Refactor constant pool entry formatting

This commit is contained in:
ktkk 2026-06-23 10:14:04 +00:00
parent 4123ac71e9
commit db9751a4b7

View file

@ -229,11 +229,11 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
const this_class = self.thisClass() catch return error.WriteFailed;
_ = try w.write("this class:\n");
try self.formatCpInfo(w, depth, indent + 1, &.{ .class = this_class });
try this_class.format(w, depth, indent + 1, self.constant_pool);
if (self.superClass() catch return error.WriteFailed) |super_class| {
_ = try w.write("super class:\n");
try self.formatCpInfo(w, depth, indent + 1, &.{ .class = super_class });
try super_class.format(w, depth, indent + 1, self.constant_pool);
}
_ = try w.write("interfaces:\n");
@ -247,7 +247,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 self.formatCpInfo(w, depth, indent + 1, &cp_info.?);
try cp_info.?.format(w, depth, indent + 1, self.constant_pool);
}
_ = try w.write("fields:\n");
@ -267,12 +267,12 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const field_name = field.name(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = field_name });
try field_name.format(w, depth, indent + 1, self.constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("descriptor:\n");
const field_descriptor = field.descriptor(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = field_descriptor });
try field_descriptor.format(w, depth, indent + 1, self.constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("attributes:\n");
@ -304,12 +304,12 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const method_name = method.name(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = method_name });
try method_name.format(w, depth, indent + 1, self.constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("descriptor:\n");
const method_descriptor = method.descriptor(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = method_descriptor });
try method_descriptor.format(w, depth, indent + 1, self.constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("attributes:\n");
@ -340,7 +340,7 @@ fn formatAttribute(self: *const Self, w: *std.Io.Writer, depth: usize, indent: u
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const attribute_name = attribute.attributeName(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = attribute_name });
try attribute_name.format(w, depth, indent + 1, self.constant_pool);
var predefined = attribute.resolve(self.allocator, self.constant_pool) catch return error.WriteFailed;
if (predefined) |*p| {
@ -355,7 +355,7 @@ fn formatAttribute(self: *const Self, w: *std.Io.Writer, depth: usize, indent: u
switch (p.*) {
.constant_value => |attr| {
const constant_value = attr.constantValue(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &constant_value);
try constant_value.format(w, depth, indent + 1, self.constant_pool);
},
.code => |attr| {
try w.splatByteAll(' ', depth * indent);
@ -372,7 +372,7 @@ fn formatAttribute(self: *const Self, w: *std.Io.Writer, depth: usize, indent: u
defer instr_indent -= 1;
try w.splatByteAll(' ', depth * instr_indent);
try w.print("{d}: {d}\n", .{ i, instr });
try w.print("{d}: 0x{x}\n", .{ i, instr });
}
//try w.splatByteAll(' ', depth * indent);
@ -416,7 +416,7 @@ fn formatAttribute(self: *const Self, w: *std.Io.Writer, depth: usize, indent: u
try w.splatByteAll(' ', depth * attr_indent);
try w.print("{d}:\n", .{ i });
try self.formatCpInfo(w, depth, attr_indent + 1, &cp_info.?);
try cp_info.?.format(w, depth, attr_indent + 1, self.constant_pool);
}
},
.inner_classes => |attr| {
@ -428,26 +428,22 @@ fn formatAttribute(self: *const Self, w: *std.Io.Writer, depth: usize, indent: u
defer inner_classes_indent -= 1;
const inner_class = class.innerClass(self.constant_pool) catch return error.WriteFailed;
try w.splatByteAll(' ', depth * inner_classes_indent);
_ = try w.write("inner_class:\n");
try self.formatCpInfo(w, depth, inner_classes_indent + 1, &.{ .class = inner_class });
try inner_class.format(w, depth, inner_classes_indent + 1, self.constant_pool);
const outer_class = class.outerClass(self.constant_pool) catch return error.WriteFailed;
if (outer_class) |oc| {
try w.splatByteAll(' ', depth * inner_classes_indent);
_ = try w.write("outer_class:\n");
try self.formatCpInfo(w, depth, inner_classes_indent + 1, &.{ .class = oc });
try oc.format(w, depth, inner_classes_indent + 1, self.constant_pool);
}
const inner_name = class.innerName(self.constant_pool) catch return error.WriteFailed;
if (inner_name) |in| {
try w.splatByteAll(' ', depth * inner_classes_indent);
_ = try w.write("inner_name:\n");
try self.formatCpInfo(w, depth, inner_classes_indent + 1, &.{ .utf8 = in });
try in.format(w, depth, inner_classes_indent + 1, self.constant_pool);
}
try w.splatByteAll(' ', depth * inner_classes_indent);
@ -456,28 +452,25 @@ fn formatAttribute(self: *const Self, w: *std.Io.Writer, depth: usize, indent: u
},
.enclosing_method => |attr| {
const class = attr.class(self.constant_pool) catch return error.WriteFailed;
try w.splatByteAll(' ', depth * indent);
_ = try w.write("class:\n");
try self.formatCpInfo(w, depth, indent + 1, &.{ .class = class });
try class.format(w, depth, indent + 1, self.constant_pool);
const method = attr.method(self.constant_pool) catch return error.WriteFailed;
if (method) |m| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("method:\n");
try self.formatCpInfo(w, depth, indent + 1, &.{ .name_and_type = m });
try m.format(w, depth, indent + 1, self.constant_pool);
}
},
.synthetic => {},
.signature => |attr| {
const signature = attr.signature(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = signature });
try signature.format(w, depth, indent + 1, self.constant_pool);
},
.source_file => |attr| {
const source_file = attr.sourceFile(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = source_file });
try source_file.format(w, depth, indent + 1, self.constant_pool);
},
//.source_debug_extension,
//.line_number_table,
@ -498,131 +491,21 @@ fn formatAttribute(self: *const Self, w: *std.Io.Writer, depth: usize, indent: u
}
}
fn formatCpInfo(self: *const Self, w: *std.Io.Writer, depth: usize, indent: u8, cp_info: *const CpInfo) std.Io.Writer.Error!void {
try w.splatByteAll(' ', depth * indent);
try w.print("constant_value_type: {s}\n", .{ @tagName(cp_info.*) });
switch (cp_info.*) {
.class => |class| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const class_name = class.name(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = class_name });
},
.field_ref => |field_ref| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("class:\n");
const class = field_ref.class(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .class = class });
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name_and_type:\n");
const name_and_type = field_ref.nameAndType(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .name_and_type = name_and_type });
},
.method_ref => |method_ref| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("class:\n");
const class = method_ref.class(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .class = class });
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name_and_type:\n");
const name_and_type = method_ref.nameAndType(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .name_and_type = name_and_type });
},
.interface_method_ref => |interface_method_ref| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("class:\n");
const class = interface_method_ref.class(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .class = class });
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name_and_type:\n");
const name_and_type = interface_method_ref.nameAndType(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .name_and_type = name_and_type });
},
.string => |string| {
const s = string.string(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = s });
},
.integer => |integer| {
try w.splatByteAll(' ', depth * indent);
try w.print("integer: {d}\n", .{ integer.bytes });
},
.float => |float| {
const f: f32 = @bitCast(float.bytes);
try w.splatByteAll(' ', depth * indent);
try w.print("float: {d}\n", .{ f });
},
.long => |long| {
const l: u64 = (@as(u64, long.high_bytes) << 32) | long.low_bytes;
try w.splatByteAll(' ', depth * indent);
try w.print("long: {d}\n", .{ l });
},
.double => |double| {
const l: u64 = (@as(u64, double.high_bytes) << 32) | double.low_bytes;
const d: f64 = @bitCast(l);
try w.splatByteAll(' ', depth * indent);
try w.print("double: {d}\n", .{ d });
},
.name_and_type => |name_and_type| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const name = name_and_type.name(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = name });
try w.splatByteAll(' ', depth * indent);
_ = try w.write("descriptor:\n");
const descriptor = name_and_type.descriptor(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = descriptor });
},
.utf8 => |utf8| {
try w.splatByteAll(' ', depth * indent);
try w.print("bytes: \"{s}\"\n", .{ utf8.bytes });
},
.method_handle => |method_handle| {
try w.splatByteAll(' ', depth * indent);
try w.print("kind: {t}\n", .{ method_handle.reference_kind });
try w.splatByteAll(' ', depth * indent);
_ = try w.write("reference:\n");
const reference = method_handle.reference(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &reference);
},
.method_type => |method_type| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("descriptor:\n");
const descriptor = method_type.descriptor(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .utf8 = descriptor });
},
.invoke_dynamic => |invoke_dynamic| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name_and_type:\n");
const name_and_type = invoke_dynamic.nameAndType(self.constant_pool) catch return error.WriteFailed;
try self.formatCpInfo(w, depth, indent + 1, &.{ .name_and_type = name_and_type });
},
}
}
pub fn thisClass(self: *const Self) ResolveError!CpInfo.Class {
pub fn thisClass(self: *const Self) ResolveError!CpInfo {
const this_class = self.this_class - 1;
if (this_class >= self.constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = self.constant_pool[this_class];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
return cp_info.?.class;
return cp_info.?;
}
pub fn superClass(self: *const Self) ResolveError!?CpInfo.Class {
pub fn superClass(self: *const Self) ResolveError!?CpInfo {
// TODO: Determine whether this is an interface or a regular class.
// When this is an interface, assert that the super class must be Object.
if (self.super_class == 0) {
const this_class = try self.thisClass();
const this_class_name = try this_class.name(self.constant_pool);
const this_class = (try self.thisClass()).class;
const this_class_name = (try this_class.name(self.constant_pool)).utf8;
if (!std.mem.eql(u8, this_class_name.bytes, "Object")) return ResolveError.InvalidConstantType;
return null;
} else {
@ -631,7 +514,7 @@ pub fn superClass(self: *const Self) ResolveError!?CpInfo.Class {
const cp_info = self.constant_pool[super_class];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
// TODO: Assert that superclass does not have ACC_FINAL flag set.
return cp_info.?.class;
return cp_info.?;
}
}
@ -671,12 +554,12 @@ pub const CpInfo = union(CpInfo.Tag) {
pub const Class = struct {
name_index: u16,
pub fn name(self: *const Class, constant_pool: []const ?CpInfo) ResolveError!Utf8 {
pub fn name(self: *const Class, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
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.?.utf8;
return cp_info.?;
}
};
@ -684,20 +567,20 @@ pub const CpInfo = union(CpInfo.Tag) {
class_index: u16,
name_and_type_index: u16,
pub fn class(self: *const FieldRef, constant_pool: []const ?CpInfo) ResolveError!Class {
pub fn class(self: *const FieldRef, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const class_index = self.class_index - 1;
if (class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[class_index];
if (cp_info == null or @as(Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
return cp_info.?.class;
return cp_info.?;
}
pub fn nameAndType(self: *const FieldRef, constant_pool: []const ?CpInfo) ResolveError!NameAndType {
pub fn nameAndType(self: *const FieldRef, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
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.?.name_and_type;
return cp_info.?;
}
};
@ -705,20 +588,20 @@ pub const CpInfo = union(CpInfo.Tag) {
class_index: u16,
name_and_type_index: u16,
pub fn class(self: *const MethodRef, constant_pool: []const ?CpInfo) ResolveError!Class {
pub fn class(self: *const MethodRef, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const class_index = self.class_index - 1;
if (class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[class_index];
if (cp_info == null or @as(Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
return cp_info.?.class;
return cp_info.?;
}
pub fn nameAndType(self: *const MethodRef, constant_pool: []const ?CpInfo) ResolveError!NameAndType {
pub fn nameAndType(self: *const MethodRef, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
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.?.name_and_type;
return cp_info.?;
}
};
@ -726,32 +609,32 @@ pub const CpInfo = union(CpInfo.Tag) {
class_index: u16,
name_and_type_index: u16,
pub fn class(self: *const InterfaceMethodRef, constant_pool: []const ?CpInfo) ResolveError!Class {
pub fn class(self: *const InterfaceMethodRef, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const class_index = self.class_index - 1;
if (class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[class_index];
if (cp_info == null or @as(Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
return cp_info.?.class;
return cp_info.?;
}
pub fn nameAndType(self: *const InterfaceMethodRef, constant_pool: []const ?CpInfo) ResolveError!NameAndType {
pub fn nameAndType(self: *const InterfaceMethodRef, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
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.?.name_and_type;
return cp_info.?;
}
};
pub const String = struct {
string_index: u16,
pub fn string(self: *const String, constant_pool: []const ?CpInfo) ResolveError!Utf8 {
pub fn string(self: *const String, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const string_index = self.string_index - 1;
if (string_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[string_index];
if (cp_info == null or @as(Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
};
@ -777,20 +660,20 @@ pub const CpInfo = union(CpInfo.Tag) {
name_index: u16,
descriptor_index: u16,
pub fn name(self: *const NameAndType, constant_pool: []const ?CpInfo) ResolveError!Utf8 {
pub fn name(self: *const NameAndType, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
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.?.utf8;
return cp_info.?;
}
pub fn descriptor(self: *const NameAndType, constant_pool: []const ?CpInfo) ResolveError!Utf8 {
pub fn descriptor(self: *const NameAndType, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const descriptor_index = self.descriptor_index - 1;
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[descriptor_index];
if (cp_info == null or @as(Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
};
@ -838,12 +721,12 @@ pub const CpInfo = union(CpInfo.Tag) {
pub const MethodType = struct {
descriptor_index: u16,
pub fn descriptor(self: *const MethodType, constant_pool: []const ?CpInfo) ResolveError!Utf8 {
pub fn descriptor(self: *const MethodType, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const descriptor_index = self.descriptor_index - 1;
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[descriptor_index];
if (cp_info == null or @as(Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
};
@ -851,12 +734,12 @@ pub const CpInfo = union(CpInfo.Tag) {
bootstrap_method_attr_index: u16,
name_and_type_index: u16,
pub fn nameAndType(self: *const InvokeDynamic, constant_pool: []const ?CpInfo) ResolveError!NameAndType {
pub fn nameAndType(self: *const InvokeDynamic, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
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.?.name_and_type;
return cp_info.?;
}
};
@ -962,6 +845,116 @@ pub const CpInfo = union(CpInfo.Tag) {
else => {},
}
}
pub fn format(self: *const CpInfo, w: *std.Io.Writer, depth: usize, indent: u8, constant_pool: []const ?CpInfo) std.Io.Writer.Error!void {
try w.splatByteAll(' ', depth * indent);
try w.print("constant_value_type: {s}\n", .{ @tagName(self.*) });
switch (self.*) {
.class => |class| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const class_name = class.name(constant_pool) catch return error.WriteFailed;
try class_name.format(w, depth, indent + 1, constant_pool);
},
.field_ref => |field_ref| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("class:\n");
const class = field_ref.class(constant_pool) catch return error.WriteFailed;
try class.format(w, depth, indent + 1, constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name_and_type:\n");
const name_and_type = field_ref.nameAndType(constant_pool) catch return error.WriteFailed;
try name_and_type.format(w, depth, indent + 1, constant_pool);
},
.method_ref => |method_ref| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("class:\n");
const class = method_ref.class(constant_pool) catch return error.WriteFailed;
try class.format(w, depth, indent + 1, constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name_and_type:\n");
const name_and_type = method_ref.nameAndType(constant_pool) catch return error.WriteFailed;
try name_and_type.format(w, depth, indent + 1, constant_pool);
},
.interface_method_ref => |interface_method_ref| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("class:\n");
const class = interface_method_ref.class(constant_pool) catch return error.WriteFailed;
try class.format(w, depth, indent + 1, constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name_and_type:\n");
const name_and_type = interface_method_ref.nameAndType(constant_pool) catch return error.WriteFailed;
try name_and_type.format(w, depth, indent + 1, constant_pool);
},
.string => |string| {
const s = string.string(constant_pool) catch return error.WriteFailed;
try s.format(w, depth, indent + 1, constant_pool);
},
.integer => |integer| {
try w.splatByteAll(' ', depth * indent);
try w.print("integer: {d}\n", .{ integer.bytes });
},
.float => |float| {
const f: f32 = @bitCast(float.bytes);
try w.splatByteAll(' ', depth * indent);
try w.print("float: {d}\n", .{ f });
},
.long => |long| {
const l: u64 = (@as(u64, long.high_bytes) << 32) | long.low_bytes;
try w.splatByteAll(' ', depth * indent);
try w.print("long: {d}\n", .{ l });
},
.double => |double| {
const l: u64 = (@as(u64, double.high_bytes) << 32) | double.low_bytes;
const d: f64 = @bitCast(l);
try w.splatByteAll(' ', depth * indent);
try w.print("double: {d}\n", .{ d });
},
.name_and_type => |name_and_type| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const name = name_and_type.name(constant_pool) catch return error.WriteFailed;
try name.format(w, depth, indent + 1, constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("descriptor:\n");
const descriptor = name_and_type.descriptor(constant_pool) catch return error.WriteFailed;
try descriptor.format(w, depth, indent + 1, constant_pool);
},
.utf8 => |utf8| {
try w.splatByteAll(' ', depth * indent);
try w.print("bytes: \"{s}\"\n", .{ utf8.bytes });
},
.method_handle => |method_handle| {
try w.splatByteAll(' ', depth * indent);
try w.print("kind: {t}\n", .{ method_handle.reference_kind });
try w.splatByteAll(' ', depth * indent);
_ = try w.write("reference:\n");
const reference = method_handle.reference(constant_pool) catch return error.WriteFailed;
try reference.format(w, depth, indent + 1, constant_pool);
},
.method_type => |method_type| {
try w.splatByteAll(' ', depth * indent);
_ = try w.write("descriptor:\n");
const descriptor = method_type.descriptor(constant_pool) catch return error.WriteFailed;
try descriptor.format(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.format(w, depth, indent + 1, constant_pool);
},
}
}
};
pub const ClassFlags = enum(u16) {
@ -1003,20 +996,20 @@ pub const FieldInfo = struct {
allocator.free(self.attributes);
}
pub fn name(self: *const FieldInfo, constant_pool: []const ?CpInfo) ResolveError!CpInfo.Utf8 {
pub fn name(self: *const FieldInfo, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
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(CpInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
pub fn descriptor(self: *const FieldInfo, constant_pool: []const ?CpInfo) ResolveError!CpInfo.Utf8 {
pub fn descriptor(self: *const FieldInfo, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const descriptor_index = self.descriptor_index - 1;
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[descriptor_index];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
};
@ -1060,20 +1053,20 @@ pub const MethodInfo = struct {
allocator.free(self.attributes);
}
pub fn name(self: *const MethodInfo, constant_pool: []const ?CpInfo) ResolveError!CpInfo.Utf8 {
pub fn name(self: *const MethodInfo, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
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(CpInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
pub fn descriptor(self: *const MethodInfo, constant_pool: []const ?CpInfo) ResolveError!CpInfo.Utf8 {
pub fn descriptor(self: *const MethodInfo, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const descriptor_index = self.descriptor_index - 1;
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[descriptor_index];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
};
@ -1328,32 +1321,32 @@ pub const AttributeInfo = struct {
inner_name_index: u16,
inner_class_access_flags: InnerClassAccessFlags,
pub fn innerClass(self: *const InnerClass, constant_pool: []const ?CpInfo) ResolveError!CpInfo.Class {
pub fn innerClass(self: *const InnerClass, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const inner_class_info_index = self.inner_class_info_index - 1;
if (inner_class_info_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[inner_class_info_index];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
return cp_info.?.class;
return cp_info.?;
}
pub fn outerClass(self: *const InnerClass, constant_pool: []const ?CpInfo) ResolveError!?CpInfo.Class {
pub fn outerClass(self: *const InnerClass, constant_pool: []const ?CpInfo) ResolveError!?CpInfo {
if (self.outer_class_info_index == 0) return null;
const outer_class_info_index = self.outer_class_info_index - 1;
if (outer_class_info_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[outer_class_info_index];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
return cp_info.?.class;
return cp_info.?;
}
pub fn innerName(self: *const InnerClass, constant_pool: []const ?CpInfo) ResolveError!?CpInfo.Utf8 {
pub fn innerName(self: *const InnerClass, constant_pool: []const ?CpInfo) ResolveError!?CpInfo {
if (self.inner_name_index == 0) return null;
const inner_name_index = self.inner_name_index - 1;
if (inner_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[inner_name_index];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
};
@ -1377,21 +1370,21 @@ pub const AttributeInfo = struct {
class_index: u16,
method_index: u16,
pub fn class(self: *const EnclosingMethod, constant_pool: []const ?CpInfo) ResolveError!CpInfo.Class {
pub fn class(self: *const EnclosingMethod, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const class_index = self.class_index - 1;
if (class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[class_index];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
return cp_info.?.class;
return cp_info.?;
}
pub fn method(self: *const EnclosingMethod, constant_pool: []const ?CpInfo) ResolveError!?CpInfo.NameAndType {
pub fn method(self: *const EnclosingMethod, constant_pool: []const ?CpInfo) ResolveError!?CpInfo {
if (self.method_index == 0) return null;
const method_index = self.method_index - 1;
if (method_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[method_index];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .name_and_type) return ResolveError.InvalidConstantType;
return cp_info.?.name_and_type;
return cp_info.?;
}
};
@ -1400,24 +1393,24 @@ pub const AttributeInfo = struct {
pub const Signature = struct {
signature_index: u16,
pub fn signature(self: *const Signature, constant_pool: []const ?CpInfo) ResolveError!CpInfo.Utf8 {
pub fn signature(self: *const Signature, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const signature_index = self.signature_index - 1;
if (signature_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[signature_index];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
};
pub const SourceFile = struct {
source_file_index: u16,
pub fn sourceFile(self: *const SourceFile, constant_pool: []const ?CpInfo) ResolveError!CpInfo.Utf8 {
pub fn sourceFile(self: *const SourceFile, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const source_file_index = self.source_file_index - 1;
if (source_file_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[source_file_index];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
};
@ -1657,16 +1650,16 @@ pub const AttributeInfo = struct {
allocator.free(self.info);
}
pub fn attributeName(self: *const AttributeInfo, constant_pool: []const ?CpInfo) ResolveError!CpInfo.Utf8 {
pub fn attributeName(self: *const AttributeInfo, constant_pool: []const ?CpInfo) ResolveError!CpInfo {
const attribute_name_index = self.attribute_name_index - 1;
if (attribute_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
const cp_info = constant_pool[attribute_name_index];
if (cp_info == null or @as(CpInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?.utf8;
return cp_info.?;
}
pub fn resolve(self: *const AttributeInfo, allocator: std.mem.Allocator, constant_pool: []const ?CpInfo) (ResolveError || ParseError)!?Predefined {
const attribute_name = try self.attributeName(constant_pool);
const attribute_name = (try self.attributeName(constant_pool)).utf8;
var r: std.Io.Reader = .fixed(self.info);