From 07d43f2fe7e88eb9fab2ac26bfdce0bb41449797 Mon Sep 17 00:00:00 2001 From: ktkk Date: Sat, 4 Jul 2026 01:43:11 +0200 Subject: [PATCH] Dump constant pool in debug mode --- src/Class.zig | 59 ++++++++++++++++++++++++------------- src/Class/AttributeInfo.zig | 34 ++++++++++++--------- src/Class/FieldInfo.zig | 8 ++--- src/Class/MethodInfo.zig | 8 ++--- src/main.zig | 10 +++++++ 5 files changed, 77 insertions(+), 42 deletions(-) diff --git a/src/Class.zig b/src/Class.zig index 1eafdd6..787f7c2 100644 --- a/src/Class.zig +++ b/src/Class.zig @@ -246,11 +246,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 this_class.format(w, depth, indent + 1, self.constant_pool); + try this_class.indentedFormat(w, depth, indent + 1, self.constant_pool); _ = try w.write("super class:\n"); if (self.superClass() catch return error.WriteFailed) |super_class| { - try super_class.format(w, depth, indent + 1, self.constant_pool); + try super_class.indentedFormat(w, depth, indent + 1, self.constant_pool); } _ = try w.write("interfaces:\n"); @@ -264,7 +264,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 cp_info.?.format(w, depth, indent + 1, self.constant_pool); + try cp_info.?.indentedFormat(w, depth, indent + 1, self.constant_pool); } _ = try w.write("fields:\n"); @@ -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.format(w, depth, indent + 1, self.allocator, self.constant_pool); + try field.indentedFormat(w, depth, indent + 1, self.allocator, 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.format(w, depth, indent + 1, self.allocator, self.constant_pool); + try method.indentedFormat(w, depth, indent + 1, self.allocator, 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.format(w, depth, indent + 1, self.allocator, self.constant_pool); + try attribute.indentedFormat(w, depth, indent + 1, self.allocator, self.constant_pool); } } @@ -656,7 +656,26 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) { } } - pub fn format(self: *const ConstantPoolInfo, w: *std.Io.Writer, depth: usize, indent: u8, constant_pool: []const ?ConstantPoolInfo) std.Io.Writer.Error!void { + pub fn format(self: *const ConstantPoolInfo, w: *std.Io.Writer) std.Io.Writer.Error!void { + switch (self.*) { + .class => |class| try w.print("#{d}", .{ class.name_index }), + .field_ref => |field_ref| try w.print("#{d}.#{d}", .{ field_ref.class_index, field_ref.name_and_type_index }), + .method_ref => |method_ref| try w.print("#{d}.#{d}", .{ method_ref.class_index, method_ref.name_and_type_index }), + .interface_method_ref => |interface_method_ref| try w.print("#{d}.#{d}", .{ interface_method_ref.class_index, interface_method_ref.name_and_type_index }), + .string => |string| try w.print("#{d}", .{ string.string_index }), + .integer => |integer| try w.print("{d}", .{ integer.bytes }), + .float => |float| try w.print("{d}", .{ @as(f32, @bitCast(float.bytes)) }), + .long => |long| try w.print("{d}", .{ (@as(u64, long.high_bytes) << 32) | long.low_bytes }), + .double => |double| try w.print("{d}", .{ @as(f64, @bitCast((@as(u64, double.high_bytes) << 32) | double.low_bytes)) }), + .name_and_type => |name_and_type| try w.print("#{d}:#{d}", .{ name_and_type.name_index, name_and_type.descriptor_index }), + .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 }), + .invoke_dynamic => |invoke_dynamic| try w.print("#{d} #{d}", .{ invoke_dynamic.bootstrap_method_attr_index, invoke_dynamic.name_and_type_index }), + } + } + + pub fn indentedFormat(self: *const ConstantPoolInfo, w: *std.Io.Writer, depth: usize, indent: u8, constant_pool: []const ?ConstantPoolInfo) std.Io.Writer.Error!void { try w.splatByteAll(' ', depth * indent); try w.print("constant_value_type: {s}\n", .{ @tagName(self.*) }); @@ -665,44 +684,44 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) { 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); + try class_name.indentedFormat(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 class.indentedFormat(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); + try name_and_type.indentedFormat(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 class.indentedFormat(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); + try name_and_type.indentedFormat(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 class.indentedFormat(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); + try name_and_type.indentedFormat(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); + try s.indentedFormat(w, depth, indent + 1, constant_pool); }, .integer => |integer| { try w.splatByteAll(' ', depth * indent); @@ -731,12 +750,12 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) { 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 name.indentedFormat(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); + try descriptor.indentedFormat(w, depth, indent + 1, constant_pool); }, .utf8 => |utf8| { try w.splatByteAll(' ', depth * indent); @@ -749,19 +768,19 @@ pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) { 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); + try reference.indentedFormat(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); + try descriptor.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.format(w, depth, indent + 1, constant_pool); + try name_and_type.indentedFormat(w, depth, indent + 1, constant_pool); }, } } diff --git a/src/Class/AttributeInfo.zig b/src/Class/AttributeInfo.zig index 44edf19..aa6fce6 100644 --- a/src/Class/AttributeInfo.zig +++ b/src/Class/AttributeInfo.zig @@ -197,7 +197,7 @@ pub const AttributeInfo = union(enum) { } } - pub fn format( + pub fn indentedFormat( self: *const Self, w: *std.Io.Writer, depth: usize, @@ -213,7 +213,7 @@ pub const AttributeInfo = union(enum) { try w.splatByteAll(' ', depth * indent); _ = try w.write("name:\n"); const attribute_name = new.attributeName(constant_pool) catch return error.WriteFailed; - try attribute_name.format(w, depth, indent + 1, constant_pool); + try attribute_name.indentedFormat(w, depth, indent + 1, constant_pool); }, .predefined => |predefined| { try w.splatByteAll(' ', depth * indent); @@ -225,7 +225,7 @@ pub const AttributeInfo = union(enum) { switch (predefined) { .constant_value => |attr| { const constant_value = attr.constantValue(constant_pool) catch return error.WriteFailed; - try constant_value.format(w, depth, indent + 1, constant_pool); + try constant_value.indentedFormat(w, depth, indent + 1, constant_pool); }, .code => |attr| { try w.splatByteAll(' ', depth * indent); @@ -268,7 +268,7 @@ pub const AttributeInfo = union(enum) { try w.splatByteAll(' ', depth * attr_indent); try w.print("{d}:\n", .{ i }); - try a.format(w, depth, attr_indent + 1, allocator, constant_pool); + try a.indentedFormat(w, depth, attr_indent + 1, allocator, constant_pool); } }, //.stack_map_table, @@ -286,7 +286,7 @@ pub const AttributeInfo = union(enum) { try w.splatByteAll(' ', depth * exception_indent); try w.print("{d}:\n", .{ i }); - try cp_info.?.format(w, depth, exception_indent + 1, constant_pool); + try cp_info.?.indentedFormat(w, depth, exception_indent + 1, constant_pool); } }, .inner_classes => |attr| { @@ -299,30 +299,30 @@ pub const AttributeInfo = union(enum) { try w.splatByteAll(' ', depth * class_indent); try w.print("{d}:\n", .{ i }); - try class.format(w, depth, class_indent + 1, constant_pool); + try class.indentedFormat(w, depth, class_indent + 1, constant_pool); } }, .enclosing_method => |attr| { const class = attr.class(constant_pool) catch return error.WriteFailed; try w.splatByteAll(' ', depth * indent); _ = try w.write("class:\n"); - try class.format(w, depth, indent + 1, constant_pool); + try class.indentedFormat(w, depth, indent + 1, constant_pool); const method = attr.method(constant_pool) catch return error.WriteFailed; if (method) |m| { try w.splatByteAll(' ', depth * indent); _ = try w.write("method:\n"); - try m.format(w, depth, indent + 1, constant_pool); + try m.indentedFormat(w, depth, indent + 1, constant_pool); } }, .synthetic => {}, .signature => |attr| { const signature = attr.signature(constant_pool) catch return error.WriteFailed; - try signature.format(w, depth, indent + 1, constant_pool); + try signature.indentedFormat(w, depth, indent + 1, constant_pool); }, .source_file => |attr| { const source_file = attr.sourceFile(constant_pool) catch return error.WriteFailed; - try source_file.format(w, depth, indent + 1, constant_pool); + try source_file.indentedFormat(w, depth, indent + 1, constant_pool); }, //.source_debug_extension, //.line_number_table, @@ -675,27 +675,33 @@ pub const InnerClasses = struct { inner_name_index: u16, inner_class_access_flags: InnerClassAccessFlags, - pub fn format(self: *const InnerClass, w: *std.Io.Writer, depth: usize, indent: u8, constant_pool: []const ?ConstantPoolInfo) std.Io.Writer.Error!void { + pub fn indentedFormat( + self: *const InnerClass, + w: *std.Io.Writer, + depth: usize, + indent: u8, + constant_pool: []const ?ConstantPoolInfo, + ) std.Io.Writer.Error!void { try w.splatByteAll(' ', depth * indent); try w.print("flags: {f}\n", .{ self.inner_class_access_flags }); const inner_class = self.innerClass(constant_pool) catch return error.WriteFailed; try w.splatByteAll(' ', depth * indent); _ = try w.write("inner_class:\n"); - try inner_class.format(w, depth, indent + 1, constant_pool); + try inner_class.indentedFormat(w, depth, indent + 1, constant_pool); const outer_class = self.outerClass(constant_pool) catch return error.WriteFailed; if (outer_class) |oc| { try w.splatByteAll(' ', depth * indent); _ = try w.write("outer_class:\n"); - try oc.format(w, depth, indent + 1, constant_pool); + try oc.indentedFormat(w, depth, indent + 1, constant_pool); } const inner_name = self.innerName(constant_pool) catch return error.WriteFailed; if (inner_name) |in| { try w.splatByteAll(' ', depth * indent); _ = try w.write("inner_name:\n"); - try in.format(w, depth, indent + 1, constant_pool); + try in.indentedFormat(w, depth, indent + 1, constant_pool); } } diff --git a/src/Class/FieldInfo.zig b/src/Class/FieldInfo.zig index 2d80676..ed3cb61 100644 --- a/src/Class/FieldInfo.zig +++ b/src/Class/FieldInfo.zig @@ -48,7 +48,7 @@ pub fn deinit(self: *Self, allocator: std.mem.Allocator) void { allocator.free(self.attributes); } -pub fn format( +pub fn indentedFormat( self: *const Self, w: *std.Io.Writer, depth: usize, @@ -62,12 +62,12 @@ pub fn format( try w.splatByteAll(' ', depth * indent); _ = try w.write("name:\n"); const field_name = self.name(constant_pool) catch return error.WriteFailed; - try field_name.format(w, depth, indent + 1, constant_pool); + try field_name.indentedFormat(w, depth, indent + 1, constant_pool); try w.splatByteAll(' ', depth * indent); _ = try w.write("descriptor:\n"); const field_descriptor = self.descriptor(constant_pool) catch return error.WriteFailed; - try field_descriptor.format(w, depth, indent + 1, constant_pool); + try field_descriptor.indentedFormat(w, depth, indent + 1, constant_pool); try w.splatByteAll(' ', depth * indent); _ = try w.write("attributes:\n"); @@ -79,7 +79,7 @@ pub fn format( try w.splatByteAll(' ', depth * attr_indent); try w.print("{d}:\n", .{ j }); - try attribute.format(w, depth, attr_indent + 1, allocator, constant_pool); + try attribute.indentedFormat(w, depth, attr_indent + 1, allocator, constant_pool); } } diff --git a/src/Class/MethodInfo.zig b/src/Class/MethodInfo.zig index 4380e21..7a457ee 100644 --- a/src/Class/MethodInfo.zig +++ b/src/Class/MethodInfo.zig @@ -51,7 +51,7 @@ pub fn deinit(self: *Self, allocator: std.mem.Allocator) void { allocator.free(self.attributes); } -pub fn format( +pub fn indentedFormat( self: *const Self, w: *std.Io.Writer, depth: usize, @@ -65,12 +65,12 @@ pub fn format( try w.splatByteAll(' ', depth * indent); _ = try w.write("name:\n"); const method_name = self.name(constant_pool) catch return error.WriteFailed; - try method_name.format(w, depth, indent + 1, constant_pool); + try method_name.indentedFormat(w, depth, indent + 1, constant_pool); try w.splatByteAll(' ', depth * indent); _ = try w.write("descriptor:\n"); const method_descriptor = self.descriptor(constant_pool) catch return error.WriteFailed; - try method_descriptor.format(w, depth, indent + 1, constant_pool); + try method_descriptor.indentedFormat(w, depth, indent + 1, constant_pool); try w.splatByteAll(' ', depth * indent); _ = try w.write("attributes:\n"); @@ -82,7 +82,7 @@ pub fn format( try w.splatByteAll(' ', depth * attr_indent); try w.print("{d}:\n", .{ j }); - try attribute.format(w, depth, attr_indent + 1, allocator, constant_pool); + try attribute.indentedFormat(w, depth, attr_indent + 1, allocator, constant_pool); } } diff --git a/src/main.zig b/src/main.zig index 2dde461..4ea41ec 100644 --- a/src/main.zig +++ b/src/main.zig @@ -52,6 +52,16 @@ pub fn main(init: std.process.Init) !void { }; defer class.deinit(); + if (@import("builtin").mode == .Debug) { + for (class.constant_pool, 1..) |cp_info, i| { + if (cp_info) |info| { + std.debug.print("#{d} = {s}\t{f}\n", .{ i, @tagName(info), info }); + } else { + std.debug.print("#{d} = null\n", .{ i }); + } + } + } + try stdout.print("{f}", .{ class }); try stdout.flush();