Refactor constant pool
This commit is contained in:
parent
04cf7663af
commit
9135e95dbd
5 changed files with 689 additions and 659 deletions
577
src/Class.zig
577
src/Class.zig
|
|
@ -5,13 +5,14 @@ const EnumFlags = @import("EnumFlags.zig").EnumFlags;
|
||||||
pub const FieldInfo = @import("Class/FieldInfo.zig");
|
pub const FieldInfo = @import("Class/FieldInfo.zig");
|
||||||
pub const MethodInfo = @import("Class/MethodInfo.zig");
|
pub const MethodInfo = @import("Class/MethodInfo.zig");
|
||||||
pub const AttributeInfo = @import("Class/AttributeInfo.zig").AttributeInfo;
|
pub const AttributeInfo = @import("Class/AttributeInfo.zig").AttributeInfo;
|
||||||
|
pub const ConstantPool = @import("Class/ConstantPool.zig");
|
||||||
|
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
magic: u32,
|
magic: u32,
|
||||||
minor_version: u16,
|
minor_version: u16,
|
||||||
major_version: u16,
|
major_version: u16,
|
||||||
constant_pool: []?ConstantPoolInfo,
|
constant_pool: []?ConstantPool.Info,
|
||||||
access_flags: ClassAccessFlags,
|
access_flags: ClassAccessFlags,
|
||||||
this_class: u16,
|
this_class: u16,
|
||||||
super_class: u16,
|
super_class: u16,
|
||||||
|
|
@ -109,16 +110,16 @@ pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) (ParseError ||
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseConstantPool(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError![]?ConstantPoolInfo {
|
fn parseConstantPool(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseError![]?ConstantPool.Info {
|
||||||
const constant_pool_size = try input.takeInt(u16, .big);
|
const constant_pool_size = try input.takeInt(u16, .big);
|
||||||
const constant_pool = try allocator.alloc(?ConstantPoolInfo, constant_pool_size - 1);
|
const constant_pool = try allocator.alloc(?ConstantPool.Info, constant_pool_size - 1);
|
||||||
errdefer allocator.free(constant_pool);
|
errdefer allocator.free(constant_pool);
|
||||||
|
|
||||||
var i: usize = 0;
|
var i: usize = 0;
|
||||||
while (i < constant_pool_size - 1) {
|
while (i < constant_pool_size - 1) {
|
||||||
defer i += 1;
|
defer i += 1;
|
||||||
|
|
||||||
const cp_info = try ConstantPoolInfo.parse(input, allocator);
|
const cp_info = try ConstantPool.Info.parse(input, allocator);
|
||||||
constant_pool[i] = cp_info;
|
constant_pool[i] = cp_info;
|
||||||
|
|
||||||
switch (cp_info) {
|
switch (cp_info) {
|
||||||
|
|
@ -145,7 +146,7 @@ fn parseInterfaces(input: *std.Io.Reader, allocator: std.mem.Allocator) ParseErr
|
||||||
return interfaces;
|
return interfaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseFields(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) (ParseError || ResolveError)![]FieldInfo {
|
fn parseFields(input: *std.Io.Reader, constant_pool: []const ?ConstantPool.Info, allocator: std.mem.Allocator) (ParseError || ResolveError)![]FieldInfo {
|
||||||
const fields_count = try input.takeInt(u16, .big);
|
const fields_count = try input.takeInt(u16, .big);
|
||||||
const fields = try allocator.alloc(FieldInfo, fields_count);
|
const fields = try allocator.alloc(FieldInfo, fields_count);
|
||||||
errdefer allocator.free(fields);
|
errdefer allocator.free(fields);
|
||||||
|
|
@ -157,7 +158,7 @@ fn parseFields(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo,
|
||||||
return fields;
|
return fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseMethods(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) (ParseError || ResolveError)![]MethodInfo {
|
fn parseMethods(input: *std.Io.Reader, constant_pool: []const ?ConstantPool.Info, allocator: std.mem.Allocator) (ParseError || ResolveError)![]MethodInfo {
|
||||||
const methods_count = try input.takeInt(u16, .big);
|
const methods_count = try input.takeInt(u16, .big);
|
||||||
const methods = try allocator.alloc(MethodInfo, methods_count);
|
const methods = try allocator.alloc(MethodInfo, methods_count);
|
||||||
errdefer allocator.free(methods);
|
errdefer allocator.free(methods);
|
||||||
|
|
@ -169,7 +170,7 @@ fn parseMethods(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo,
|
||||||
return methods;
|
return methods;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parseAttributes(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) (ParseError || ResolveError)![]AttributeInfo {
|
pub fn parseAttributes(input: *std.Io.Reader, constant_pool: []const ?ConstantPool.Info, allocator: std.mem.Allocator) (ParseError || ResolveError)![]AttributeInfo {
|
||||||
const attributes_count = try input.takeInt(u16, .big);
|
const attributes_count = try input.takeInt(u16, .big);
|
||||||
const attributes = try allocator.alloc(AttributeInfo, attributes_count);
|
const attributes = try allocator.alloc(AttributeInfo, attributes_count);
|
||||||
errdefer allocator.free(attributes);
|
errdefer allocator.free(attributes);
|
||||||
|
|
@ -259,7 +260,7 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
||||||
|
|
||||||
if (interface >= self.constant_pool.len) return error.WriteFailed;
|
if (interface >= self.constant_pool.len) return error.WriteFailed;
|
||||||
const cp_info = self.constant_pool[interface - 1];
|
const cp_info = self.constant_pool[interface - 1];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return error.WriteFailed;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
@ -297,15 +298,15 @@ pub fn format(self: *const Self, w: *std.Io.Writer) std.Io.Writer.Error!void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn thisClass(self: *const Self) ResolveError!ConstantPoolInfo {
|
pub fn thisClass(self: *const Self) ResolveError!ConstantPool.Info {
|
||||||
const this_class = self.this_class - 1;
|
const this_class = self.this_class - 1;
|
||||||
if (this_class >= self.constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (this_class >= self.constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = self.constant_pool[this_class];
|
const cp_info = self.constant_pool[this_class];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn superClass(self: *const Self) ResolveError!?ConstantPoolInfo {
|
pub fn superClass(self: *const Self) ResolveError!?ConstantPool.Info {
|
||||||
if (self.super_class == 0) {
|
if (self.super_class == 0) {
|
||||||
const this_class = (try self.thisClass()).class;
|
const this_class = (try self.thisClass()).class;
|
||||||
const this_class_name = (try this_class.name(self.constant_pool)).utf8;
|
const this_class_name = (try this_class.name(self.constant_pool)).utf8;
|
||||||
|
|
@ -315,7 +316,7 @@ pub fn superClass(self: *const Self) ResolveError!?ConstantPoolInfo {
|
||||||
const super_class = self.super_class - 1;
|
const super_class = self.super_class - 1;
|
||||||
if (super_class >= self.constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (super_class >= self.constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = self.constant_pool[super_class];
|
const cp_info = self.constant_pool[super_class];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||||
|
|
||||||
if (self.access_flags.contains(.interface)) {
|
if (self.access_flags.contains(.interface)) {
|
||||||
const super_class_name = (try cp_info.?.class.name(self.constant_pool)).utf8;
|
const super_class_name = (try cp_info.?.class.name(self.constant_pool)).utf8;
|
||||||
|
|
@ -326,555 +327,3 @@ pub fn superClass(self: *const Self) ResolveError!?ConstantPoolInfo {
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const ConstantPoolInfo = union(ConstantPoolInfo.Tag) {
|
|
||||||
class: Class,
|
|
||||||
field_ref: FieldRef,
|
|
||||||
method_ref: MethodRef,
|
|
||||||
interface_method_ref: InterfaceMethodRef,
|
|
||||||
string: String,
|
|
||||||
integer: Integer,
|
|
||||||
float: Float,
|
|
||||||
long: Long,
|
|
||||||
double: Double,
|
|
||||||
name_and_type: NameAndType,
|
|
||||||
utf8: Utf8,
|
|
||||||
method_handle: MethodHandle,
|
|
||||||
method_type: MethodType,
|
|
||||||
dynamic: Dynamic,
|
|
||||||
invoke_dynamic: InvokeDynamic,
|
|
||||||
module: Module,
|
|
||||||
package: Package,
|
|
||||||
|
|
||||||
pub const Tag = enum(u8) {
|
|
||||||
class = 7,
|
|
||||||
field_ref = 9,
|
|
||||||
method_ref = 10,
|
|
||||||
interface_method_ref = 11,
|
|
||||||
string = 8,
|
|
||||||
integer = 3,
|
|
||||||
float = 4,
|
|
||||||
long = 5,
|
|
||||||
double = 6,
|
|
||||||
name_and_type = 12,
|
|
||||||
utf8 = 1,
|
|
||||||
method_handle = 15,
|
|
||||||
method_type = 16,
|
|
||||||
dynamic = 17,
|
|
||||||
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 {
|
|
||||||
name_index: u16,
|
|
||||||
|
|
||||||
pub fn name(self: *const Class, 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 FieldRef = struct {
|
|
||||||
class_index: u16,
|
|
||||||
name_and_type_index: u16,
|
|
||||||
|
|
||||||
pub fn class(self: *const FieldRef, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
|
||||||
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.?;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nameAndType(self: *const FieldRef, 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 MethodRef = struct {
|
|
||||||
class_index: u16,
|
|
||||||
name_and_type_index: u16,
|
|
||||||
|
|
||||||
pub fn class(self: *const MethodRef, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
|
||||||
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.?;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nameAndType(self: *const MethodRef, 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 InterfaceMethodRef = struct {
|
|
||||||
class_index: u16,
|
|
||||||
name_and_type_index: u16,
|
|
||||||
|
|
||||||
pub fn class(self: *const InterfaceMethodRef, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
|
||||||
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.?;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn nameAndType(self: *const InterfaceMethodRef, 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 String = struct {
|
|
||||||
string_index: u16,
|
|
||||||
|
|
||||||
pub fn string(self: *const String, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
|
||||||
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.?;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Integer = struct {
|
|
||||||
bytes: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Float = struct {
|
|
||||||
bytes: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Long = struct {
|
|
||||||
high_bytes: u32,
|
|
||||||
low_bytes: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Double = struct {
|
|
||||||
high_bytes: u32,
|
|
||||||
low_bytes: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const NameAndType = struct {
|
|
||||||
name_index: u16,
|
|
||||||
descriptor_index: u16,
|
|
||||||
|
|
||||||
pub fn name(self: *const NameAndType, 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 descriptor(self: *const NameAndType, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
|
||||||
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.?;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Utf8 = struct {
|
|
||||||
bytes: []const u8,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const MethodHandle = struct {
|
|
||||||
reference_kind: Kind,
|
|
||||||
reference_index: u16,
|
|
||||||
|
|
||||||
pub const Kind = enum(u8) {
|
|
||||||
get_field = 1,
|
|
||||||
get_static = 2,
|
|
||||||
put_field = 3,
|
|
||||||
put_static = 4,
|
|
||||||
invoke_virtual = 5,
|
|
||||||
invoke_static = 6,
|
|
||||||
invoke_special = 7,
|
|
||||||
new_invoke_special = 8,
|
|
||||||
invoke_interface = 9,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub fn reference(self: *const MethodHandle, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
|
||||||
const reference_index = self.reference_index - 1;
|
|
||||||
if (reference_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
|
||||||
const cp_info = constant_pool[reference_index];
|
|
||||||
return switch (self.reference_kind) {
|
|
||||||
.get_field, .get_static, .put_field, .put_static => blk: {
|
|
||||||
if (cp_info == null or @as(Tag, cp_info.?) != .field_ref) break :blk ResolveError.InvalidConstantType;
|
|
||||||
break :blk cp_info.?;
|
|
||||||
},
|
|
||||||
.invoke_virtual, .invoke_static, .invoke_special, .new_invoke_special => blk: {
|
|
||||||
if (cp_info == null or @as(Tag, cp_info.?) != .method_ref) break :blk ResolveError.InvalidConstantType;
|
|
||||||
break :blk cp_info.?;
|
|
||||||
},
|
|
||||||
.invoke_interface => blk: {
|
|
||||||
if (cp_info == null or @as(Tag, cp_info.?) != .interface_method_ref) break :blk ResolveError.InvalidConstantType;
|
|
||||||
break :blk cp_info.?;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const MethodType = struct {
|
|
||||||
descriptor_index: u16,
|
|
||||||
|
|
||||||
pub fn descriptor(self: *const MethodType, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
|
||||||
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.?;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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,
|
|
||||||
|
|
||||||
pub fn nameAndType(self: *const InvokeDynamic, 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 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;
|
|
||||||
|
|
||||||
return switch (tag) {
|
|
||||||
.class => .{
|
|
||||||
.class = .{
|
|
||||||
.name_index = try input.takeInt(u16, .big),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.field_ref => .{
|
|
||||||
.field_ref = .{
|
|
||||||
.class_index = try input.takeInt(u16, .big),
|
|
||||||
.name_and_type_index = try input.takeInt(u16, .big),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.method_ref => .{
|
|
||||||
.method_ref = .{
|
|
||||||
.class_index = try input.takeInt(u16, .big),
|
|
||||||
.name_and_type_index = try input.takeInt(u16, .big),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.interface_method_ref => .{
|
|
||||||
.interface_method_ref = .{
|
|
||||||
.class_index = try input.takeInt(u16, .big),
|
|
||||||
.name_and_type_index = try input.takeInt(u16, .big),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.string => .{
|
|
||||||
.string = .{
|
|
||||||
.string_index = try input.takeInt(u16, .big),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.integer => .{
|
|
||||||
.integer = .{
|
|
||||||
.bytes = try input.takeInt(u32, .big),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.float => .{
|
|
||||||
.integer = .{
|
|
||||||
.bytes = try input.takeInt(u32, .big),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.long => .{
|
|
||||||
.long = .{
|
|
||||||
.high_bytes = try input.takeInt(u32, .big),
|
|
||||||
.low_bytes = try input.takeInt(u32, .big),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.double => .{
|
|
||||||
.double = .{
|
|
||||||
.high_bytes = try input.takeInt(u32, .big),
|
|
||||||
.low_bytes = try input.takeInt(u32, .big),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.name_and_type => .{
|
|
||||||
.name_and_type = .{
|
|
||||||
.name_index = try input.takeInt(u16, .big),
|
|
||||||
.descriptor_index = try input.takeInt(u16, .big),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.utf8 => blk: {
|
|
||||||
const length = try input.takeInt(u16, .big);
|
|
||||||
const bytes = try input.readAlloc(allocator, length);
|
|
||||||
|
|
||||||
break :blk .{
|
|
||||||
.utf8 = .{
|
|
||||||
.bytes = bytes,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
.method_handle => blk: {
|
|
||||||
const kind_byte = try input.takeByte();
|
|
||||||
const kind = std.enums.fromInt(MethodHandle.Kind, kind_byte) orelse return ParseError.InvalidTag;
|
|
||||||
|
|
||||||
break :blk .{
|
|
||||||
.method_handle = .{
|
|
||||||
.reference_kind = kind,
|
|
||||||
.reference_index = try input.takeInt(u16, .big),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
.method_type => .{
|
|
||||||
.method_type = .{
|
|
||||||
.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),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(self: *ConstantPoolInfo, allocator: std.mem.Allocator) void {
|
|
||||||
switch (self.*) {
|
|
||||||
.utf8 => |info| allocator.free(info.bytes),
|
|
||||||
else => {},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 }),
|
|
||||||
.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 }),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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.*) });
|
|
||||||
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
.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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
.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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
.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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
},
|
|
||||||
.string => |string| {
|
|
||||||
const s = string.string(constant_pool) catch return error.WriteFailed;
|
|
||||||
try s.indentedFormat(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.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.indentedFormat(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.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.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);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ const std = @import("std");
|
||||||
const EnumFlags = @import("../EnumFlags.zig").EnumFlags;
|
const EnumFlags = @import("../EnumFlags.zig").EnumFlags;
|
||||||
|
|
||||||
const Class = @import("../Class.zig");
|
const Class = @import("../Class.zig");
|
||||||
const ConstantPoolInfo = Class.ConstantPoolInfo;
|
const ConstantPool = Class.ConstantPool;
|
||||||
const ParseError = Class.ParseError;
|
const ParseError = Class.ParseError;
|
||||||
const ResolveError = Class.ResolveError;
|
const ResolveError = Class.ResolveError;
|
||||||
|
|
||||||
|
|
@ -44,11 +44,11 @@ pub const AttributeInfo = union(enum) {
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) (ParseError || ResolveError)!AttributeInfo {
|
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPool.Info, allocator: std.mem.Allocator) (ParseError || ResolveError)!AttributeInfo {
|
||||||
const attribute_name_index = try input.takeInt(u16, .big) - 1;
|
const attribute_name_index = try input.takeInt(u16, .big) - 1;
|
||||||
if (attribute_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (attribute_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[attribute_name_index];
|
const cp_info = constant_pool[attribute_name_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
const attribute_name = cp_info.?.utf8;
|
const attribute_name = cp_info.?.utf8;
|
||||||
|
|
||||||
const attribute_length = try input.takeInt(u32, .big);
|
const attribute_length = try input.takeInt(u32, .big);
|
||||||
|
|
@ -266,7 +266,7 @@ pub const AttributeInfo = union(enum) {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
switch (self.*) {
|
switch (self.*) {
|
||||||
.new => |new| {
|
.new => |new| {
|
||||||
|
|
@ -347,7 +347,7 @@ pub const AttributeInfo = union(enum) {
|
||||||
|
|
||||||
if (index >= constant_pool.len) return error.WriteFailed;
|
if (index >= constant_pool.len) return error.WriteFailed;
|
||||||
const cp_info = constant_pool[index];
|
const cp_info = constant_pool[index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return error.WriteFailed;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * exception_indent);
|
try w.splatByteAll(' ', depth * exception_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
@ -486,7 +486,7 @@ pub const AttributeInfo = union(enum) {
|
||||||
|
|
||||||
if (index >= constant_pool.len) return error.WriteFailed;
|
if (index >= constant_pool.len) return error.WriteFailed;
|
||||||
const cp_info = constant_pool[index];
|
const cp_info = constant_pool[index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .package) return error.WriteFailed;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .package) return error.WriteFailed;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * package_indent);
|
try w.splatByteAll(' ', depth * package_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
@ -517,7 +517,7 @@ pub const AttributeInfo = union(enum) {
|
||||||
|
|
||||||
if (index >= constant_pool.len) return error.WriteFailed;
|
if (index >= constant_pool.len) return error.WriteFailed;
|
||||||
const cp_info = constant_pool[index];
|
const cp_info = constant_pool[index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return error.WriteFailed;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * class_indent);
|
try w.splatByteAll(' ', depth * class_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
@ -549,7 +549,7 @@ pub const AttributeInfo = union(enum) {
|
||||||
|
|
||||||
if (index >= constant_pool.len) return error.WriteFailed;
|
if (index >= constant_pool.len) return error.WriteFailed;
|
||||||
const cp_info = constant_pool[index];
|
const cp_info = constant_pool[index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return error.WriteFailed;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * class_indent);
|
try w.splatByteAll(' ', depth * class_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
@ -580,11 +580,11 @@ pub const NewAttribute = struct {
|
||||||
allocator.free(self.info);
|
allocator.free(self.info);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn attributeName(self: *const Self, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn attributeName(self: *const Self, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const attribute_name_index = self.attribute_name_index - 1;
|
const attribute_name_index = self.attribute_name_index - 1;
|
||||||
if (attribute_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (attribute_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[attribute_name_index];
|
const cp_info = constant_pool[attribute_name_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
|
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
@ -601,7 +601,7 @@ pub const ConstantValue = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn constantValue(self: *const Self, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn constantValue(self: *const Self, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const constant_value_index = self.constant_value_index - 1;
|
const constant_value_index = self.constant_value_index - 1;
|
||||||
if (constant_value_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (constant_value_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[constant_value_index];
|
const cp_info = constant_pool[constant_value_index];
|
||||||
|
|
@ -631,7 +631,7 @@ pub const Code = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
try w.print("start_pc: {d}\n", .{ self.start_pc });
|
try w.print("start_pc: {d}\n", .{ self.start_pc });
|
||||||
|
|
@ -650,17 +650,17 @@ pub const Code = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn catchType(self: *const ExceptionHandler, constant_pool: []const ?ConstantPoolInfo) ResolveError!?ConstantPoolInfo {
|
pub fn catchType(self: *const ExceptionHandler, constant_pool: []const ?ConstantPool.Info) ResolveError!?ConstantPool.Info {
|
||||||
if (self.catch_type == 0) return null;
|
if (self.catch_type == 0) return null;
|
||||||
const catch_type = self.catch_type - 1;
|
const catch_type = self.catch_type - 1;
|
||||||
if (catch_type >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (catch_type >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[catch_type];
|
const cp_info = constant_pool[catch_type];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) (ParseError || ResolveError)!Self {
|
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPool.Info, allocator: std.mem.Allocator) (ParseError || ResolveError)!Self {
|
||||||
const max_stack = try input.takeInt(u16, .big);
|
const max_stack = try input.takeInt(u16, .big);
|
||||||
const max_locals = try input.takeInt(u16, .big);
|
const max_locals = try input.takeInt(u16, .big);
|
||||||
|
|
||||||
|
|
@ -947,7 +947,7 @@ pub const InnerClasses = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
try w.print("flags: {f}\n", .{ self.inner_class_access_flags });
|
try w.print("flags: {f}\n", .{ self.inner_class_access_flags });
|
||||||
|
|
@ -972,31 +972,31 @@ pub const InnerClasses = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn innerClass(self: *const InnerClass, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn innerClass(self: *const InnerClass, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const inner_class_info_index = self.inner_class_info_index - 1;
|
const inner_class_info_index = self.inner_class_info_index - 1;
|
||||||
if (inner_class_info_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (inner_class_info_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[inner_class_info_index];
|
const cp_info = constant_pool[inner_class_info_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn outerClass(self: *const InnerClass, constant_pool: []const ?ConstantPoolInfo) ResolveError!?ConstantPoolInfo {
|
pub fn outerClass(self: *const InnerClass, constant_pool: []const ?ConstantPool.Info) ResolveError!?ConstantPool.Info {
|
||||||
if (self.outer_class_info_index == 0) return null;
|
if (self.outer_class_info_index == 0) return null;
|
||||||
const outer_class_info_index = self.outer_class_info_index - 1;
|
const outer_class_info_index = self.outer_class_info_index - 1;
|
||||||
if (outer_class_info_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (outer_class_info_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
|
|
||||||
const cp_info = constant_pool[outer_class_info_index];
|
const cp_info = constant_pool[outer_class_info_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn innerName(self: *const InnerClass, constant_pool: []const ?ConstantPoolInfo) ResolveError!?ConstantPoolInfo {
|
pub fn innerName(self: *const InnerClass, constant_pool: []const ?ConstantPool.Info) ResolveError!?ConstantPool.Info {
|
||||||
if (self.inner_name_index == 0) return null;
|
if (self.inner_name_index == 0) return null;
|
||||||
const inner_name_index = self.inner_name_index - 1;
|
const inner_name_index = self.inner_name_index - 1;
|
||||||
if (inner_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (inner_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
|
|
||||||
const cp_info = constant_pool[inner_name_index];
|
const cp_info = constant_pool[inner_name_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1037,20 +1037,20 @@ pub const EnclosingMethod = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn class(self: *const EnclosingMethod, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn class(self: *const EnclosingMethod, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const class_index = self.class_index - 1;
|
const class_index = self.class_index - 1;
|
||||||
if (class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[class_index];
|
const cp_info = constant_pool[class_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn method(self: *const EnclosingMethod, constant_pool: []const ?ConstantPoolInfo) ResolveError!?ConstantPoolInfo {
|
pub fn method(self: *const EnclosingMethod, constant_pool: []const ?ConstantPool.Info) ResolveError!?ConstantPool.Info {
|
||||||
if (self.method_index == 0) return null;
|
if (self.method_index == 0) return null;
|
||||||
const method_index = self.method_index - 1;
|
const method_index = self.method_index - 1;
|
||||||
if (method_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (method_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[method_index];
|
const cp_info = constant_pool[method_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .name_and_type) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .name_and_type) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1068,11 +1068,11 @@ pub const Signature = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn signature(self: *const Signature, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn signature(self: *const Signature, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const signature_index = self.signature_index - 1;
|
const signature_index = self.signature_index - 1;
|
||||||
if (signature_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (signature_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[signature_index];
|
const cp_info = constant_pool[signature_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1088,11 +1088,11 @@ pub const SourceFile = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sourceFile(self: *const SourceFile, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn sourceFile(self: *const SourceFile, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const source_file_index = self.source_file_index - 1;
|
const source_file_index = self.source_file_index - 1;
|
||||||
if (source_file_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (source_file_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[source_file_index];
|
const cp_info = constant_pool[source_file_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1174,7 +1174,7 @@ pub const LocalVariableTable = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
try w.print("start_pc: {d}\n", .{ self.start_pc });
|
try w.print("start_pc: {d}\n", .{ self.start_pc });
|
||||||
|
|
@ -1193,19 +1193,19 @@ pub const LocalVariableTable = struct {
|
||||||
try descriptor_.indentedFormat(w, depth, indent + 1, constant_pool);
|
try descriptor_.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self: *const LocalVariable, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn name(self: *const LocalVariable, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const name_index = self.name_index - 1;
|
const name_index = self.name_index - 1;
|
||||||
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[name_index];
|
const cp_info = constant_pool[name_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn descriptor(self: *const LocalVariable, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn descriptor(self: *const LocalVariable, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const descriptor_index = self.descriptor_index - 1;
|
const descriptor_index = self.descriptor_index - 1;
|
||||||
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[descriptor_index];
|
const cp_info = constant_pool[descriptor_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1251,7 +1251,7 @@ pub const LocalVariableTypeTable = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
try w.print("start_pc: {d}\n", .{ self.start_pc });
|
try w.print("start_pc: {d}\n", .{ self.start_pc });
|
||||||
|
|
@ -1270,19 +1270,19 @@ pub const LocalVariableTypeTable = struct {
|
||||||
try signature_.indentedFormat(w, depth, indent + 1, constant_pool);
|
try signature_.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self: *const LocalVariableType, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn name(self: *const LocalVariableType, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const name_index = self.name_index - 1;
|
const name_index = self.name_index - 1;
|
||||||
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[name_index];
|
const cp_info = constant_pool[name_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn signature(self: *const LocalVariableType, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn signature(self: *const LocalVariableType, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const signature_index = self.signature_index - 1;
|
const signature_index = self.signature_index - 1;
|
||||||
if (signature_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (signature_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[signature_index];
|
const cp_info = constant_pool[signature_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1623,7 +1623,7 @@ pub const BootstrapMethods = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
const bootstrap_method = self.bootstrapMethod(constant_pool) catch return error.WriteFailed;
|
const bootstrap_method = self.bootstrapMethod(constant_pool) catch return error.WriteFailed;
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
|
@ -1641,7 +1641,7 @@ pub const BootstrapMethods = struct {
|
||||||
|
|
||||||
if (index >= constant_pool.len) return error.WriteFailed;
|
if (index >= constant_pool.len) return error.WriteFailed;
|
||||||
const cp_info = constant_pool[index];
|
const cp_info = constant_pool[index];
|
||||||
if (cp_info == null or !@as(ConstantPoolInfo.Tag, cp_info.?).loadable()) return error.WriteFailed;
|
if (cp_info == null or !@as(ConstantPool.Info.Tag, cp_info.?).loadable()) return error.WriteFailed;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * bootstrap_argument_indent);
|
try w.splatByteAll(' ', depth * bootstrap_argument_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
@ -1649,11 +1649,11 @@ pub const BootstrapMethods = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bootstrapMethod(self: *const BootstrapMethod, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn bootstrapMethod(self: *const BootstrapMethod, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const bootstrap_method_ref = self.bootstrap_method_ref - 1;
|
const bootstrap_method_ref = self.bootstrap_method_ref - 1;
|
||||||
if (bootstrap_method_ref >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (bootstrap_method_ref >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[bootstrap_method_ref];
|
const cp_info = constant_pool[bootstrap_method_ref];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .method_handle) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .method_handle) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1711,7 +1711,7 @@ pub const MethodParameters = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
try w.print("flags: {f}\n", .{ self.access_flags });
|
try w.print("flags: {f}\n", .{ self.access_flags });
|
||||||
|
|
@ -1722,11 +1722,11 @@ pub const MethodParameters = struct {
|
||||||
try name_.indentedFormat(w, depth, indent + 1, constant_pool);
|
try name_.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self: *const Parameter, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn name(self: *const Parameter, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const name_index = self.name_index - 1;
|
const name_index = self.name_index - 1;
|
||||||
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[name_index];
|
const cp_info = constant_pool[name_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1787,7 +1787,7 @@ pub const Module = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
const requires_ = self.requires(constant_pool) catch return error.WriteFailed;
|
const requires_ = self.requires(constant_pool) catch return error.WriteFailed;
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
|
@ -1805,20 +1805,20 @@ pub const Module = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn requires(self: *const Requires, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn requires(self: *const Requires, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const requires_index = self.requires_index - 1;
|
const requires_index = self.requires_index - 1;
|
||||||
if (requires_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (requires_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[requires_index];
|
const cp_info = constant_pool[requires_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .module) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .module) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn requiresVersion(self: *const Requires, constant_pool: []const ?ConstantPoolInfo) ResolveError!?ConstantPoolInfo {
|
pub fn requiresVersion(self: *const Requires, constant_pool: []const ?ConstantPool.Info) ResolveError!?ConstantPool.Info {
|
||||||
if (self.requires_version_index == 0) return null;
|
if (self.requires_version_index == 0) return null;
|
||||||
const requires_version_index = self.requires_version_index - 1;
|
const requires_version_index = self.requires_version_index - 1;
|
||||||
if (requires_version_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (requires_version_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[requires_version_index];
|
const cp_info = constant_pool[requires_version_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1838,7 +1838,7 @@ pub const Module = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
const exports_ = self.exports(constant_pool) catch return error.WriteFailed;
|
const exports_ = self.exports(constant_pool) catch return error.WriteFailed;
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
|
@ -1859,7 +1859,7 @@ pub const Module = struct {
|
||||||
|
|
||||||
if (index >= constant_pool.len) return error.WriteFailed;
|
if (index >= constant_pool.len) return error.WriteFailed;
|
||||||
const cp_info = constant_pool[index];
|
const cp_info = constant_pool[index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .module) return error.WriteFailed;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .module) return error.WriteFailed;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * exports_to_indent);
|
try w.splatByteAll(' ', depth * exports_to_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
@ -1867,11 +1867,11 @@ pub const Module = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn exports(self: *const Exports, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn exports(self: *const Exports, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const exports_index = self.exports_index - 1;
|
const exports_index = self.exports_index - 1;
|
||||||
if (exports_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (exports_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[exports_index];
|
const cp_info = constant_pool[exports_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .package) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .package) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1891,7 +1891,7 @@ pub const Module = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
const opens_ = self.opens(constant_pool) catch return error.WriteFailed;
|
const opens_ = self.opens(constant_pool) catch return error.WriteFailed;
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
|
@ -1912,7 +1912,7 @@ pub const Module = struct {
|
||||||
|
|
||||||
if (index >= constant_pool.len) return error.WriteFailed;
|
if (index >= constant_pool.len) return error.WriteFailed;
|
||||||
const cp_info = constant_pool[index];
|
const cp_info = constant_pool[index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .module) return error.WriteFailed;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .module) return error.WriteFailed;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * opens_to_indent);
|
try w.splatByteAll(' ', depth * opens_to_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
@ -1920,11 +1920,11 @@ pub const Module = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn opens(self: *const Opens, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn opens(self: *const Opens, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const opens_index = self.opens_index - 1;
|
const opens_index = self.opens_index - 1;
|
||||||
if (opens_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (opens_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[opens_index];
|
const cp_info = constant_pool[opens_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .package) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .package) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -1938,7 +1938,7 @@ pub const Module = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
const provides_ = self.provides(constant_pool) catch return error.WriteFailed;
|
const provides_ = self.provides(constant_pool) catch return error.WriteFailed;
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
|
@ -1956,7 +1956,7 @@ pub const Module = struct {
|
||||||
|
|
||||||
if (index >= constant_pool.len) return error.WriteFailed;
|
if (index >= constant_pool.len) return error.WriteFailed;
|
||||||
const cp_info = constant_pool[index];
|
const cp_info = constant_pool[index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return error.WriteFailed;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * provides_with_indent);
|
try w.splatByteAll(' ', depth * provides_with_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
@ -1964,11 +1964,11 @@ pub const Module = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provides(self: *const Provides, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn provides(self: *const Provides, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const provides_index = self.provides_index - 1;
|
const provides_index = self.provides_index - 1;
|
||||||
if (provides_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (provides_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[provides_index];
|
const cp_info = constant_pool[provides_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -2088,7 +2088,7 @@ pub const Module = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
const module_name = self.moduleName(constant_pool) catch return error.WriteFailed;
|
const module_name = self.moduleName(constant_pool) catch return error.WriteFailed;
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
|
@ -2152,7 +2152,7 @@ pub const Module = struct {
|
||||||
|
|
||||||
if (index >= constant_pool.len) return error.WriteFailed;
|
if (index >= constant_pool.len) return error.WriteFailed;
|
||||||
const cp_info = constant_pool[index];
|
const cp_info = constant_pool[index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return error.WriteFailed;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return error.WriteFailed;
|
||||||
|
|
||||||
try w.splatByteAll(' ', depth * uses_indent);
|
try w.splatByteAll(' ', depth * uses_indent);
|
||||||
try w.print("{d}:\n", .{ i });
|
try w.print("{d}:\n", .{ i });
|
||||||
|
|
@ -2172,20 +2172,20 @@ pub const Module = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn moduleName(self: *const Module, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn moduleName(self: *const Module, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const module_name_index = self.module_name_index - 1;
|
const module_name_index = self.module_name_index - 1;
|
||||||
if (module_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (module_name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[module_name_index];
|
const cp_info = constant_pool[module_name_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn moduleVersion(self: *const Module, constant_pool: []const ?ConstantPoolInfo) ResolveError!?ConstantPoolInfo {
|
pub fn moduleVersion(self: *const Module, constant_pool: []const ?ConstantPool.Info) ResolveError!?ConstantPool.Info {
|
||||||
if (self.module_version_index == 0) return null;
|
if (self.module_version_index == 0) return null;
|
||||||
const module_version_index = self.module_version_index - 1;
|
const module_version_index = self.module_version_index - 1;
|
||||||
if (module_version_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (module_version_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[module_version_index];
|
const cp_info = constant_pool[module_version_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -2224,11 +2224,11 @@ pub const ModuleMainClass = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mainClass(self: *const ModuleMainClass, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn mainClass(self: *const ModuleMainClass, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const main_class_index = self.main_class_index - 1;
|
const main_class_index = self.main_class_index - 1;
|
||||||
if (main_class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (main_class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[main_class_index];
|
const cp_info = constant_pool[main_class_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -2244,11 +2244,11 @@ pub const NestHost = struct {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn hostClass(self: *const NestHost, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn hostClass(self: *const NestHost, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const host_class_index = self.host_class_index - 1;
|
const host_class_index = self.host_class_index - 1;
|
||||||
if (host_class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (host_class_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[host_class_index];
|
const cp_info = constant_pool[host_class_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -2285,7 +2285,7 @@ pub const Record = struct {
|
||||||
descriptor_index: u16,
|
descriptor_index: u16,
|
||||||
attributes: []AttributeInfo,
|
attributes: []AttributeInfo,
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) (ParseError || ResolveError)!RecordComponentInfo {
|
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPool.Info, allocator: std.mem.Allocator) (ParseError || ResolveError)!RecordComponentInfo {
|
||||||
const name_index = try input.takeInt(u16, .big);
|
const name_index = try input.takeInt(u16, .big);
|
||||||
const descriptor_index = try input.takeInt(u16, .big);
|
const descriptor_index = try input.takeInt(u16, .big);
|
||||||
|
|
||||||
|
|
@ -2315,7 +2315,7 @@ pub const Record = struct {
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
const name_ = self.name(constant_pool) catch return error.WriteFailed;
|
const name_ = self.name(constant_pool) catch return error.WriteFailed;
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
|
|
@ -2341,24 +2341,24 @@ pub const Record = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self: *const RecordComponentInfo, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn name(self: *const RecordComponentInfo, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const name_index = self.name_index - 1;
|
const name_index = self.name_index - 1;
|
||||||
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[name_index];
|
const cp_info = constant_pool[name_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn descriptor(self: *const RecordComponentInfo, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn descriptor(self: *const RecordComponentInfo, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const descriptor_index = self.descriptor_index - 1;
|
const descriptor_index = self.descriptor_index - 1;
|
||||||
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[descriptor_index];
|
const cp_info = constant_pool[descriptor_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) (ParseError || ResolveError)!Self {
|
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPool.Info, allocator: std.mem.Allocator) (ParseError || ResolveError)!Self {
|
||||||
const components_count = try input.takeInt(u16, .big);
|
const components_count = try input.takeInt(u16, .big);
|
||||||
const components = try allocator.alloc(RecordComponentInfo, components_count);
|
const components = try allocator.alloc(RecordComponentInfo, components_count);
|
||||||
for (components) |*component| {
|
for (components) |*component| {
|
||||||
|
|
|
||||||
581
src/Class/ConstantPool.zig
Normal file
581
src/Class/ConstantPool.zig
Normal file
|
|
@ -0,0 +1,581 @@
|
||||||
|
const std = @import("std");
|
||||||
|
|
||||||
|
const Class = @import("../Class.zig");
|
||||||
|
const AttributeInfo = Class.AttributeInfo;
|
||||||
|
const ParseError = Class.ParseError;
|
||||||
|
const ResolveError = Class.ResolveError;
|
||||||
|
|
||||||
|
pub const Info = union(Info.Tag) {
|
||||||
|
class: Info.Class,
|
||||||
|
field_ref: FieldRef,
|
||||||
|
method_ref: MethodRef,
|
||||||
|
interface_method_ref: InterfaceMethodRef,
|
||||||
|
string: String,
|
||||||
|
integer: Integer,
|
||||||
|
float: Float,
|
||||||
|
long: Long,
|
||||||
|
double: Double,
|
||||||
|
name_and_type: NameAndType,
|
||||||
|
utf8: Utf8,
|
||||||
|
method_handle: MethodHandle,
|
||||||
|
method_type: MethodType,
|
||||||
|
dynamic: Dynamic,
|
||||||
|
invoke_dynamic: InvokeDynamic,
|
||||||
|
module: Module,
|
||||||
|
package: Package,
|
||||||
|
|
||||||
|
pub const Tag = enum(u8) {
|
||||||
|
class = 7,
|
||||||
|
field_ref = 9,
|
||||||
|
method_ref = 10,
|
||||||
|
interface_method_ref = 11,
|
||||||
|
string = 8,
|
||||||
|
integer = 3,
|
||||||
|
float = 4,
|
||||||
|
long = 5,
|
||||||
|
double = 6,
|
||||||
|
name_and_type = 12,
|
||||||
|
utf8 = 1,
|
||||||
|
method_handle = 15,
|
||||||
|
method_type = 16,
|
||||||
|
dynamic = 17,
|
||||||
|
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 {
|
||||||
|
name_index: u16,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn name(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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 FieldRef = struct {
|
||||||
|
class_index: u16,
|
||||||
|
name_and_type_index: u16,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn class(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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.?;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nameAndType(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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 MethodRef = struct {
|
||||||
|
class_index: u16,
|
||||||
|
name_and_type_index: u16,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn class(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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.?;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nameAndType(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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 InterfaceMethodRef = struct {
|
||||||
|
class_index: u16,
|
||||||
|
name_and_type_index: u16,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn class(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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.?;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn nameAndType(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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 String = struct {
|
||||||
|
string_index: u16,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn string(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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.?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Integer = struct {
|
||||||
|
bytes: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Float = struct {
|
||||||
|
bytes: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Long = struct {
|
||||||
|
high_bytes: u32,
|
||||||
|
low_bytes: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Double = struct {
|
||||||
|
high_bytes: u32,
|
||||||
|
low_bytes: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const NameAndType = struct {
|
||||||
|
name_index: u16,
|
||||||
|
descriptor_index: u16,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn name(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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 descriptor(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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.?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Utf8 = struct {
|
||||||
|
bytes: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MethodHandle = struct {
|
||||||
|
reference_kind: Kind,
|
||||||
|
reference_index: u16,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub const Kind = enum(u8) {
|
||||||
|
get_field = 1,
|
||||||
|
get_static = 2,
|
||||||
|
put_field = 3,
|
||||||
|
put_static = 4,
|
||||||
|
invoke_virtual = 5,
|
||||||
|
invoke_static = 6,
|
||||||
|
invoke_special = 7,
|
||||||
|
new_invoke_special = 8,
|
||||||
|
invoke_interface = 9,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub fn reference(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
const reference_index = self.reference_index - 1;
|
||||||
|
if (reference_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
|
const cp_info = constant_pool[reference_index];
|
||||||
|
return switch (self.reference_kind) {
|
||||||
|
.get_field, .get_static, .put_field, .put_static => blk: {
|
||||||
|
if (cp_info == null or @as(Tag, cp_info.?) != .field_ref) break :blk ResolveError.InvalidConstantType;
|
||||||
|
break :blk cp_info.?;
|
||||||
|
},
|
||||||
|
.invoke_virtual, .invoke_static, .invoke_special, .new_invoke_special => blk: {
|
||||||
|
if (cp_info == null or @as(Tag, cp_info.?) != .method_ref) break :blk ResolveError.InvalidConstantType;
|
||||||
|
break :blk cp_info.?;
|
||||||
|
},
|
||||||
|
.invoke_interface => blk: {
|
||||||
|
if (cp_info == null or @as(Tag, cp_info.?) != .interface_method_ref) break :blk ResolveError.InvalidConstantType;
|
||||||
|
break :blk cp_info.?;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const MethodType = struct {
|
||||||
|
descriptor_index: u16,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn descriptor(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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.?;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const Dynamic = struct {
|
||||||
|
bootstrap_method_attr_index: u16,
|
||||||
|
name_and_type_index: u16,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn nameAndType(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn nameAndType(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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 Module = struct {
|
||||||
|
name_index: u16,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn name(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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,
|
||||||
|
|
||||||
|
const Self = @This();
|
||||||
|
|
||||||
|
pub fn name(self: *const Self, constant_pool: []const ?Info) ResolveError!Info {
|
||||||
|
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!Info {
|
||||||
|
const tag_byte = try input.takeByte();
|
||||||
|
const tag = std.enums.fromInt(Tag, tag_byte) orelse return ParseError.InvalidTag;
|
||||||
|
|
||||||
|
return switch (tag) {
|
||||||
|
.class => .{
|
||||||
|
.class = .{
|
||||||
|
.name_index = try input.takeInt(u16, .big),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.field_ref => .{
|
||||||
|
.field_ref = .{
|
||||||
|
.class_index = try input.takeInt(u16, .big),
|
||||||
|
.name_and_type_index = try input.takeInt(u16, .big),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.method_ref => .{
|
||||||
|
.method_ref = .{
|
||||||
|
.class_index = try input.takeInt(u16, .big),
|
||||||
|
.name_and_type_index = try input.takeInt(u16, .big),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.interface_method_ref => .{
|
||||||
|
.interface_method_ref = .{
|
||||||
|
.class_index = try input.takeInt(u16, .big),
|
||||||
|
.name_and_type_index = try input.takeInt(u16, .big),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.string => .{
|
||||||
|
.string = .{
|
||||||
|
.string_index = try input.takeInt(u16, .big),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.integer => .{
|
||||||
|
.integer = .{
|
||||||
|
.bytes = try input.takeInt(u32, .big),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.float => .{
|
||||||
|
.integer = .{
|
||||||
|
.bytes = try input.takeInt(u32, .big),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.long => .{
|
||||||
|
.long = .{
|
||||||
|
.high_bytes = try input.takeInt(u32, .big),
|
||||||
|
.low_bytes = try input.takeInt(u32, .big),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.double => .{
|
||||||
|
.double = .{
|
||||||
|
.high_bytes = try input.takeInt(u32, .big),
|
||||||
|
.low_bytes = try input.takeInt(u32, .big),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.name_and_type => .{
|
||||||
|
.name_and_type = .{
|
||||||
|
.name_index = try input.takeInt(u16, .big),
|
||||||
|
.descriptor_index = try input.takeInt(u16, .big),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.utf8 => blk: {
|
||||||
|
const length = try input.takeInt(u16, .big);
|
||||||
|
const bytes = try input.readAlloc(allocator, length);
|
||||||
|
|
||||||
|
break :blk .{
|
||||||
|
.utf8 = .{
|
||||||
|
.bytes = bytes,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
.method_handle => blk: {
|
||||||
|
const kind_byte = try input.takeByte();
|
||||||
|
const kind = std.enums.fromInt(MethodHandle.Kind, kind_byte) orelse return ParseError.InvalidTag;
|
||||||
|
|
||||||
|
break :blk .{
|
||||||
|
.method_handle = .{
|
||||||
|
.reference_kind = kind,
|
||||||
|
.reference_index = try input.takeInt(u16, .big),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
.method_type => .{
|
||||||
|
.method_type = .{
|
||||||
|
.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),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *Info, allocator: std.mem.Allocator) void {
|
||||||
|
switch (self.*) {
|
||||||
|
.utf8 => |info| allocator.free(info.bytes),
|
||||||
|
else => {},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn format(self: *const Info, 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 }),
|
||||||
|
.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 }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn indentedFormat(
|
||||||
|
self: *const Info,
|
||||||
|
w: *std.Io.Writer,
|
||||||
|
depth: usize,
|
||||||
|
indent: u8,
|
||||||
|
constant_pool: []const ?Info,
|
||||||
|
) 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.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.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.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.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.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.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.indentedFormat(w, depth, indent + 1, constant_pool);
|
||||||
|
},
|
||||||
|
.string => |string| {
|
||||||
|
const s = string.string(constant_pool) catch return error.WriteFailed;
|
||||||
|
try s.indentedFormat(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.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.indentedFormat(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.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.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);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -3,7 +3,7 @@ const std = @import("std");
|
||||||
const EnumFlags = @import("../EnumFlags.zig").EnumFlags;
|
const EnumFlags = @import("../EnumFlags.zig").EnumFlags;
|
||||||
|
|
||||||
const Class = @import("../Class.zig");
|
const Class = @import("../Class.zig");
|
||||||
const ConstantPoolInfo = Class.ConstantPoolInfo;
|
const ConstantPool = Class.ConstantPool;
|
||||||
const AttributeInfo = Class.AttributeInfo;
|
const AttributeInfo = Class.AttributeInfo;
|
||||||
const ResolveError = Class.ResolveError;
|
const ResolveError = Class.ResolveError;
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ pub const FieldAccessFlags = EnumFlags(enum(u16) {
|
||||||
@"enum" = 0x4000,
|
@"enum" = 0x4000,
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) !Self {
|
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPool.Info, allocator: std.mem.Allocator) !Self {
|
||||||
const access_flags: FieldAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
|
const access_flags: FieldAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
|
||||||
const name_index = try input.takeInt(u16, .big);
|
const name_index = try input.takeInt(u16, .big);
|
||||||
const descriptor_index = try input.takeInt(u16, .big);
|
const descriptor_index = try input.takeInt(u16, .big);
|
||||||
|
|
@ -51,7 +51,7 @@ pub fn indentedFormat(
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
try w.print("flags: {f}\n", .{ self.access_flags });
|
try w.print("flags: {f}\n", .{ self.access_flags });
|
||||||
|
|
@ -80,19 +80,19 @@ pub fn indentedFormat(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self: *const Self, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn name(self: *const Self, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const name_index = self.name_index - 1;
|
const name_index = self.name_index - 1;
|
||||||
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[name_index];
|
const cp_info = constant_pool[name_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn descriptor(self: *const Self, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn descriptor(self: *const Self, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const descriptor_index = self.descriptor_index - 1;
|
const descriptor_index = self.descriptor_index - 1;
|
||||||
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[descriptor_index];
|
const cp_info = constant_pool[descriptor_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ const std = @import("std");
|
||||||
const EnumFlags = @import("../EnumFlags.zig").EnumFlags;
|
const EnumFlags = @import("../EnumFlags.zig").EnumFlags;
|
||||||
|
|
||||||
const Class = @import("../Class.zig");
|
const Class = @import("../Class.zig");
|
||||||
const ConstantPoolInfo = Class.ConstantPoolInfo;
|
const ConstantPool = Class.ConstantPool;
|
||||||
const AttributeInfo = Class.AttributeInfo;
|
const AttributeInfo = Class.AttributeInfo;
|
||||||
const ResolveError = Class.ResolveError;
|
const ResolveError = Class.ResolveError;
|
||||||
|
|
||||||
|
|
@ -29,7 +29,7 @@ pub const MethodAccessFlags = EnumFlags(enum(u16) {
|
||||||
synthetic = 0x1000,
|
synthetic = 0x1000,
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPoolInfo, allocator: std.mem.Allocator) !Self {
|
pub fn parse(input: *std.Io.Reader, constant_pool: []const ?ConstantPool.Info, allocator: std.mem.Allocator) !Self {
|
||||||
const access_flags: MethodAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
|
const access_flags: MethodAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
|
||||||
const name_index = try input.takeInt(u16, .big);
|
const name_index = try input.takeInt(u16, .big);
|
||||||
const descriptor_index = try input.takeInt(u16, .big);
|
const descriptor_index = try input.takeInt(u16, .big);
|
||||||
|
|
@ -54,7 +54,7 @@ pub fn indentedFormat(
|
||||||
w: *std.Io.Writer,
|
w: *std.Io.Writer,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
indent: u8,
|
indent: u8,
|
||||||
constant_pool: []const ?ConstantPoolInfo,
|
constant_pool: []const ?ConstantPool.Info,
|
||||||
) std.Io.Writer.Error!void {
|
) std.Io.Writer.Error!void {
|
||||||
try w.splatByteAll(' ', depth * indent);
|
try w.splatByteAll(' ', depth * indent);
|
||||||
try w.print("flags: {f}\n", .{ self.access_flags });
|
try w.print("flags: {f}\n", .{ self.access_flags });
|
||||||
|
|
@ -83,19 +83,19 @@ pub fn indentedFormat(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(self: *const Self, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn name(self: *const Self, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const name_index = self.name_index - 1;
|
const name_index = self.name_index - 1;
|
||||||
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (name_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[name_index];
|
const cp_info = constant_pool[name_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn descriptor(self: *const Self, constant_pool: []const ?ConstantPoolInfo) ResolveError!ConstantPoolInfo {
|
pub fn descriptor(self: *const Self, constant_pool: []const ?ConstantPool.Info) ResolveError!ConstantPool.Info {
|
||||||
const descriptor_index = self.descriptor_index - 1;
|
const descriptor_index = self.descriptor_index - 1;
|
||||||
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
if (descriptor_index >= constant_pool.len) return ResolveError.InvalidConstantPoolIndex;
|
||||||
const cp_info = constant_pool[descriptor_index];
|
const cp_info = constant_pool[descriptor_index];
|
||||||
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
if (cp_info == null or @as(ConstantPool.Info.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
|
||||||
return cp_info.?;
|
return cp_info.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue