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;
|
defer instr_indent -= 1;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * instr_indent);
|
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.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);
|
||||||
|
|
|
||||||
|
|
@ -255,7 +255,7 @@ fn Branch(comptime T: type) type {
|
||||||
const bytes = bits / 8;
|
const bytes = bits / 8;
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
branch: T,
|
branch_offset: T,
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
|
|
@ -263,7 +263,7 @@ fn Branch(comptime T: type) type {
|
||||||
defer byte_index.* += bytes;
|
defer byte_index.* += bytes;
|
||||||
|
|
||||||
return .{
|
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 {
|
form1: struct {
|
||||||
opcode: ModifiableOp,
|
opcode: ModifiableOp,
|
||||||
index: u16,
|
index: u16,
|
||||||
|
|
@ -595,8 +595,8 @@ pub const Instruction = union(Op) {
|
||||||
fsub,
|
fsub,
|
||||||
getfield: Index(u16),
|
getfield: Index(u16),
|
||||||
getstatic: Index(u16),
|
getstatic: Index(u16),
|
||||||
goto: Index(u16),
|
goto: Branch(u16),
|
||||||
goto_w: Index(u32),
|
goto_w: Branch(u32),
|
||||||
i2b,
|
i2b,
|
||||||
i2c,
|
i2c,
|
||||||
i2d,
|
i2d,
|
||||||
|
|
@ -1045,5 +1045,183 @@ pub const Instruction = union(Op) {
|
||||||
else => {},
|
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