Format bootstrap methods attribute

This commit is contained in:
ktkk 2026-07-05 20:54:23 +02:00
parent a8c87dc421
commit 04cf7663af
2 changed files with 62 additions and 2 deletions

View file

@ -364,6 +364,13 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
invoke_dynamic = 18,
module = 19,
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 {

View file

@ -444,8 +444,22 @@ pub const AttributeInfo = union(enum) {
//.runtime_invisible_annotations,
//.runtime_visible_parameter_annotations,
//.runtime_invisible_parameter_annotations,
//.runtime_visible_type_annotations,
//.runtime_invisible_type_annotations,
//.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| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("parameters:\n");
@ -456,7 +470,7 @@ pub const AttributeInfo = union(enum) {
try w.splatByteAll(' ', depth * parameter_indent);
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),
@ -1603,6 +1617,45 @@ pub const BootstrapMethods = struct {
pub const BootstrapMethod = struct {
bootstrap_method_ref: 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 {