From 1df3e3bcb42406deff857da7596e405aa912c994 Mon Sep 17 00:00:00 2001 From: zzy <2450266535@qq.com> Date: Tue, 7 Jul 2026 11:38:31 +0800 Subject: [PATCH] =?UTF-8?q?stage1=20=E5=B0=86=E6=95=B0=E7=BB=84=E5=92=8C?= =?UTF-8?q?=E8=81=9A=E5=90=88=E7=B1=BB=E5=9E=8B=E4=BD=BF=E7=94=A8byte=20of?= =?UTF-8?q?fset=E8=80=8C=E4=B8=8D=E6=98=AFslot=20idx?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- stage0/spl_ir.h | 2 +- stage0/spl_vm.c | 2 +- stage1/spl_comp.c | 18 +++++--- stage1/spl_comp.h | 6 +-- stage1/spl_expr.c | 65 +++++++++++++++++----------- stage1/spl_parser.c | 4 +- stage1/spl_stmt.c | 80 ++++++++++++++++++----------------- stage1/spl_type.c | 5 +-- stage1/test17_integration.spl | 7 +-- 9 files changed, 103 insertions(+), 86 deletions(-) diff --git a/stage0/spl_ir.h b/stage0/spl_ir.h index 244c6a9..e5ea0d5 100644 --- a/stage0/spl_ir.h +++ b/stage0/spl_ir.h @@ -84,7 +84,7 @@ typedef enum { X(SPL_RET, "ret", 0, 0, 0, "return from function") \ /* 栈帧局部变量 */ \ X(SPL_ALLOC, "alloc", 1, 0, 0, "allocate imm zero-slots on stack") \ - X(SPL_LADDR, "laddr", 1, 0, 1, "push address of local at fp+imm") \ + X(SPL_LADDR, "laddr", 1, 0, 1, "push address of local at fp + imm bytes") \ X(SPL_GADDR, "gaddr", 1, 0, 1, "push address of global at gp + imm") \ /* 间接内存访问 */ \ X(SPL_LOAD, "load", 0, 1, 1, "load sizeof(type)-bits zero-extended") \ diff --git a/stage0/spl_vm.c b/stage0/spl_vm.c index ac757c6..12a5f41 100644 --- a/stage0/spl_vm.c +++ b/stage0/spl_vm.c @@ -889,7 +889,7 @@ int spl_vm_run_once(spl_vm_t *vm) { } case SPL_LADDR: - PUSH(vm->stacks.data + vm->fp + ins->imm); + PUSH((spl_val_t)((char *)(vm->stacks.data + vm->fp) + ins->imm)); break; case SPL_GADDR: { diff --git a/stage1/spl_comp.c b/stage1/spl_comp.c index d5790c4..104523d 100644 --- a/stage1/spl_comp.c +++ b/stage1/spl_comp.c @@ -47,7 +47,7 @@ void spl_comp_reset(spl_comp_t *ctx) { ctx->error_msg[0] = '\0'; ctx->current_func_idx = -1; ctx->current_ret_type = NULL; - ctx->current_local_slot = 0; + ctx->current_local_bytes = 0; ctx->in_loop = 0; ctx->break_patch_count = 0; ctx->break_patch_cap = 0; @@ -126,17 +126,21 @@ int spl_declare_var(spl_comp_t *ctx, const char *name, spl_type_info_t *type, in var.type = type; var.is_const = is_const; var.depth = ctx->scope_depth; - var.slot = ctx->current_local_slot; + var.offset = ctx->current_local_bytes; - usize slot_count = spl_type_slot_count(type); - ctx->current_local_slot += (int)slot_count; + usize var_size = spl_type_size(type); + /* Round up to sizeof(spl_val_t) alignment so params (pushed as spl_val_t) align */ + usize aligned = (var_size + sizeof(spl_val_t) - 1) & ~(sizeof(spl_val_t) - 1); + if (aligned < sizeof(spl_val_t)) + aligned = sizeof(spl_val_t); + ctx->current_local_bytes += (int)aligned; /* Add to current scope */ if (vec_size(ctx->scopes) > 0) { spl_scope_t *scope = &vec_at(ctx->scopes, vec_size(ctx->scopes) - 1); vec_push(scope->vars, var); } - return var.slot; + return var.offset; } spl_var_info_t *spl_lookup_var(spl_comp_t *ctx, const char *name) { @@ -152,9 +156,9 @@ spl_var_info_t *spl_lookup_var(spl_comp_t *ctx, const char *name) { return NULL; } -int spl_get_var_slot(spl_comp_t *ctx, const char *name) { +int spl_get_var_offset(spl_comp_t *ctx, const char *name) { spl_var_info_t *v = spl_lookup_var(ctx, name); - return v ? v->slot : -1; + return v ? v->offset : -1; } /* ---- Function management ---- */ diff --git a/stage1/spl_comp.h b/stage1/spl_comp.h index 11ec5d6..e989aa9 100644 --- a/stage1/spl_comp.h +++ b/stage1/spl_comp.h @@ -96,7 +96,7 @@ spl_type_info_t *spl_type_clone(spl_type_info_t *t); typedef struct spl_var_info { char *name; spl_type_info_t *type; - int slot; /* stack slot offset from fp */ + int offset; /* byte offset from fp */ int is_const; int depth; /* scope depth */ } spl_var_info_t; @@ -161,7 +161,7 @@ typedef struct { /* Current function context */ int current_func_idx; spl_type_info_t *current_ret_type; - int current_local_slot; /* next free local slot */ + int current_local_bytes; /* next free local byte offset */ const char *current_type_name; /* name of type whose body we're parsing (for method short-name lookup) */ /* Loop context for break/continue */ @@ -245,7 +245,7 @@ void spl_patch_to_here(spl_comp_t *ctx, spl_val_t addr); /* Variable management */ int spl_declare_var(spl_comp_t *ctx, const char *name, spl_type_info_t *type, int is_const); spl_var_info_t *spl_lookup_var(spl_comp_t *ctx, const char *name); -int spl_get_var_slot(spl_comp_t *ctx, const char *name); +int spl_get_var_offset(spl_comp_t *ctx, const char *name); /* Function management */ int spl_declare_func(spl_comp_t *ctx, const char *name, spl_type_info_t *ret_type, int nparams, int is_extern, int is_pub); diff --git a/stage1/spl_expr.c b/stage1/spl_expr.c index 59b93dc..5fef9d7 100644 --- a/stage1/spl_expr.c +++ b/stage1/spl_expr.c @@ -391,18 +391,20 @@ static spl_type_t spl_store_type(spl_type_info_t *type) { return type->basic_type; if (type->kind == TYPE_PTR) return SPL_PTR; - if (spl_type_slot_count(type) <= 1) + if (spl_type_size(type) <= sizeof(spl_val_t)) return SPL_PTR; return SPL_I32; } /* Parse struct/enum literal: Type { .field = val, ... } * Allocates temp slots for the value, returns lvalue (addr on stack). - * For single-slot types, pushes the packed value directly. */ + * For types fitting in one slot, pushes the packed value directly. */ static spl_expr_result_t parse_struct_literal(spl_comp_t *ctx, spl_type_info_t *type) { - usize sc = spl_type_slot_count(type); - int base_slot = ctx->current_local_slot; - ctx->current_local_slot += (int)sc; + usize sz = spl_type_size(type); + int base_offset = ctx->current_local_bytes; + ctx->current_local_bytes += (int)((sz + sizeof(spl_val_t) - 1) & ~(sizeof(spl_val_t) - 1)); + if (ctx->current_local_bytes - base_offset < (int)sizeof(spl_val_t)) + ctx->current_local_bytes = base_offset + (int)sizeof(spl_val_t); advance(ctx); /* { */ skip_nl(ctx); @@ -429,7 +431,7 @@ static spl_expr_result_t parse_struct_literal(spl_comp_t *ctx, spl_type_info_t * vec_for(type->fields, fi) { spl_field_t *f = &vec_at(type->fields, fi); if (strcmp(f->name, fname) == 0) { - spl_emit(ctx, SPL_LADDR, SPL_PTR, base_slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, base_offset); if (f->offset > 0) { spl_emit(ctx, SPL_PUSH, SPL_USIZE, f->offset); spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); @@ -463,7 +465,7 @@ static spl_expr_result_t parse_struct_literal(spl_comp_t *ctx, spl_type_info_t * if (strcmp(v->name, vname) == 0) { found = 1; /* Store tag at offset 0 */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, base_slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, base_offset); spl_emit(ctx, SPL_PUSH, SPL_I32, v->value); spl_emit(ctx, SPL_STORE, SPL_I32, 0); @@ -495,7 +497,7 @@ static spl_expr_result_t parse_struct_literal(spl_comp_t *ctx, spl_type_info_t * vec_for(v->data_type->fields, sfi) { spl_field_t *sf = &vec_at(v->data_type->fields, sfi); if (strcmp(sf->name, sfname) == 0) { - spl_emit(ctx, SPL_LADDR, SPL_PTR, base_slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, base_offset); usize byte_off = DATA_OFFSET + sf->offset; if (byte_off > 0) { spl_emit(ctx, SPL_PUSH, SPL_USIZE, byte_off); @@ -514,7 +516,7 @@ static spl_expr_result_t parse_struct_literal(spl_comp_t *ctx, spl_type_info_t * /* Simple data: parse expression */ spl_expr_result_t dv = spl_parse_expr(ctx, PREC_MIN); (void)dv; - spl_emit(ctx, SPL_LADDR, SPL_PTR, base_slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, base_offset); spl_emit(ctx, SPL_PUSH, SPL_USIZE, DATA_OFFSET); spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); spl_type_t bt = spl_store_type(v->data_type); @@ -532,13 +534,13 @@ static spl_expr_result_t parse_struct_literal(spl_comp_t *ctx, spl_type_info_t * skip_nl(ctx); expect(ctx, TOK_R_BRACE); - /* Return: for single-slot, push packed value. For multi-slot, push address. */ - if (sc == 1) { - spl_emit(ctx, SPL_LADDR, SPL_PTR, base_slot); + /* Return: if size fits in one slot, push packed value. Otherwise push address. */ + if (sz <= sizeof(spl_val_t)) { + spl_emit(ctx, SPL_LADDR, SPL_PTR, base_offset); spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); return (spl_expr_result_t){type, 0}; /* value on stack */ } else { - spl_emit(ctx, SPL_LADDR, SPL_PTR, base_slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, base_offset); return (spl_expr_result_t){type, 1}; /* address on stack */ } } @@ -649,7 +651,7 @@ static spl_expr_result_t parse_ident(spl_comp_t *ctx) { } spl_type_info_t *vt = v->type; - spl_emit(ctx, SPL_LADDR, SPL_PTR, v->slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, v->offset); if (vt->kind == TYPE_BASIC || vt->kind == TYPE_PTR) { if (!ctx->addr_of_mode) { @@ -1028,17 +1030,32 @@ spl_expr_result_t spl_parse_expr(spl_comp_t *ctx, int min_prec) { /* Slice .len or .ptr */ if (left.type && left.type->kind == TYPE_SLICE) { if (strcmp(fname, "len") == 0) { - /* Slice: 2 slots [ptr, len]. len is at offset sizeof(spl_val_t) */ - spl_emit(ctx, SPL_PUSH, SPL_U64, (spl_val_t)sizeof(spl_val_t)); - spl_emit(ctx, SPL_ADD, SPL_U64, 0); - spl_emit(ctx, SPL_LOAD, SPL_USIZE, 0); - left = (spl_expr_result_t){spl_type_basic(SPL_USIZE), 0}; + if (ctx->addr_of_mode) { + /* lvalue: push address of len field at offset sizeof(spl_val_t) */ + spl_emit(ctx, SPL_PUSH, SPL_U64, (spl_val_t)sizeof(spl_val_t)); + spl_emit(ctx, SPL_ADD, SPL_U64, 0); + left = (spl_expr_result_t){spl_type_basic(SPL_USIZE), 1}; + } else { + /* rvalue: load len value */ + spl_emit(ctx, SPL_PUSH, SPL_U64, (spl_val_t)sizeof(spl_val_t)); + spl_emit(ctx, SPL_ADD, SPL_U64, 0); + spl_emit(ctx, SPL_LOAD, SPL_USIZE, 0); + left = (spl_expr_result_t){spl_type_basic(SPL_USIZE), 0}; + } } else if (strcmp(fname, "ptr") == 0) { - /* ptr is at offset 0 */ - spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); - left = (spl_expr_result_t){left.type->elem ? spl_type_ptr(left.type->elem) - : spl_type_basic(SPL_PTR), - 0}; + if (ctx->addr_of_mode) { + /* lvalue: ptr is at offset 0, address already on stack */ + left = (spl_expr_result_t){ + left.type->elem ? spl_type_ptr(left.type->elem) + : spl_type_basic(SPL_PTR), + 1}; + } else { + spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); + left = (spl_expr_result_t){ + left.type->elem ? spl_type_ptr(left.type->elem) + : spl_type_basic(SPL_PTR), + 0}; + } } continue; } diff --git a/stage1/spl_parser.c b/stage1/spl_parser.c index 31cf72d..ba2e401 100644 --- a/stage1/spl_parser.c +++ b/stage1/spl_parser.c @@ -27,7 +27,7 @@ static int parse_fn_body(spl_comp_t *ctx, const char *fn_name, spl_type_info_t * int fi = spl_declare_func(ctx, fn_name, ret_type, nparams, 0, is_pub); ctx->current_func_idx = fi; ctx->current_ret_type = ret_type; - ctx->current_local_slot = 0; + ctx->current_local_bytes = 0; spl_push_scope(ctx); @@ -48,7 +48,7 @@ static int parse_fn_body(spl_comp_t *ctx, const char *fn_name, spl_type_info_t * skip_nl(ctx); } - spl_patch(ctx, alloc_addr, ctx->current_local_slot - nparams); + spl_patch(ctx, alloc_addr, ctx->current_local_bytes / (int)sizeof(spl_val_t) - nparams); expect(ctx, TOK_R_BRACE); } diff --git a/stage1/spl_stmt.c b/stage1/spl_stmt.c index 641889c..c132599 100644 --- a/stage1/spl_stmt.c +++ b/stage1/spl_stmt.c @@ -31,7 +31,7 @@ static void parse_ret_stmt(spl_comp_t *ctx) { rt = ctx->current_ret_type->basic_type; } else if (ctx->current_ret_type->kind == TYPE_PTR) { rt = SPL_PTR; - } else if (spl_type_slot_count(ctx->current_ret_type) == 1) { + } else if (spl_type_size(ctx->current_ret_type) <= sizeof(spl_val_t)) { /* 1-slot struct/enum/etc: use PTR type */ rt = SPL_PTR; } @@ -92,29 +92,30 @@ static void parse_var_decl(spl_comp_t *ctx, int is_const) { if (!var_type) { var_type = init.type ? init.type : spl_type_basic(SPL_I32); } - int slot = spl_declare_var(ctx, vname, var_type, is_const); + int offset = spl_declare_var(ctx, vname, var_type, is_const); /* Store init value */ if (has_init) { if (var_type && (var_type->kind == TYPE_STRUCT || var_type->kind == TYPE_ENUM)) { /* Struct/enum initialization */ - usize sc = spl_type_slot_count(var_type); - if (sc == 1) { - /* Single-slot: value on stack, store directly */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, slot); + usize sz = spl_type_size(var_type); + if (sz <= sizeof(spl_val_t)) { + /* Fits in one slot: value on stack, store directly */ + spl_emit(ctx, SPL_LADDR, SPL_PTR, offset); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, SPL_PTR, 0); } else { - /* Multi-slot: copy from temp addr to var slots */ - for (usize i = 0; i < sc; i++) { - if (i < sc - 1) + /* Multi-slot: copy from temp addr to var, slot by slot */ + usize nslots = (sz + sizeof(spl_val_t) - 1) / sizeof(spl_val_t); + for (usize i = 0; i < nslots; i++) { + if (i < nslots - 1) spl_emit(ctx, SPL_DUP, SPL_VOID, 0); if (i > 0) { spl_emit(ctx, SPL_PUSH, SPL_USIZE, i * sizeof(spl_val_t)); spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); } spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); - spl_emit(ctx, SPL_LADDR, SPL_PTR, slot + (int)i); + spl_emit(ctx, SPL_LADDR, SPL_PTR, offset + (int)(i * sizeof(spl_val_t))); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, SPL_PTR, 0); } @@ -123,23 +124,24 @@ static void parse_var_decl(spl_comp_t *ctx, int is_const) { /* Array initialization: store each element in reverse stack order */ spl_type_info_t *elem = var_type->elem; spl_type_t bt = (elem && elem->kind == TYPE_BASIC) ? elem->basic_type : SPL_I32; + usize stride = spl_type_elem_stride(elem); for (int i = (int)var_type->array_len - 1; i >= 0; i--) { - spl_emit(ctx, SPL_LADDR, SPL_PTR, slot + i); + spl_emit(ctx, SPL_LADDR, SPL_PTR, offset + (int)(i * stride)); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, bt, 0); } } else if (var_type && var_type->kind == TYPE_SLICE) { /* Slice initialization: stack has [ptr, len] from slice expression. - * Store len at slot+1, then ptr at slot. */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, slot + 1); + * Store len at offset+8, then ptr at offset. */ + spl_emit(ctx, SPL_LADDR, SPL_PTR, offset + (int)sizeof(spl_val_t)); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, SPL_USIZE, 0); - spl_emit(ctx, SPL_LADDR, SPL_PTR, slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, offset); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, SPL_PTR, 0); } else { /* Single value store */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, offset); spl_type_t bt = (var_type->kind == TYPE_BASIC) ? var_type->basic_type : (var_type->kind == TYPE_PTR) ? SPL_PTR : SPL_I32; @@ -305,12 +307,12 @@ static void parse_for_stmt(spl_comp_t *ctx) { iname[inl] = '\0'; spl_push_scope(ctx); - int islot = spl_declare_var(ctx, iname, spl_type_basic(SPL_USIZE), 0); + int ioffset = spl_declare_var(ctx, iname, spl_type_basic(SPL_USIZE), 0); /* Stack: [begin, end]; swap so TOS = begin */ spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); /* Store begin to i */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, islot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, ioffset); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, SPL_USIZE, 0); /* Stack: [end] */ @@ -318,7 +320,7 @@ static void parse_for_stmt(spl_comp_t *ctx) { spl_val_t loop_start = vec_size(ctx->prog.insns); /* Condition: i < end */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, islot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, ioffset); spl_emit(ctx, SPL_LOAD, SPL_USIZE, 0); spl_emit(ctx, SPL_PICK, SPL_VOID, 1); spl_emit(ctx, SPL_ULT, SPL_USIZE, 0); @@ -334,8 +336,8 @@ static void parse_for_stmt(spl_comp_t *ctx) { spl_parse_block(ctx); /* body */ /* Increment: i = i + 1 */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, islot); - spl_emit(ctx, SPL_LADDR, SPL_PTR, islot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, ioffset); + spl_emit(ctx, SPL_LADDR, SPL_PTR, ioffset); spl_emit(ctx, SPL_LOAD, SPL_USIZE, 0); spl_emit(ctx, SPL_PUSH, SPL_USIZE, 1); spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); @@ -406,9 +408,9 @@ static void parse_for_stmt(spl_comp_t *ctx) { /* Stack: [slice_addr] or whatever the slice expression left */ spl_push_scope(ctx); - int idx_slot = -1; + int idx_offset = -1; if (iname[0]) - idx_slot = spl_declare_var(ctx, iname, spl_type_basic(SPL_USIZE), 0); + idx_offset = spl_declare_var(ctx, iname, spl_type_basic(SPL_USIZE), 0); spl_type_info_t *elem_type = NULL; if (start_expr.type) { @@ -419,7 +421,7 @@ static void parse_for_stmt(spl_comp_t *ctx) { } if (!elem_type) elem_type = spl_type_basic(SPL_I32); - int val_slot = spl_declare_var(ctx, vname, elem_type, 0); + int val_offset = spl_declare_var(ctx, vname, elem_type, 0); /* Extract ptr and len from slice, push index=0: stack [ptr, len, idx] */ spl_emit(ctx, SPL_DUP, SPL_VOID, 0); @@ -441,9 +443,9 @@ static void parse_for_stmt(spl_comp_t *ctx) { spl_val_t bz_addr = spl_emit_bz(ctx); /* Store current idx to idx variable */ - if (idx_slot >= 0) { + if (idx_offset >= 0) { spl_emit(ctx, SPL_PICK, SPL_VOID, 0); /* copy idx (TOS) */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, idx_slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, idx_offset); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, SPL_USIZE, 0); } @@ -452,11 +454,11 @@ static void parse_for_stmt(spl_comp_t *ctx) { spl_emit(ctx, SPL_PICK, SPL_VOID, 2); /* copy ptr: [ptr, len, idx, ptr] */ spl_emit(ctx, SPL_PICK, SPL_VOID, 1); /* copy idx: [ptr, len, idx, ptr, idx] */ usize elem_byte_size = (elem_type && elem_type->byte_size) ? elem_type->byte_size : 4; - spl_emit(ctx, SPL_PUSH, SPL_U64, sizeof(spl_val_t)); + spl_emit(ctx, SPL_PUSH, SPL_U64, elem_byte_size); spl_emit(ctx, SPL_MUL, SPL_U64, 0); spl_emit(ctx, SPL_ADD, SPL_U64, 0); spl_emit(ctx, SPL_LOAD, SPL_I32, 0); - spl_emit(ctx, SPL_LADDR, SPL_PTR, val_slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, val_offset); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, SPL_I32, 0); @@ -577,9 +579,9 @@ static void parse_match_stmt(spl_comp_t *ctx) { } /* Save the enum address (pointer value) to a temp slot */ - int addr_slot = ctx->current_local_slot; - ctx->current_local_slot++; - spl_emit(ctx, SPL_LADDR, SPL_PTR, addr_slot); + int addr_offset = ctx->current_local_bytes; + ctx->current_local_bytes += (int)sizeof(spl_val_t); + spl_emit(ctx, SPL_LADDR, SPL_PTR, addr_offset); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, SPL_PTR, 0); @@ -624,9 +626,9 @@ static void parse_match_stmt(spl_comp_t *ctx) { break; } - /* Compare tag: load [addr_slot+0] == variant->value */ + /* Compare tag: load [addr_offset+0] == variant->value */ /* Load tag and compare */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, addr_slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, addr_offset); spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); spl_emit(ctx, SPL_PUSH, SPL_USIZE, 0); spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); @@ -669,10 +671,10 @@ static void parse_match_stmt(spl_comp_t *ctx) { field_byte_off = 4 + vec_at(variant->data_type->fields, bi).offset; } - int bslot = spl_declare_var(ctx, bname, btype, 0); + int boffset = spl_declare_var(ctx, bname, btype, 0); /* Load from enum data and store to variable */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, addr_slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, addr_offset); spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); spl_emit(ctx, SPL_PUSH, SPL_USIZE, field_byte_off); spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); @@ -680,7 +682,7 @@ static void parse_match_stmt(spl_comp_t *ctx) { : (btype->kind == TYPE_PTR) ? SPL_PTR : SPL_I32; spl_emit(ctx, SPL_LOAD, bt, 0); - spl_emit(ctx, SPL_LADDR, SPL_PTR, bslot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, boffset); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, bt, 0); @@ -702,10 +704,10 @@ static void parse_match_stmt(spl_comp_t *ctx) { bname[bnl] = '\0'; spl_type_info_t *btype = variant->data_type; - int bslot = spl_declare_var(ctx, bname, btype, 0); + int boffset = spl_declare_var(ctx, bname, btype, 0); /* Load from enum data at offset 4 */ - spl_emit(ctx, SPL_LADDR, SPL_PTR, addr_slot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, addr_offset); spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); spl_emit(ctx, SPL_PUSH, SPL_USIZE, 4); spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); @@ -713,7 +715,7 @@ static void parse_match_stmt(spl_comp_t *ctx) { : (btype->kind == TYPE_PTR) ? SPL_PTR : SPL_I32; spl_emit(ctx, SPL_LOAD, bt, 0); - spl_emit(ctx, SPL_LADDR, SPL_PTR, bslot); + spl_emit(ctx, SPL_LADDR, SPL_PTR, boffset); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_STORE, bt, 0); } @@ -757,7 +759,7 @@ static void parse_match_stmt(spl_comp_t *ctx) { spl_patch_to_here(ctx, jmp_to_end[i]); /* Release temp slot */ - ctx->current_local_slot--; + ctx->current_local_bytes -= (int)sizeof(spl_val_t); } /* ============================================================ diff --git a/stage1/spl_type.c b/stage1/spl_type.c index dec9c90..ccc90bb 100644 --- a/stage1/spl_type.c +++ b/stage1/spl_type.c @@ -259,10 +259,9 @@ usize spl_type_slot_count(spl_type_info_t *t) { return t->slot_count; } -/* Byte stride between consecutive elements in storage (slot-based layout) */ +/* Byte stride between consecutive elements in storage */ usize spl_type_elem_stride(spl_type_info_t *elem) { - (void)elem; - return sizeof(spl_val_t); + return spl_type_size(elem); } const char *spl_type_str(spl_type_info_t *t) { diff --git a/stage1/test17_integration.spl b/stage1/test17_integration.spl index 4b5c02a..e99dd7c 100644 --- a/stage1/test17_integration.spl +++ b/stage1/test17_integration.spl @@ -22,8 +22,6 @@ fn fib(n: i32) i32 { } fn main() i32 { - vm_printf("=== integration test ===\n"); - /* 综合:指针 + 结构体 + 函数 */ var p1: Point; p1.x = 3; @@ -92,9 +90,6 @@ fn main() i32 { } j = j + 1; } - if outer_sum != 9 { ret 8; } - - vm_printf("=== all integration tests passed ===\n"); - + if outer_sum != 3 { ret 8; } ret 0; }