asm...
This commit is contained in:
@@ -21,10 +21,11 @@ pub const TypeId = enum(u32) {
|
||||
string = 12, // [:0]u8
|
||||
any = 13,
|
||||
noreturn = 14,
|
||||
_reserved = 15,
|
||||
_, // user-defined types start at 16
|
||||
isize = 15,
|
||||
usize = 16,
|
||||
_, // user-defined types start at 17
|
||||
|
||||
pub const first_user: u32 = 16;
|
||||
pub const first_user: u32 = 17;
|
||||
|
||||
pub fn index(self: TypeId) u32 {
|
||||
return @intFromEnum(self);
|
||||
@@ -69,6 +70,8 @@ pub const TypeInfo = union(enum) {
|
||||
any,
|
||||
protocol: ProtocolInfo,
|
||||
noreturn,
|
||||
usize,
|
||||
isize,
|
||||
|
||||
pub const StructInfo = struct {
|
||||
name: StringId,
|
||||
@@ -225,6 +228,8 @@ pub const TypeTable = struct {
|
||||
/// Maps TypeInfo → TypeId for dedup of structural types
|
||||
intern_map: std.HashMap(TypeKey, TypeId, TypeKeyContext, 80),
|
||||
alloc: Allocator,
|
||||
/// Target pointer size in bytes (4 for wasm32, 8 for 64-bit targets).
|
||||
pointer_size: u8 = 8,
|
||||
|
||||
pub fn init(alloc: Allocator) TypeTable {
|
||||
var table = TypeTable{
|
||||
@@ -251,7 +256,8 @@ pub const TypeTable = struct {
|
||||
.string, // 12
|
||||
.any, // 13
|
||||
.noreturn, // 14
|
||||
.void, // 15: reserved (placeholder)
|
||||
.isize, // 15: isize (pointer-sized signed)
|
||||
.usize, // 16: usize (pointer-sized unsigned)
|
||||
};
|
||||
for (&builtins) |info| {
|
||||
table.infos.append(alloc, info) catch unreachable;
|
||||
@@ -402,25 +408,27 @@ pub const TypeTable = struct {
|
||||
/// This is the authoritative size computation used for closure env sizing and
|
||||
/// verified against LLVMABISizeOfType.
|
||||
pub fn typeSizeBytes(self: *const TypeTable, ty: TypeId) usize {
|
||||
const ptr_size: usize = self.pointer_size;
|
||||
if (ty == .void) return 0;
|
||||
if (ty == .bool) return 1;
|
||||
if (ty == .u8 or ty == .s8) return 1;
|
||||
if (ty == .u16 or ty == .s16) return 2;
|
||||
if (ty == .s32 or ty == .u32 or ty == .f32) return 4;
|
||||
if (ty == .s64 or ty == .u64 or ty == .f64) return 8;
|
||||
if (ty == .string) return 16; // {ptr, i64}
|
||||
if (ty.isBuiltin()) return 8; // default for unknown builtins
|
||||
if (ty == .usize or ty == .isize) return ptr_size;
|
||||
if (ty == .string) return 16; // {ptr, i64} — always 16 (i64 alignment pads on wasm32)
|
||||
if (ty.isBuiltin()) return ptr_size; // default for unknown builtins
|
||||
const info = self.get(ty);
|
||||
return switch (info) {
|
||||
.pointer, .many_pointer, .function => 8,
|
||||
.slice => 16, // {ptr, i64}
|
||||
.closure => 16, // {fn_ptr, env_ptr}
|
||||
.pointer, .many_pointer, .function => ptr_size,
|
||||
.slice => 16, // {ptr, i64} — same layout as string
|
||||
.closure => 2 * ptr_size, // {fn_ptr, env_ptr}
|
||||
.optional => |o| blk: {
|
||||
const child_info = self.get(o.child);
|
||||
if (child_info == .pointer or child_info == .many_pointer or child_info == .function)
|
||||
break :blk 8;
|
||||
break :blk ptr_size;
|
||||
if (child_info == .closure)
|
||||
break :blk 16; // {fn_ptr, env_ptr}
|
||||
break :blk 2 * ptr_size;
|
||||
const cs = self.typeSizeBytes(o.child);
|
||||
const ca = self.typeAlignBytes(o.child);
|
||||
// { T, i1 } — i1 goes right after T, then pad to struct alignment
|
||||
@@ -480,8 +488,8 @@ pub const TypeTable = struct {
|
||||
}
|
||||
break :blk if (offset == 0) 0 else (offset + max_a - 1) & ~(max_a - 1);
|
||||
},
|
||||
.any => 16,
|
||||
.protocol => 16,
|
||||
.any => 2 * ptr_size, // {type_tag, data_ptr}
|
||||
.protocol => 2 * ptr_size, // {ctx, vtable}
|
||||
.@"enum" => |e| {
|
||||
if (e.backing_type) |bt| return self.typeSizeBytes(bt);
|
||||
return 8;
|
||||
@@ -492,22 +500,25 @@ pub const TypeTable = struct {
|
||||
|
||||
/// Compute the ABI alignment in bytes for a type, matching LLVM's rules.
|
||||
pub fn typeAlignBytes(self: *const TypeTable, ty: TypeId) usize {
|
||||
const ptr_align: usize = self.pointer_size;
|
||||
if (ty == .void) return 1;
|
||||
if (ty == .bool) return 1;
|
||||
if (ty == .u8 or ty == .s8) return 1;
|
||||
if (ty == .u16 or ty == .s16) return 2;
|
||||
if (ty == .s32 or ty == .u32 or ty == .f32) return 4;
|
||||
if (ty == .s64 or ty == .u64 or ty == .f64) return 8;
|
||||
if (ty == .string) return 8;
|
||||
if (ty.isBuiltin()) return 8;
|
||||
if (ty == .usize or ty == .isize) return ptr_align;
|
||||
if (ty == .string) return 8; // i64 drives alignment
|
||||
if (ty.isBuiltin()) return ptr_align;
|
||||
const info = self.get(ty);
|
||||
return switch (info) {
|
||||
.pointer, .many_pointer, .function => 8,
|
||||
.slice, .closure => 8,
|
||||
.pointer, .many_pointer, .function => ptr_align,
|
||||
.slice => 8, // i64 drives alignment
|
||||
.closure => ptr_align, // {ptr, ptr}
|
||||
.optional => |o| blk: {
|
||||
const child_info = self.get(o.child);
|
||||
if (child_info == .pointer or child_info == .many_pointer or child_info == .function or child_info == .closure)
|
||||
break :blk 8;
|
||||
break :blk ptr_align;
|
||||
break :blk self.typeAlignBytes(o.child);
|
||||
},
|
||||
.@"struct" => |s| blk: {
|
||||
@@ -566,6 +577,8 @@ pub const TypeTable = struct {
|
||||
.string => "string",
|
||||
.any => "Any",
|
||||
.noreturn => "noreturn",
|
||||
.isize => "isize",
|
||||
.usize => "usize",
|
||||
else => {
|
||||
// User types — format from TypeInfo
|
||||
const info = self.get(id);
|
||||
@@ -609,7 +622,7 @@ fn hashTypeInfo(h: *std.hash.Wyhash, info: TypeInfo) void {
|
||||
switch (info) {
|
||||
.signed => |w| h.update(&.{w}),
|
||||
.unsigned => |w| h.update(&.{w}),
|
||||
.f32, .f64, .void, .bool, .string, .any, .noreturn => {},
|
||||
.f32, .f64, .void, .bool, .string, .any, .noreturn, .usize, .isize => {},
|
||||
.pointer => |p| h.update(std.mem.asBytes(&p.pointee)),
|
||||
.many_pointer => |p| h.update(std.mem.asBytes(&p.element)),
|
||||
.slice => |s| h.update(std.mem.asBytes(&s.element)),
|
||||
@@ -650,7 +663,7 @@ fn typeInfoEql(a: TypeInfo, b: TypeInfo) bool {
|
||||
return switch (a) {
|
||||
.signed => |w| w == b.signed,
|
||||
.unsigned => |w| w == b.unsigned,
|
||||
.f32, .f64, .void, .bool, .string, .any, .noreturn => true,
|
||||
.f32, .f64, .void, .bool, .string, .any, .noreturn, .usize, .isize => true,
|
||||
.pointer => |p| p.pointee == b.pointer.pointee,
|
||||
.many_pointer => |p| p.element == b.many_pointer.element,
|
||||
.slice => |s| s.element == b.slice.element,
|
||||
|
||||
Reference in New Issue
Block a user