41 lines
1.5 KiB
Zig
41 lines
1.5 KiB
Zig
const Class = @import("../../Class.zig");
|
|
const ConstantPoolInfo = Class.ConstantPoolInfo;
|
|
const ResolveError = Class.ResolveError;
|
|
|
|
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 ?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(ConstantPoolInfo.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(ConstantPoolInfo.Tag, cp_info.?) != .method_ref) break :blk ResolveError.InvalidConstantType;
|
|
break :blk cp_info.?;
|
|
},
|
|
.invoke_interface => blk: {
|
|
if (cp_info == null or @as(ConstantPoolInfo.Tag, cp_info.?) != .interface_method_ref) break :blk ResolveError.InvalidConstantType;
|
|
break :blk cp_info.?;
|
|
},
|
|
};
|
|
}
|
|
|