From bd7181ae1fc5cbf020c9d44ba587f6934c0f914c Mon Sep 17 00:00:00 2001 From: Hojun-Cho Date: Tue, 26 May 2026 01:26:03 +0900 Subject: [PATCH] wcc: add the size primitive type (TY_SIZE), classify as unsigned int (#85) fold-1: type exists + classifies; mirrors TY_UINTPTR at every site, both stages. size(T)/len() return types UNCHANGED (fold-2). Regenerates the 5 combined.ww (lib/ww embedded). --- cmd/w6c/cgen.c | 2 +- cmd/wcc/type.c | 8 +++++--- cmd/wcc/ww.h | 7 +++++-- lib/ww/typ.ww | 5 +++++ selfhost/cmd/w6c/main.combined.ww | 12 +++++++++--- selfhost/cmd/wcc/check.ww | 7 ++++--- selfhost/cmd/wwdump/main.combined.ww | 12 +++++++++--- 7 files changed, 38 insertions(+), 15 deletions(-) diff --git a/cmd/w6c/cgen.c b/cmd/w6c/cgen.c index 5c550307..903ab0d8 100644 --- a/cmd/w6c/cgen.c +++ b/cmd/w6c/cgen.c @@ -711,7 +711,7 @@ let_emit_size(Type *t) case TY_BOOL: case TY_RUNE: case TY_I8: case TY_I16: case TY_I32: case TY_I64: case TY_U8: case TY_U16: case TY_U32: case TY_U64: - case TY_INT: case TY_UINT: case TY_UINTPTR: + case TY_INT: case TY_UINT: case TY_UINTPTR: case TY_SIZE: case TY_PTR: return 8; case TY_F32: diff --git a/cmd/wcc/type.c b/cmd/wcc/type.c index 671118d4..269c6ba3 100644 --- a/cmd/wcc/type.c +++ b/cmd/wcc/type.c @@ -12,7 +12,7 @@ Type *ty_void, *ty_bool, *ty_rune; Type *ty_i8, *ty_i16, *ty_i32, *ty_i64; Type *ty_u8, *ty_u16, *ty_u32, *ty_u64; -Type *ty_int, *ty_uint, *ty_uintptr; +Type *ty_int, *ty_uint, *ty_uintptr, *ty_size; Type *ty_f32, *ty_f64, *ty_str; Type *ty_err; Type *ty_never; @@ -58,6 +58,7 @@ typesinit(Arena *a) ty_int = prim(a, TY_INT, "int", 8, 8); /* amd64 */ ty_uint = prim(a, TY_UINT, "uint", 8, 8); ty_uintptr= prim(a, TY_UINTPTR,"uintptr", 8, 8); + ty_size = prim(a, TY_SIZE, "size", 8, 8); /* #85: mirrors uintptr */ ty_f32 = prim(a, TY_F32, "f32", 4, 4); ty_f64 = prim(a, TY_F64, "f64", 8, 8); /* str IS []u8: { *u8, len, cap } — 24 bytes, 3-reg ABI (#1/Phase 3). @@ -148,7 +149,7 @@ type_isint(Type *t) switch (t->kind) { case TY_I8: case TY_I16: case TY_I32: case TY_I64: case TY_U8: case TY_U16: case TY_U32: case TY_U64: - case TY_INT: case TY_UINT: case TY_UINTPTR: + case TY_INT: case TY_UINT: case TY_UINTPTR: case TY_SIZE: case TY_RUNE: case TY_UNTYPED_INT: case TY_UNTYPED_RUNE: @@ -183,7 +184,7 @@ type_isunsigned(Type *t) if (t == NULL) return 0; switch (t->kind) { case TY_U8: case TY_U16: case TY_U32: case TY_U64: - case TY_UINT: case TY_UINTPTR: + case TY_UINT: case TY_UINTPTR: case TY_SIZE: case TY_RUNE: return 1; case TY_NAMED: return type_isunsigned(t->under); @@ -373,6 +374,7 @@ type_name(Arena *a, Type *t) case TY_INT: return "int"; case TY_UINT: return "uint"; case TY_UINTPTR: return "uintptr"; + case TY_SIZE: return "size"; case TY_F32: return "f32"; case TY_F64: return "f64"; case TY_STR: return "str"; diff --git a/cmd/wcc/ww.h b/cmd/wcc/ww.h index 41dee3e8..f3766f34 100644 --- a/cmd/wcc/ww.h +++ b/cmd/wcc/ww.h @@ -389,8 +389,11 @@ typedef enum { TY_UNTYPED_NIL, /* Appended at the tail to keep existing TY_* values stable — * lib/ww/typ.ww mirrors them as explicit `def` numbers. */ - TY_ENUM /* `enum [storage] { ... }`. sub=storage, + TY_ENUM, /* `enum [storage] { ... }`. sub=storage, * fields=member list (Tfield.offset = u64 value). */ + TY_SIZE /* platform-width unsigned int; mirrors TY_UINTPTR + * (8/8 on amd64). Hare: `size`, SIZE_MAX=U64_MAX + * (ref/hare/types/arch+x86_64.ha:17,20). #85 fold-1. */ } TypeKind; typedef struct Tfield Tfield; @@ -436,7 +439,7 @@ struct Type { extern Type *ty_void, *ty_bool, *ty_rune; extern Type *ty_i8, *ty_i16, *ty_i32, *ty_i64; extern Type *ty_u8, *ty_u16, *ty_u32, *ty_u64; -extern Type *ty_int, *ty_uint, *ty_uintptr; +extern Type *ty_int, *ty_uint, *ty_uintptr, *ty_size; extern Type *ty_f32, *ty_f64, *ty_str; extern Type *ty_err; extern Type *ty_never; diff --git a/lib/ww/typ.ww b/lib/ww/typ.ww index 60096c80..4e308afd 100644 --- a/lib/ww/typ.ww +++ b/lib/ww/typ.ww @@ -57,6 +57,7 @@ type tykind = enum i32 { // Tail-appended values keep prior TY_* stable for the byte-diff // against cmd/wcc/ww.h. TY_ENUM = 35, + TY_SIZE = 36, // #85 fold-1; mirrors TY_UINTPTR (8/8 amd64) }; // ---- tinfo / tfield / tparam ----------------------------------------- @@ -158,6 +159,7 @@ type tctx = struct { tyint: *tinfo, tyuint: *tinfo, tyuintptr: *tinfo, + tysize: *tinfo, tyf32: *tinfo, tyf64: *tinfo, tystr: *tinfo, @@ -203,6 +205,7 @@ export fn typesinit(c: *tctx) void = { c.tyint = prim(tykind.TY_INT, "int", 8u64, 8u64); c.tyuint = prim(tykind.TY_UINT, "uint", 8u64, 8u64); c.tyuintptr= prim(tykind.TY_UINTPTR, "uintptr", 8u64, 8u64); + c.tysize = prim(tykind.TY_SIZE, "size", 8u64, 8u64); // #85 c.tyf32 = prim(tykind.TY_F32, "f32", 4u64, 4u64); c.tyf64 = prim(tykind.TY_F64, "f64", 8u64, 8u64); // str IS []u8: { *u8, len, cap } — 24B, 3-reg ABI (#1/Phase 3). @@ -323,6 +326,7 @@ export fn typeisint(t: *tinfo) bool = { if (k == tykind.TY_INT) { return true; }; if (k == tykind.TY_UINT){ return true; }; if (k == tykind.TY_UINTPTR) { return true; }; + if (k == tykind.TY_SIZE) { return true; }; if (k == tykind.TY_RUNE){ return true; }; if (k == tykind.TY_UNTYPED_INT) { return true; }; if (k == tykind.TY_UNTYPED_RUNE) { return true; }; @@ -359,6 +363,7 @@ export fn typeisunsigned(t: *tinfo) bool = { if (k == tykind.TY_U64) { return true; }; if (k == tykind.TY_UINT){ return true; }; if (k == tykind.TY_UINTPTR) { return true; }; + if (k == tykind.TY_SIZE) { return true; }; if (k == tykind.TY_RUNE){ return true; }; if (k == tykind.TY_NAMED) { return typeisunsigned(t.under); }; if (k == tykind.TY_ENUM) { return typeisunsigned(t.sub); }; diff --git a/selfhost/cmd/w6c/main.combined.ww b/selfhost/cmd/w6c/main.combined.ww index f284840b..e4a3c687 100644 --- a/selfhost/cmd/w6c/main.combined.ww +++ b/selfhost/cmd/w6c/main.combined.ww @@ -6394,6 +6394,7 @@ type tykind = enum i32 { // Tail-appended values keep prior TY_* stable for the byte-diff // against cmd/wcc/ww.h. TY_ENUM = 35, + TY_SIZE = 36, // #85 fold-1; mirrors TY_UINTPTR (8/8 amd64) }; // ---- tinfo / tfield / tparam ----------------------------------------- @@ -6495,6 +6496,7 @@ type tctx = struct { tyint: *tinfo, tyuint: *tinfo, tyuintptr: *tinfo, + tysize: *tinfo, tyf32: *tinfo, tyf64: *tinfo, tystr: *tinfo, @@ -6540,6 +6542,7 @@ export fn typesinit(c: *tctx) void = { c.tyint = prim(tykind.TY_INT, "int", 8u64, 8u64); c.tyuint = prim(tykind.TY_UINT, "uint", 8u64, 8u64); c.tyuintptr= prim(tykind.TY_UINTPTR, "uintptr", 8u64, 8u64); + c.tysize = prim(tykind.TY_SIZE, "size", 8u64, 8u64); // #85 c.tyf32 = prim(tykind.TY_F32, "f32", 4u64, 4u64); c.tyf64 = prim(tykind.TY_F64, "f64", 8u64, 8u64); // str IS []u8: { *u8, len, cap } — 24B, 3-reg ABI (#1/Phase 3). @@ -6660,6 +6663,7 @@ export fn typeisint(t: *tinfo) bool = { if (k == tykind.TY_INT) { return true; }; if (k == tykind.TY_UINT){ return true; }; if (k == tykind.TY_UINTPTR) { return true; }; + if (k == tykind.TY_SIZE) { return true; }; if (k == tykind.TY_RUNE){ return true; }; if (k == tykind.TY_UNTYPED_INT) { return true; }; if (k == tykind.TY_UNTYPED_RUNE) { return true; }; @@ -6696,6 +6700,7 @@ export fn typeisunsigned(t: *tinfo) bool = { if (k == tykind.TY_U64) { return true; }; if (k == tykind.TY_UINT){ return true; }; if (k == tykind.TY_UINTPTR) { return true; }; + if (k == tykind.TY_SIZE) { return true; }; if (k == tykind.TY_RUNE){ return true; }; if (k == tykind.TY_NAMED) { return typeisunsigned(t.under); }; if (k == tykind.TY_ENUM) { return typeisunsigned(t.sub); }; @@ -8328,7 +8333,7 @@ fn tupleelemslot(pt: *tinfo) u64 = { pk == tykind.TY_CHAN || pk == tykind.TY_I64 || pk == tykind.TY_U64 || pk == tykind.TY_INT || pk == tykind.TY_UINT || pk == tykind.TY_UINTPTR || - pk == tykind.TY_F64) { return 8u64; }; + pk == tykind.TY_SIZE || pk == tykind.TY_F64) { return 8u64; }; if (pk == tykind.TY_BOOL || pk == tykind.TY_RUNE || pk == tykind.TY_I8 || pk == tykind.TY_I16 || pk == tykind.TY_I32 || pk == tykind.TY_U8 || @@ -8373,8 +8378,9 @@ fn fieldslotsize(ft: *tinfo) u64 = { fk == tykind.TY_U8 || fk == tykind.TY_U16 || fk == tykind.TY_U32 || fk == tykind.TY_U64 || fk == tykind.TY_INT || fk == tykind.TY_UINT || - fk == tykind.TY_UINTPTR || fk == tykind.TY_F32 || - fk == tykind.TY_F64 || fk == tykind.TY_ENUM) { return t.size; }; + fk == tykind.TY_UINTPTR || fk == tykind.TY_SIZE || + fk == tykind.TY_F32 || fk == tykind.TY_F64 || + fk == tykind.TY_ENUM) { return t.size; }; return 8u64; }; diff --git a/selfhost/cmd/wcc/check.ww b/selfhost/cmd/wcc/check.ww index f1edd42c..aa6e3e28 100644 --- a/selfhost/cmd/wcc/check.ww +++ b/selfhost/cmd/wcc/check.ww @@ -1210,7 +1210,7 @@ fn tupleelemslot(pt: *tinfo) u64 = { pk == tykind.TY_CHAN || pk == tykind.TY_I64 || pk == tykind.TY_U64 || pk == tykind.TY_INT || pk == tykind.TY_UINT || pk == tykind.TY_UINTPTR || - pk == tykind.TY_F64) { return 8u64; }; + pk == tykind.TY_SIZE || pk == tykind.TY_F64) { return 8u64; }; if (pk == tykind.TY_BOOL || pk == tykind.TY_RUNE || pk == tykind.TY_I8 || pk == tykind.TY_I16 || pk == tykind.TY_I32 || pk == tykind.TY_U8 || @@ -1255,8 +1255,9 @@ fn fieldslotsize(ft: *tinfo) u64 = { fk == tykind.TY_U8 || fk == tykind.TY_U16 || fk == tykind.TY_U32 || fk == tykind.TY_U64 || fk == tykind.TY_INT || fk == tykind.TY_UINT || - fk == tykind.TY_UINTPTR || fk == tykind.TY_F32 || - fk == tykind.TY_F64 || fk == tykind.TY_ENUM) { return t.size; }; + fk == tykind.TY_UINTPTR || fk == tykind.TY_SIZE || + fk == tykind.TY_F32 || fk == tykind.TY_F64 || + fk == tykind.TY_ENUM) { return t.size; }; return 8u64; }; diff --git a/selfhost/cmd/wwdump/main.combined.ww b/selfhost/cmd/wwdump/main.combined.ww index 034e78a0..75f2ac1e 100644 --- a/selfhost/cmd/wwdump/main.combined.ww +++ b/selfhost/cmd/wwdump/main.combined.ww @@ -6394,6 +6394,7 @@ type tykind = enum i32 { // Tail-appended values keep prior TY_* stable for the byte-diff // against cmd/wcc/ww.h. TY_ENUM = 35, + TY_SIZE = 36, // #85 fold-1; mirrors TY_UINTPTR (8/8 amd64) }; // ---- tinfo / tfield / tparam ----------------------------------------- @@ -6495,6 +6496,7 @@ type tctx = struct { tyint: *tinfo, tyuint: *tinfo, tyuintptr: *tinfo, + tysize: *tinfo, tyf32: *tinfo, tyf64: *tinfo, tystr: *tinfo, @@ -6540,6 +6542,7 @@ export fn typesinit(c: *tctx) void = { c.tyint = prim(tykind.TY_INT, "int", 8u64, 8u64); c.tyuint = prim(tykind.TY_UINT, "uint", 8u64, 8u64); c.tyuintptr= prim(tykind.TY_UINTPTR, "uintptr", 8u64, 8u64); + c.tysize = prim(tykind.TY_SIZE, "size", 8u64, 8u64); // #85 c.tyf32 = prim(tykind.TY_F32, "f32", 4u64, 4u64); c.tyf64 = prim(tykind.TY_F64, "f64", 8u64, 8u64); // str IS []u8: { *u8, len, cap } — 24B, 3-reg ABI (#1/Phase 3). @@ -6660,6 +6663,7 @@ export fn typeisint(t: *tinfo) bool = { if (k == tykind.TY_INT) { return true; }; if (k == tykind.TY_UINT){ return true; }; if (k == tykind.TY_UINTPTR) { return true; }; + if (k == tykind.TY_SIZE) { return true; }; if (k == tykind.TY_RUNE){ return true; }; if (k == tykind.TY_UNTYPED_INT) { return true; }; if (k == tykind.TY_UNTYPED_RUNE) { return true; }; @@ -6696,6 +6700,7 @@ export fn typeisunsigned(t: *tinfo) bool = { if (k == tykind.TY_U64) { return true; }; if (k == tykind.TY_UINT){ return true; }; if (k == tykind.TY_UINTPTR) { return true; }; + if (k == tykind.TY_SIZE) { return true; }; if (k == tykind.TY_RUNE){ return true; }; if (k == tykind.TY_NAMED) { return typeisunsigned(t.under); }; if (k == tykind.TY_ENUM) { return typeisunsigned(t.sub); }; @@ -8328,7 +8333,7 @@ fn tupleelemslot(pt: *tinfo) u64 = { pk == tykind.TY_CHAN || pk == tykind.TY_I64 || pk == tykind.TY_U64 || pk == tykind.TY_INT || pk == tykind.TY_UINT || pk == tykind.TY_UINTPTR || - pk == tykind.TY_F64) { return 8u64; }; + pk == tykind.TY_SIZE || pk == tykind.TY_F64) { return 8u64; }; if (pk == tykind.TY_BOOL || pk == tykind.TY_RUNE || pk == tykind.TY_I8 || pk == tykind.TY_I16 || pk == tykind.TY_I32 || pk == tykind.TY_U8 || @@ -8373,8 +8378,9 @@ fn fieldslotsize(ft: *tinfo) u64 = { fk == tykind.TY_U8 || fk == tykind.TY_U16 || fk == tykind.TY_U32 || fk == tykind.TY_U64 || fk == tykind.TY_INT || fk == tykind.TY_UINT || - fk == tykind.TY_UINTPTR || fk == tykind.TY_F32 || - fk == tykind.TY_F64 || fk == tykind.TY_ENUM) { return t.size; }; + fk == tykind.TY_UINTPTR || fk == tykind.TY_SIZE || + fk == tykind.TY_F32 || fk == tykind.TY_F64 || + fk == tykind.TY_ENUM) { return t.size; }; return 8u64; };