Format bootstrap methods attribute
This commit is contained in:
parent
a8c87dc421
commit
04cf7663af
2 changed files with 62 additions and 2 deletions
|
|
@ -364,6 +364,13 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
|
||||||
invoke_dynamic = 18,
|
invoke_dynamic = 18,
|
||||||
module = 19,
|
module = 19,
|
||||||
package = 20,
|
package = 20,
|
||||||
|
|
||||||
|
pub fn loadable(self: Tag) bool {
|
||||||
|
return switch (self) {
|
||||||
|
.integer, .float, .long, .double, .class, .string, .method_handle, .method_type, .dynamic => true,
|
||||||
|
else => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const Class = struct {
|
pub const Class = struct {
|
||||||
|
|
|
||||||
|
|
@ -444,8 +444,22 @@ pub const AttributeInfo = union(enum) {
|
||||||
//.runtime_invisible_annotations,
|
//.runtime_invisible_annotations,
|
||||||
//.runtime_visible_parameter_annotations,
|
//.runtime_visible_parameter_annotations,
|
||||||
//.runtime_invisible_parameter_annotations,
|
//.runtime_invisible_parameter_annotations,
|
||||||
|
//.runtime_visible_type_annotations,
|
||||||
|
//.runtime_invisible_type_annotations,
|
||||||
//.annotation_default,
|
//.annotation_default,
|
||||||
//.bootstrap_methods,
|
.bootstrap_methods => |attr| {
|
||||||
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
_ = try w.write("bootstrap_methods:\n");
|
||||||
|
var bootstrap_method_indent = indent;
|
||||||
|
for (attr.bootstrap_methods, 0..) |bootstrap_method, i| {
|
||||||
|
bootstrap_method_indent += 1;
|
||||||
|
defer bootstrap_method_indent -= 1;
|
||||||
|
|
||||||
|
try w.splatByteAll(' ', depth * bootstrap_method_indent);
|
||||||
|
try w.print("{d}:\n", .{ i });
|
||||||
|
try bootstrap_method.indentedFormat(w, depth, bootstrap_method_indent + 1, constant_pool);
|
||||||
|
}
|
||||||
|
},
|
||||||
.method_parameters => |attr| {
|
.method_parameters => |attr| {
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
_ = try w.write("parameters:\n");
|
_ = try w.write("parameters:\n");
|
||||||
|
|
@ -456,7 +470,7 @@ pub const AttributeInfo = union(enum) {
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * parameter_indent);
|
try w.splatByteAll(' ', depth * parameter_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
try parameter.indentedFormat(w, depth, parameter_indent, constant_pool);
|
try parameter.indentedFormat(w, depth, parameter_indent + 1, constant_pool);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.module => |attr| try attr.indentedFormat(w, depth, indent, constant_pool),
|
.module => |attr| try attr.indentedFormat(w, depth, indent, constant_pool),
|
||||||
|
|
@ -1603,6 +1617,45 @@ pub const BootstrapMethods = struct {
|
||||||
pub const BootstrapMethod = struct {
|
pub const BootstrapMethod = struct {
|
||||||
bootstrap_method_ref: u16,
|
bootstrap_method_ref: u16,
|
||||||
bootstrap_arguments: []u16,
|
bootstrap_arguments: []u16,
|
||||||
|
|
||||||
|
pub fn indentedFormat(
|
||||||
|
self: *const BootstrapMethod,
|
||||||
|
w: *std.Io.Writer,
|
||||||
|
depth: usize,
|
||||||
|
indent: u8,
|
||||||
|
constant_pool: []const ?ConstantPoolInfo,
|
||||||
|
) std.Io.Writer.Error!void {
|
||||||
|
const bootstrap_method = self.bootstrapMethod(constant_pool) catch return error.WriteFailed;
|
||||||
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
_ = try w.write("bootstrap_method:\n");
|
||||||
|
try bootstrap_method.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||||
|
|
||||||
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
_ = try w.write("bootstrap_arguments:\n");
|
||||||
|
var bootstrap_argument_indent = indent;
|
||||||
|
for (self.bootstrap_arguments, 0..) |bootstrap_argument, i| {
|
||||||
|
bootstrap_argument_indent += 1;
|
||||||
|
defer bootstrap_argument_indent -= 1;
|
||||||
|
|
||||||
|
const index = bootstrap_argument - 1;
|
||||||
|
|
||||||
|
if (index >= constant_pool.len) return error.WriteFailed;
|
||||||
|
const cp_info = constant_pool[index];
|
||||||
|
if (cp_info == null or !@as(ConstantPoolInfo.Tag, cp_info.?).loadable()) return error.WriteFailed;
|
||||||
|
|
||||||
|
try w.splatByteAll(' ', depth * bootstrap_argument_indent);
|
||||||
|
try w.print("{d}:\n", .{ i });
|
||||||
|
try cp_info.?.indentedFormat(w, depth, bootstrap_argument_indent + 1, constant_pool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bootstrapMethod(self: *const BootstrapMethod, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
||||||
|
const bootstrap_method_ref = self.bootstrap_method_ref - 1;
|
||||||
|
if (bootstrap_method_ref >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
|
const cp_info = constant_pool[bootstrap_method_ref];
|
||||||
|
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .method_handle) return ResolveError.InvalidConstantType;
|
||||||
|
return cp_info.?;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self {
|
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!Self {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue