Introduce constant pool info formatting helper
This commit is contained in:
parent
f12bcd2911
commit
89e548c8cc
1 changed files with 70 additions and 94 deletions
|
|
@ -116,16 +116,28 @@ pub const Info = union(Info.Tag) {
|
|||
|
||||
pub const Float = struct {
|
||||
bytes: u32,
|
||||
|
||||
pub fn float(self: *const Float) f32 {
|
||||
return @bitCast(self.bytes);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Long = struct {
|
||||
high_bytes: u32,
|
||||
low_bytes: u32,
|
||||
|
||||
pub fn long(self: *const Long) u64 {
|
||||
return (@as(u64, self.high_bytes) << 32) | self.low_bytes;
|
||||
}
|
||||
};
|
||||
|
||||
pub const Double = struct {
|
||||
high_bytes: u32,
|
||||
low_bytes: u32,
|
||||
|
||||
pub fn double(self: *const Double) f64 {
|
||||
return @bitCast((@as(u64, self.high_bytes) << 32) | self.low_bytes);
|
||||
}
|
||||
};
|
||||
|
||||
pub const NameAndType = struct {
|
||||
|
|
@ -349,12 +361,12 @@ pub const Info = union(Info.Tag) {
|
|||
.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)) }),
|
||||
.float => |float| try w.print("{d}", .{ float.float() }),
|
||||
.long => |long| try w.print("{d}", .{ long.long() }),
|
||||
.double => |double| try w.print("{d}", .{ double.double() }),
|
||||
.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_handle => |method_handle| try w.print("{t} #{d}", .{ 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 }),
|
||||
|
|
@ -371,128 +383,75 @@ pub const Info = union(Info.Tag) {
|
|||
constant_pool: Self,
|
||||
) std.Io.Writer.Error!void {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("constant_value_type: {s}\n", .{ @tagName(self.*) });
|
||||
try w.print("constant_value_type: {t}\n", .{ 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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
.class => |*class| {
|
||||
try formatInfo(w, depth, indent, "name", class, .name, 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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
.field_ref => |*field_ref| {
|
||||
try formatInfo(w, depth, indent, "class", field_ref, .class, 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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
try formatInfo(w, depth, indent, "name_and_type", field_ref, .nameAndType, 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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
.method_ref => |*method_ref| {
|
||||
try formatInfo(w, depth, indent, "class", method_ref, .class, 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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
try formatInfo(w, depth, indent, "name_and_type", method_ref, .nameAndType, 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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
.interface_method_ref => |*interface_method_ref| {
|
||||
try formatInfo(w, depth, indent, "class", interface_method_ref, .class, 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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
try formatInfo(w, depth, indent, "name_and_type", interface_method_ref, .nameAndType, constant_pool);
|
||||
},
|
||||
.string => |string| {
|
||||
const s = string.string(constant_pool) catch return error.WriteFailed;
|
||||
try s.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
.string => |*string| {
|
||||
try formatInfo(w, depth, indent, "string", string, .string, constant_pool);
|
||||
},
|
||||
.integer => |integer| {
|
||||
.integer => |*integer| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("integer: {d}\n", .{ integer.bytes });
|
||||
},
|
||||
.float => |float| {
|
||||
const f: f32 = @bitCast(float.bytes);
|
||||
|
||||
.float => |*float| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("float: {d}\n", .{ f });
|
||||
try w.print("float: {d}\n", .{ float.float() });
|
||||
},
|
||||
.long => |long| {
|
||||
const l: u64 = (@as(u64, long.high_bytes) << 32) | long.low_bytes;
|
||||
|
||||
.long => |*long| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("long: {d}\n", .{ l });
|
||||
try w.print("long: {d}\n", .{ long.long() });
|
||||
},
|
||||
.double => |double| {
|
||||
const l: u64 = (@as(u64, double.high_bytes) << 32) | double.low_bytes;
|
||||
const d: f64 = @bitCast(l);
|
||||
|
||||
.double => |*double| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("double: {d}\n", .{ d });
|
||||
try w.print("double: {d}\n", .{ double.double() });
|
||||
},
|
||||
.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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
.name_and_type => |*name_and_type| {
|
||||
try formatInfo(w, depth, indent, "name", name_and_type, .name, 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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
try formatInfo(w, depth, indent, "descriptor", name_and_type, .descriptor, constant_pool);
|
||||
},
|
||||
.utf8 => |utf8| {
|
||||
.utf8 => |*utf8| {
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
try w.print("bytes: \"{s}\"\n", .{ utf8.bytes });
|
||||
},
|
||||
.method_handle => |method_handle| {
|
||||
.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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
try formatInfo(w, depth, indent, "descriptor", method_handle, .reference, 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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
.method_type => |*method_type| {
|
||||
try formatInfo(w, depth, indent, "descriptor", method_type, .descriptor, 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);
|
||||
.dynamic => |*dynamic| {
|
||||
try formatInfo(w, depth, indent, "name_and_type", dynamic, .nameAndType, 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);
|
||||
.invoke_dynamic => |*invoke_dynamic| {
|
||||
try formatInfo(w, depth, indent, "name_and_type", invoke_dynamic, .nameAndType, 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);
|
||||
.module => |*module| {
|
||||
try formatInfo(w, depth, indent, "name", module, .name, 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);
|
||||
.package => |*package| {
|
||||
try formatInfo(w, depth, indent, "name", package, .name, constant_pool);
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
@ -569,3 +528,20 @@ pub fn getLoadableOptional(self: *const Self, index: u16) ResolveError!?Info {
|
|||
if (index == 0) return null;
|
||||
return self.getLoadable(index);
|
||||
}
|
||||
|
||||
pub fn formatInfo(
|
||||
w: *std.Io.Writer,
|
||||
depth: usize,
|
||||
indent: u8,
|
||||
comptime name: []const u8,
|
||||
context: anytype,
|
||||
comptime getter: std.meta.DeclEnum(@TypeOf(context.*)),
|
||||
constant_pool: Self,
|
||||
) std.Io.Writer.Error!void {
|
||||
const func = @field(@TypeOf(context.*), @tagName(getter));
|
||||
|
||||
try w.splatByteAll(' ', depth * indent);
|
||||
_ = try w.write(name ++ ":\n");
|
||||
const info = func(context, constant_pool) catch return error.WriteFailed;
|
||||
try info.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue