Compare commits
1 commit
master
...
feature/te
| Author | SHA1 | Date | |
|---|---|---|---|
| 9e0e5ff8ea |
6 changed files with 84 additions and 1305 deletions
|
|
@ -36,8 +36,6 @@ pub const ClassAccessFlags = EnumFlags(enum(u16) {
|
||||||
pub const ParseError = std.Io.Reader.Error || std.mem.Allocator.Error || error {
|
pub const ParseError = std.Io.Reader.Error || std.mem.Allocator.Error || error {
|
||||||
InvalidMagicNumber,
|
InvalidMagicNumber,
|
||||||
InvalidTag,
|
InvalidTag,
|
||||||
InvalidOp,
|
|
||||||
InvalidArrayType,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ResolveError = error {
|
pub const ResolveError = error {
|
||||||
|
|
|
||||||
|
|
@ -319,22 +319,20 @@ pub const AttributeInfo = union(enum) {
|
||||||
defer instr_indent -= 1;
|
defer instr_indent -= 1;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * instr_indent);
|
try w.splatByteAll(' ', depth * instr_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}: 0x{x}\n", .{ i, instr });
|
||||||
|
|
||||||
try instr.indentedFormat(w, depth, instr_indent + 1, constant_pool);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
_ = try w.write("exception_table:\n");
|
_ = try w.write("exception_table:\n");
|
||||||
var exception_indent = indent;
|
var exception_indent = indent;
|
||||||
for (attr.exception_table, 0..) |*exception, i| {
|
for (attr.exception_table, 0..) |*exception, i| {
|
||||||
exception_indent += 1;
|
exception_indent += 1;
|
||||||
defer exception_indent -= 1;
|
defer exception_indent -= 1;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * exception_indent);
|
try w.splatByteAll(' ', depth * exception_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
||||||
try exception.indentedFormat(w, depth, exception_indent + 1, constant_pool);
|
try exception.indentedFormat(w, depth, exception_indent + 1, constant_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
|
@ -692,14 +690,12 @@ pub const ConstantValue = struct {
|
||||||
pub const Code = struct {
|
pub const Code = struct {
|
||||||
max_stack: u16,
|
max_stack: u16,
|
||||||
max_locals: u16,
|
max_locals: u16,
|
||||||
code: []Instruction,
|
code: []u8,
|
||||||
exception_table: []ExceptionHandler,
|
exception_table: []ExceptionHandler,
|
||||||
attributes: []AttributeInfo,
|
attributes: []AttributeInfo,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub const Instruction = @import("Code/Instruction.zig").Instruction;
|
|
||||||
|
|
||||||
pub const ExceptionHandler = struct {
|
pub const ExceptionHandler = struct {
|
||||||
start_pc: u16,
|
start_pc: u16,
|
||||||
end_pc: u16,
|
end_pc: u16,
|
||||||
|
|
@ -740,20 +736,8 @@ pub const Code = struct {
|
||||||
const max_locals = try input.takeInt(u16, .big);
|
const max_locals = try input.takeInt(u16, .big);
|
||||||
|
|
||||||
const code_length = try input.takeInt(u32, .big);
|
const code_length = try input.takeInt(u32, .big);
|
||||||
var code_reader_buf: [1024]u8 = undefined;
|
const code = try input.readAlloc(allocator, code_length);
|
||||||
var code_reader = input.limited(.limited(code_length), &code_reader_buf);
|
errdefer allocator.free(code);
|
||||||
var code = &code_reader.interface;
|
|
||||||
var byte_index: usize = 0;
|
|
||||||
var instructions: std.ArrayList(Instruction) = .empty;
|
|
||||||
defer instructions.deinit(allocator);
|
|
||||||
loop: while (true) {
|
|
||||||
_ = code.peekByte() catch |err| switch (err) {
|
|
||||||
error.EndOfStream => break :loop,
|
|
||||||
else => return err,
|
|
||||||
};
|
|
||||||
|
|
||||||
try instructions.append(allocator, try .parse(code, allocator, &byte_index));
|
|
||||||
}
|
|
||||||
|
|
||||||
const exception_table_length = try input.takeInt(u16, .big);
|
const exception_table_length = try input.takeInt(u16, .big);
|
||||||
const exception_table = try allocator.alloc(ExceptionHandler, exception_table_length);
|
const exception_table = try allocator.alloc(ExceptionHandler, exception_table_length);
|
||||||
|
|
@ -777,16 +761,13 @@ pub const Code = struct {
|
||||||
return .{
|
return .{
|
||||||
.max_stack = max_stack,
|
.max_stack = max_stack,
|
||||||
.max_locals = max_locals,
|
.max_locals = max_locals,
|
||||||
.code = try instructions.toOwnedSlice(allocator),
|
.code = code,
|
||||||
.exception_table = exception_table,
|
.exception_table = exception_table,
|
||||||
.attributes = attributes,
|
.attributes = attributes,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
|
||||||
for (self.code) |*instruction| {
|
|
||||||
instruction.deinit(allocator);
|
|
||||||
}
|
|
||||||
allocator.free(self.code);
|
allocator.free(self.code);
|
||||||
allocator.free(self.exception_table);
|
allocator.free(self.exception_table);
|
||||||
for (self.attributes) |*attr| {
|
for (self.attributes) |*attr| {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -8,7 +8,13 @@ pub fn EnumFlags(comptime E: type) type {
|
||||||
|
|
||||||
mask: BackingInt,
|
mask: BackingInt,
|
||||||
|
|
||||||
pub const empty: Self = .{ .data = 0 };
|
pub const empty: Self = .{ .mask = 0 };
|
||||||
|
|
||||||
|
test empty {
|
||||||
|
const flags: EnumFlags(Enum) = .empty;
|
||||||
|
|
||||||
|
try std.testing.expectEqual(0b0000_0000, flags.mask);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn from(mask: BackingInt) Self {
|
pub fn from(mask: BackingInt) Self {
|
||||||
return .{
|
return .{
|
||||||
|
|
@ -16,6 +22,12 @@ pub fn EnumFlags(comptime E: type) type {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test from {
|
||||||
|
const flags: EnumFlags(Enum) = .from(0b0000_0001);
|
||||||
|
|
||||||
|
try std.testing.expectEqual(0b0000_0001, flags.mask);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn contains(self: Self, flag: E) bool {
|
pub fn contains(self: Self, flag: E) bool {
|
||||||
return (self.mask & @intFromEnum(flag)) != 0;
|
return (self.mask & @intFromEnum(flag)) != 0;
|
||||||
}
|
}
|
||||||
|
|
@ -48,3 +60,64 @@ pub fn EnumFlags(comptime E: type) type {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Enum = enum(u8) {
|
||||||
|
a = 0b0000_0001,
|
||||||
|
b = 0b0000_0010,
|
||||||
|
c = 0b0000_0100,
|
||||||
|
};
|
||||||
|
|
||||||
|
test {
|
||||||
|
|
||||||
|
std.testing.refAllDecls(EnumFlags(Enum));
|
||||||
|
}
|
||||||
|
|
||||||
|
test "EnumFlags operations" {
|
||||||
|
var flags: EnumFlags(Enum) = .from(0b0000_0001);
|
||||||
|
|
||||||
|
try std.testing.expect(flags.contains(Enum.a));
|
||||||
|
|
||||||
|
flags.remove(Enum.a);
|
||||||
|
try std.testing.expect(!flags.contains(Enum.a));
|
||||||
|
|
||||||
|
flags.remove(Enum.a); // Removing twice should not enable the flag
|
||||||
|
try std.testing.expect(!flags.contains(Enum.a));
|
||||||
|
|
||||||
|
flags.insert(Enum.b);
|
||||||
|
try std.testing.expectEqual(0b0000_0010, flags.mask);
|
||||||
|
try std.testing.expect(flags.contains(Enum.b));
|
||||||
|
try std.testing.expect(!flags.contains(Enum.a));
|
||||||
|
|
||||||
|
flags.toggle(Enum.a);
|
||||||
|
try std.testing.expectEqual(0b0000_0011, flags.mask);
|
||||||
|
try std.testing.expect(flags.contains(Enum.a));
|
||||||
|
try std.testing.expect(flags.contains(Enum.b));
|
||||||
|
try std.testing.expect(!flags.contains(Enum.c));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn testFormat(expected: []const u8, flags: EnumFlags(Enum)) !void {
|
||||||
|
var out_buf: [1024]u8 = undefined;
|
||||||
|
var out: std.Io.Writer = .fixed(&out_buf);
|
||||||
|
|
||||||
|
try flags.format(&out);
|
||||||
|
|
||||||
|
try std.testing.expectEqualStrings(expected, out.buffered());
|
||||||
|
}
|
||||||
|
|
||||||
|
test "EnumFlags format" {
|
||||||
|
var flags: EnumFlags(Enum) = .empty;
|
||||||
|
|
||||||
|
flags.toggle(Enum.a);
|
||||||
|
flags.toggle(Enum.b);
|
||||||
|
flags.toggle(Enum.c);
|
||||||
|
try testFormat("a | b | c", flags);
|
||||||
|
|
||||||
|
flags.toggle(Enum.b);
|
||||||
|
try testFormat("a | c", flags);
|
||||||
|
|
||||||
|
flags.remove(Enum.c);
|
||||||
|
try testFormat("a", flags);
|
||||||
|
|
||||||
|
flags.insert(Enum.b);
|
||||||
|
try testFormat("a | b", flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,52 +17,6 @@ public class Main implements Runnable, Supplier<Integer>, Interface {
|
||||||
} finally {
|
} finally {
|
||||||
System.err.println("Finally block");
|
System.err.println("Finally block");
|
||||||
}
|
}
|
||||||
|
|
||||||
var a = 8;
|
|
||||||
a <<= 3;
|
|
||||||
final var b = a >> 1;
|
|
||||||
switch (b) {
|
|
||||||
case 1:
|
|
||||||
break;
|
|
||||||
case 32:
|
|
||||||
System.out.println("Good");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
System.out.println("Number " + a);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
final var o = getObject();
|
|
||||||
switch (o) {
|
|
||||||
case Integer i:
|
|
||||||
switch (i) {
|
|
||||||
case 1:
|
|
||||||
System.out.println("One");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
System.out.println("Two");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
System.out.println("Three");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
System.out.println("Something else");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
inc(5);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Object getObject() {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void inc(int i) {
|
|
||||||
i += 1000;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
BIN
testsuite/classes/java/Object.class
Normal file
BIN
testsuite/classes/java/Object.class
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue