Format additional predefined attribute infos

This commit is contained in:
ktkk 2026-07-05 00:25:25 +02:00
parent 9af766e495
commit f8b1f968e0
4 changed files with 273 additions and 19 deletions

View file

@ -274,7 +274,7 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
try w.splatByteAll(' ', depth * indent);
try w.print("{d}:\n", .{ i });
try field.indentedFormat(w, depth, indent + 1, self.allocator, self.constant_pool);
try field.indentedFormat(w, depth, indent + 1, self.constant_pool);
}
_ = try w.write("methods:\n");
@ -284,7 +284,7 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
try w.splatByteAll(' ', depth * indent);
try w.print("{d}:\n", .{ i });
try method.indentedFormat(w, depth, indent + 1, self.allocator, self.constant_pool);
try method.indentedFormat(w, depth, indent + 1, self.constant_pool);
}
_ = try w.write("attributes:\n");
@ -294,7 +294,7 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
try w.splatByteAll(' ', depth * indent);
try w.print("{d}:\n", .{ i });
try attribute.indentedFormat(w, depth, indent + 1, self.allocator, self.constant_pool);
try attribute.indentedFormat(w, depth, indent + 1, self.constant_pool);
}
}
@ -342,7 +342,10 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
utf8: Utf8,
method_handle: MethodHandle,
method_type: MethodType,
dynamic: Dynamic,
invoke_dynamic: InvokeDynamic,
module: Module,
package: Package,
pub const Tag = enum(u8) {
class = 7,
@ -358,7 +361,10 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
utf8 = 1,
method_handle = 15,
method_type = 16,
dynamic = 17,
invoke_dynamic = 18,
module = 19,
package = 20,
};
pub const Class = struct {
@ -540,6 +546,19 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
}
};
pub const Dynamic = struct {
bootstrap_method_attr_index: u16,
name_and_type_index: u16,
pub fn nameAndType(self: *const Dynamic, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
const name_and_type_index = self.name_and_type_index - 1;
if (name_and_type_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[name_and_type_index];
if (cp_info == null or @as(Tag, cp_info.?) != .name_and_type) return ResolveError.InvalidConstantType;
return cp_info.?;
}
};
pub const InvokeDynamic = struct {
bootstrap_method_attr_index: u16,
name_and_type_index: u16,
@ -553,6 +572,30 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
}
};
pub const Module = struct {
name_index: u16,
pub fn name(self: *const Module, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
const name_index = self.name_index - 1;
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[name_index];
if (cp_info == null or @as(Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}
};
pub const Package = struct {
name_index: u16,
pub fn name(self: *const Package, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
const name_index = self.name_index - 1;
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[name_index];
if (cp_info == null or @as(Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}
};
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError!ConstantPoolInfo {
const tag_byte = try input.takeByte();
const tag = std.enums.fromInt(Tag, tag_byte) orelse return ParseError.InvalidTag;
@ -640,12 +683,28 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
.descriptor_index = try input.takeInt(u16, .big),
},
},
.dynamic => .{
.dynamic = .{
.bootstrap_method_attr_index = try input.takeInt(u16, .big),
.name_and_type_index = try input.takeInt(u16, .big),
},
},
.invoke_dynamic => .{
.invoke_dynamic = .{
.bootstrap_method_attr_index = try input.takeInt(u16, .big),
.name_and_type_index = try input.takeInt(u16, .big),
},
},
.module => .{
.module = .{
.name_index = try input.takeInt(u16, .big),
},
},
.package => .{
.package = .{
.name_index = try input.takeInt(u16, .big),
},
},
};
}
@ -671,7 +730,10 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
.utf8 => |utf8| try w.print("\"{s}\"", .{ utf8.bytes }),
.method_handle => |method_handle| try w.print("{s} #{d}", .{ @tagName(method_handle.reference_kind), method_handle.reference_index }),
.method_type => |method_type| try w.print("#{d}", .{ method_type.descriptor_index }),
.dynamic => |dynamic| try w.print("#{d} #{d}", .{ dynamic.bootstrap_method_attr_index, dynamic.name_and_type_index }),
.invoke_dynamic => |invoke_dynamic| try w.print("#{d} #{d}", .{ invoke_dynamic.bootstrap_method_attr_index, invoke_dynamic.name_and_type_index }),
.module => |module| try w.print("#{d}", .{ module.name_index }),
.package => |package| try w.print("#{d}", .{ package.name_index }),
}
}
@ -782,12 +844,30 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
const descriptor = method_type.descriptor(constant_pool) catch return error.WriteFailed;
try descriptor.indentedFormat(w, depth, indent + 1, constant_pool);
},
.dynamic => |dynamic| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name_and_type:\n");
const name_and_type = dynamic.nameAndType(constant_pool) catch return error.WriteFailed;
try name_and_type.indentedFormat(w, depth, indent + 1, constant_pool);
},
.invoke_dynamic => |invoke_dynamic| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name_and_type:\n");
const name_and_type = invoke_dynamic.nameAndType(constant_pool) catch return error.WriteFailed;
try name_and_type.indentedFormat(w, depth, indent + 1, constant_pool);
},
.module => |module| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const name = module.name(constant_pool) catch return error.WriteFailed;
try name.indentedFormat(w, depth, indent + 1, constant_pool);
},
.package => |package| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const name = package.name(constant_pool) catch return error.WriteFailed;
try name.indentedFormat(w, depth, indent + 1, constant_pool);
},
}
}
};