Format instructions
This commit is contained in:
parent
76699b87e6
commit
6d8e9d05f9
2 changed files with 191 additions and 11 deletions
|
|
@ -319,20 +319,22 @@ pub const AttributeInfo = union(enum) {
|
|||
defer instr_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * instr_indent);
|
||||
try w.print("{d}: {t}\n", .{ i, instr });
|
||||
try w.print("{d}:\n", .{ i });
|
||||
|
||||
try instr.indentedFormat(w, depth, instr_indent + 1, constant_pool);
|
||||
}
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("exception_table:\n");
|
||||
var exception_indent = indent;
|
||||
for (attr.exception_table, 0..) |*exception, i| {
|
||||
exception_indent += 1;
|
||||
defer exception_indent -= 1;
|
||||
exception_indent += 1;
|
||||
defer exception_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * exception_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
try w.splatByteAll(' ', depth * exception_indent);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ fn Branch(comptime T: type) type {
|
|||
const bytes = bits / 8;
|
||||
|
||||
return struct {
|
||||
branch: T,
|
||||
branch_offset: T,
|
||||
|
||||
const Self = @This();
|
||||
|
||||
|
|
@ -263,7 +263,7 @@ fn Branch(comptime T: type) type {
|
|||
defer byte_index.* += bytes;
|
||||
|
||||
return .{
|
||||
.branch = try input.takeInt(u16, .big),
|
||||
.branch_offset = try input.takeInt(u16, .big),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
|
@ -456,7 +456,7 @@ const TableSwitch = struct {
|
|||
}
|
||||
};
|
||||
|
||||
const Wide = union {
|
||||
const Wide = union(enum) {
|
||||
form1: struct {
|
||||
opcode: ModifiableOp,
|
||||
index: u16,
|
||||
|
|
@ -595,8 +595,8 @@ pub const Instruction = union(Op) {
|
|||
fsub,
|
||||
getfield: Index(u16),
|
||||
getstatic: Index(u16),
|
||||
goto: Index(u16),
|
||||
goto_w: Index(u32),
|
||||
goto: Branch(u16),
|
||||
goto_w: Branch(u32),
|
||||
i2b,
|
||||
i2c,
|
||||
i2d,
|
||||
|
|
@ -1045,5 +1045,183 @@ pub const Instruction = union(Op) {
|
|||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn indentedFormat(
|
||||
self: *const Self,
|
||||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
constant_pool: ConstantPool,
|
||||
) std.Io.Writer.Error!void {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("type: {t}\n", .{ self.* });
|
||||
|
||||
switch (self.*) {
|
||||
.aload, .astore, .dload, .dstore, .fload, .fstore, .iload, .istore, .lload, .lstore => |load_store| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("index: {d}\n", .{ load_store.index });
|
||||
},
|
||||
.anewarray, .checkcast, .instanceof => |constant| {
|
||||
const @"type" = constant_pool.get(constant.index) catch return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("type:\n");
|
||||
try @"type".indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.bipush => |bipush| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("byte: 0x{X}\n", .{ bipush.byte });
|
||||
},
|
||||
.getfield, .getstatic, .putfield, .putstatic => |get_set_field| {
|
||||
const field = constant_pool.get(get_set_field.index) catch return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("field:\n");
|
||||
try field.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.goto, .if_acmpeq, .if_acmpne, .if_icmpeq, .if_icmpne, .if_icmplt, .if_icmpge, .if_icmpgt, .if_icmple, .ifeq, .ifne, .iflt, .ifge, .ifgt, .ifle, .ifnonnull, .ifnull, .jsr => |branch| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("branch_offset: {d}\n", .{ branch.branch_offset });
|
||||
},
|
||||
.goto_w, .jsr_w => |branch_w| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("branch_offset: {d}\n", .{ branch_w.branch_offset });
|
||||
},
|
||||
.iinc => |iinc| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("index: {d}\n", .{ iinc.index });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("const: {d}\n", .{ iinc.@"const" });
|
||||
},
|
||||
.invokedynamic => |invokedynamic| {
|
||||
const call_site_specifier = constant_pool.get(invokedynamic.index) catch return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("call_site_specifier:\n");
|
||||
try call_site_specifier.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.invokeinterface => |invokeinterface| {
|
||||
const interface_method = constant_pool.get(invokeinterface.index) catch return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("interface_method:\n");
|
||||
try interface_method.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("count: {d}\n", .{ invokeinterface.count });
|
||||
},
|
||||
.invokespecial, .invokestatic, .invokevirtual => |invokespecial| {
|
||||
const method = constant_pool.get(invokespecial.index) catch return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("method:\n");
|
||||
try method.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.ldc => |ldc| {
|
||||
const value = constant_pool.get(ldc.index) catch return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("value:\n");
|
||||
try value.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.ldc_w, .ldc2_w => |ldc_w| {
|
||||
const value = constant_pool.get(ldc_w.index) catch return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("value:\n");
|
||||
try value.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.lookupswitch => |lookupswitch| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("default: {d}\n", .{ lookupswitch.default });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("pairs:\n");
|
||||
var pairs_indent = indent;
|
||||
for (lookupswitch.pairs, 0..) |pair, i| {
|
||||
pairs_indent += 1;
|
||||
defer pairs_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * pairs_indent);
|
||||
try w.print("{d}:\n", .{ i });
|
||||
{
|
||||
pairs_indent += 1;
|
||||
defer pairs_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * pairs_indent);
|
||||
try w.print("match: {d}\n", .{ pair.match });
|
||||
|
||||
try w.splatByteAll(' ', depth * pairs_indent);
|
||||
try w.print("offset: {d}\n", .{ pair.offset });
|
||||
}
|
||||
}
|
||||
},
|
||||
.multianewarray => |multianewarray| {
|
||||
const @"type" = constant_pool.get(multianewarray.index) catch return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("type:\n");
|
||||
try @"type".indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("dimensions: {d}\n", .{ multianewarray.dimensions });
|
||||
},
|
||||
.new => |new| {
|
||||
const @"type" = constant_pool.get(new.index) catch return error.WriteFailed;
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("type:\n");
|
||||
try @"type".indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
},
|
||||
.newarray => |newarray| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("type: {t}\n", .{ newarray.array_type });
|
||||
},
|
||||
.ret => |ret| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("index: {d}\n", .{ ret.index });
|
||||
},
|
||||
.sipush => |sipush| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("short: 0x{X}\n", .{ sipush.short });
|
||||
},
|
||||
.tableswitch => |tableswitch| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("default: {d}\n", .{ tableswitch.default });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write("offsets:\n");
|
||||
var offsets_indent = indent;
|
||||
for (tableswitch.offsets, 0..) |offset, i| {
|
||||
offsets_indent += 1;
|
||||
defer offsets_indent -= 1;
|
||||
|
||||
try w.splatByteAll(' ', depth * offsets_indent);
|
||||
try w.print("{d}: {d}\n", .{ i, offset });
|
||||
}
|
||||
},
|
||||
.wide => |wide| switch (wide) {
|
||||
.form1 => |form1| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("opcode: {t}\n", .{ form1.opcode });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("index: {d}\n", .{ form1.index });
|
||||
},
|
||||
.form2 => |form2| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("opcode: {t}\n", .{ form2.opcode });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("index: {d}\n", .{ form2.index });
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("const: {d}\n", .{ form2.@"const" });
|
||||
},
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue