Modularize

This commit is contained in:
ktkk 2026-06-24 14:32:27 +00:00
parent c61d74c22c
commit eacf0381c9
13 changed files with 1492 additions and 1399 deletions

File diff suppressed because it is too large Load diff

1040
src/Class/AttributeInfo.zig Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,16 @@
const Class = @import("../../Class.zig");
const ConstantPoolInfo = Class.ConstantPoolInfo;
const ResolveError = Class.ResolveError;
name_index: u16,
const Self = @This();
pub fn name(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}

View file

@ -0,0 +1,25 @@
const Class = @import("../../Class.zig");
const ConstantPoolInfo = Class.ConstantPoolInfo;
const ResolveError = Class.ResolveError;
class_index: u16,
name_and_type_index: u16,
const Self = @This();
pub fn class(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
return cp_info.?;
}
pub fn nameAndType(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .name_and_type) return ResolveError.InvalidConstantType;
return cp_info.?;
}

View file

@ -0,0 +1,25 @@
const Class = @import("../../Class.zig");
const ConstantPoolInfo = Class.ConstantPoolInfo;
const ResolveError = Class.ResolveError;
class_index: u16,
name_and_type_index: u16,
const Self = @This();
pub fn class(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
return cp_info.?;
}
pub fn nameAndType(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .name_and_type) return ResolveError.InvalidConstantType;
return cp_info.?;
}

View file

@ -0,0 +1,16 @@
const Class = @import("../../Class.zig");
const ConstantPoolInfo = Class.ConstantPoolInfo;
const ResolveError = Class.ResolveError;
bootstrap_method_attr_index: u16,
name_and_type_index: u16,
const Self = @This();
pub fn nameAndType(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .name_and_type) return ResolveError.InvalidConstantType;
return cp_info.?;
}

View file

@ -0,0 +1,41 @@
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.?;
},
};
}

View file

@ -0,0 +1,25 @@
const Class = @import("../../Class.zig");
const ConstantPoolInfo = Class.ConstantPoolInfo;
const ResolveError = Class.ResolveError;
class_index: u16,
name_and_type_index: u16,
const Self = @This();
pub fn class(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .class) return ResolveError.InvalidConstantType;
return cp_info.?;
}
pub fn nameAndType(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .name_and_type) return ResolveError.InvalidConstantType;
return cp_info.?;
}

View file

@ -0,0 +1,16 @@
const Class = @import("../../Class.zig");
const ConstantPoolInfo = Class.ConstantPoolInfo;
const ResolveError = Class.ResolveError;
descriptor_index: u16,
const Self = @This();
pub fn descriptor(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}

View file

@ -0,0 +1,25 @@
const Class = @import("../../Class.zig");
const ConstantPoolInfo = Class.ConstantPoolInfo;
const ResolveError = Class.ResolveError;
name_index: u16,
descriptor_index: u16,
const Self = @This();
pub fn name(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}
pub fn descriptor(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}

View file

@ -0,0 +1,16 @@
const Class = @import("../../Class.zig");
const ConstantPoolInfo = Class.ConstantPoolInfo;
const ResolveError = Class.ResolveError;
string_index: u16,
const Self = @This();
pub fn string(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}

101
src/Class/FieldInfo.zig Normal file
View file

@ -0,0 +1,101 @@
const std = @import("std");
const EnumFlags = @import("../EnumFlags.zig").EnumFlags;
const Class = @import("../Class.zig");
const ConstantPoolInfo = Class.ConstantPoolInfo;
const AttributeInfo = Class.AttributeInfo;
const ResolveError = Class.ResolveError;
access_flags: FieldAccessFlags,
name_index: u16,
descriptor_index: u16,
attributes: []AttributeInfo,
const Self = @This();
pub const FieldFlags = enum(u16) {
public = 0x0001,
private = 0x0002,
protected = 0x0004,
static = 0x0008,
final = 0x0010,
@"volatile" = 0x0040,
transient = 0x0080,
synthetic = 0x1000,
@"enum" = 0x4000,
};
pub const FieldAccessFlags = EnumFlags(FieldFlags);
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) !Self {
const access_flags: FieldAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
const name_index = try input.takeInt(u16, .big);
const descriptor_index = try input.takeInt(u16, .big);
const attributes = try Class.parseAttributes(input, allocator);
return .{
.access_flags = access_flags,
.name_index = name_index,
.descriptor_index = descriptor_index,
.attributes = attributes,
};
}
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
for (self.attributes) |*attr_info| {
attr_info.deinit(allocator);
}
allocator.free(self.attributes);
}
pub fn format(
self: *const Self,
w: *std.Io.Writer,
depth: usize,
indent: u8,
allocator: std.mem.Allocator,
constant_pool: []const ?ConstantPoolInfo,
) std.Io.Writer.Error!void {
try w.splatByteAll(' ', depth * indent);
try w.print("flags: {f}\n", .{ self.access_flags });
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const field_name = self.name(constant_pool) catch return error.WriteFailed;
try field_name.format(w, depth, indent + 1, constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("descriptor:\n");
const field_descriptor = self.descriptor(constant_pool) catch return error.WriteFailed;
try field_descriptor.format(w, depth, indent + 1, constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("attributes:\n");
var attr_indent = indent;
for (self.attributes, 0..) |*attribute, j| {
attr_indent += 1;
defer attr_indent -= 1;
try w.splatByteAll(' ', depth * attr_indent);
try w.print("{d}:\n", .{ j });
try attribute.format(w, depth, attr_indent + 1, allocator, constant_pool);
}
}
pub fn name(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}
pub fn descriptor(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}

104
src/Class/MethodInfo.zig Normal file
View file

@ -0,0 +1,104 @@
const std = @import("std");
const EnumFlags = @import("../EnumFlags.zig").EnumFlags;
const Class = @import("../Class.zig");
const ConstantPoolInfo = Class.ConstantPoolInfo;
const AttributeInfo = Class.AttributeInfo;
const ResolveError = Class.ResolveError;
access_flags: MethodAccessFlags,
name_index: u16,
descriptor_index: u16,
attributes: []AttributeInfo,
const Self = @This();
pub const MethodFlags = enum(u16) {
public = 0x0001,
private = 0x0002,
protected = 0x0004,
static = 0x0008,
final = 0x0010,
synchronized = 0x0020,
bridge = 0x0040,
varargs = 0x0080,
native = 0x0100,
abstract = 0x0400,
strict = 0x0800,
synthetic = 0x1000,
};
pub const MethodAccessFlags = EnumFlags(MethodFlags);
pub fn parse(input: *std.Io.Reader, allocator: std.mem.Allocator) !Self {
const access_flags: MethodAccessFlags = .{ .mask = try input.takeInt(u16, .big) };
const name_index = try input.takeInt(u16, .big);
const descriptor_index = try input.takeInt(u16, .big);
const attributes = try Class.parseAttributes(input, allocator);
return .{
.access_flags = access_flags,
.name_index = name_index,
.descriptor_index = descriptor_index,
.attributes = attributes,
};
}
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
for (self.attributes) |*attr_info| {
attr_info.deinit(allocator);
}
allocator.free(self.attributes);
}
pub fn format(
self: *const Self,
w: *std.Io.Writer,
depth: usize,
indent: u8,
allocator: std.mem.Allocator,
constant_pool: []const ?ConstantPoolInfo,
) std.Io.Writer.Error!void {
try w.splatByteAll(' ', depth * indent);
try w.print("flags: {f}\n", .{ self.access_flags });
try w.splatByteAll(' ', depth * indent);
_ = try w.write("name:\n");
const method_name = self.name(constant_pool) catch return error.WriteFailed;
try method_name.format(w, depth, indent + 1, constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("descriptor:\n");
const method_descriptor = self.descriptor(constant_pool) catch return error.WriteFailed;
try method_descriptor.format(w, depth, indent + 1, constant_pool);
try w.splatByteAll(' ', depth * indent);
_ = try w.write("attributes:\n");
var attr_indent = indent;
for (self.attributes, 0..) |*attribute, j| {
attr_indent += 1;
defer attr_indent -= 1;
try w.splatByteAll(' ', depth * attr_indent);
try w.print("{d}:\n", .{ j });
try attribute.format(w, depth, attr_indent + 1, allocator, constant_pool);
}
}
pub fn name(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}
pub fn descriptor(self: *const Self, 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(ConstantPoolInfo.Tag, cp_info.?) != .utf8) return ResolveError.InvalidConstantType;
return cp_info.?;
}