stage1 将数组和聚合类型使用byte offset而不是slot idx

This commit is contained in:
zzy
2026-07-07 11:38:31 +08:00
parent 3cf11f922e
commit 1df3e3bcb4
9 changed files with 103 additions and 86 deletions

View File

@@ -84,7 +84,7 @@ typedef enum {
X(SPL_RET, "ret", 0, 0, 0, "return from function") \ 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_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_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") \ X(SPL_LOAD, "load", 0, 1, 1, "load sizeof(type)-bits zero-extended") \

View File

@@ -889,7 +889,7 @@ int spl_vm_run_once(spl_vm_t *vm) {
} }
case SPL_LADDR: case SPL_LADDR:
PUSH(vm->stacks.data + vm->fp + ins->imm); PUSH((spl_val_t)((char *)(vm->stacks.data + vm->fp) + ins->imm));
break; break;
case SPL_GADDR: { case SPL_GADDR: {

View File

@@ -47,7 +47,7 @@ void spl_comp_reset(spl_comp_t *ctx) {
ctx->error_msg[0] = '\0'; ctx->error_msg[0] = '\0';
ctx->current_func_idx = -1; ctx->current_func_idx = -1;
ctx->current_ret_type = NULL; ctx->current_ret_type = NULL;
ctx->current_local_slot = 0; ctx->current_local_bytes = 0;
ctx->in_loop = 0; ctx->in_loop = 0;
ctx->break_patch_count = 0; ctx->break_patch_count = 0;
ctx->break_patch_cap = 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.type = type;
var.is_const = is_const; var.is_const = is_const;
var.depth = ctx->scope_depth; 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); usize var_size = spl_type_size(type);
ctx->current_local_slot += (int)slot_count; /* 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 */ /* Add to current scope */
if (vec_size(ctx->scopes) > 0) { if (vec_size(ctx->scopes) > 0) {
spl_scope_t *scope = &vec_at(ctx->scopes, vec_size(ctx->scopes) - 1); spl_scope_t *scope = &vec_at(ctx->scopes, vec_size(ctx->scopes) - 1);
vec_push(scope->vars, var); 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) { 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; 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); spl_var_info_t *v = spl_lookup_var(ctx, name);
return v ? v->slot : -1; return v ? v->offset : -1;
} }
/* ---- Function management ---- */ /* ---- Function management ---- */

View File

@@ -96,7 +96,7 @@ spl_type_info_t *spl_type_clone(spl_type_info_t *t);
typedef struct spl_var_info { typedef struct spl_var_info {
char *name; char *name;
spl_type_info_t *type; spl_type_info_t *type;
int slot; /* stack slot offset from fp */ int offset; /* byte offset from fp */
int is_const; int is_const;
int depth; /* scope depth */ int depth; /* scope depth */
} spl_var_info_t; } spl_var_info_t;
@@ -161,7 +161,7 @@ typedef struct {
/* Current function context */ /* Current function context */
int current_func_idx; int current_func_idx;
spl_type_info_t *current_ret_type; 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) */ const char *current_type_name; /* name of type whose body we're parsing (for method short-name lookup) */
/* Loop context for break/continue */ /* Loop context for break/continue */
@@ -245,7 +245,7 @@ void spl_patch_to_here(spl_comp_t *ctx, spl_val_t addr);
/* Variable management */ /* Variable management */
int spl_declare_var(spl_comp_t *ctx, const char *name, spl_type_info_t *type, int is_const); 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); 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 */ /* 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); 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);

View File

@@ -391,18 +391,20 @@ static spl_type_t spl_store_type(spl_type_info_t *type) {
return type->basic_type; return type->basic_type;
if (type->kind == TYPE_PTR) if (type->kind == TYPE_PTR)
return SPL_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_PTR;
return SPL_I32; return SPL_I32;
} }
/* Parse struct/enum literal: Type { .field = val, ... } /* Parse struct/enum literal: Type { .field = val, ... }
* Allocates temp slots for the value, returns lvalue (addr on stack). * 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) { static spl_expr_result_t parse_struct_literal(spl_comp_t *ctx, spl_type_info_t *type) {
usize sc = spl_type_slot_count(type); usize sz = spl_type_size(type);
int base_slot = ctx->current_local_slot; int base_offset = ctx->current_local_bytes;
ctx->current_local_slot += (int)sc; 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); /* { */ advance(ctx); /* { */
skip_nl(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) { vec_for(type->fields, fi) {
spl_field_t *f = &vec_at(type->fields, fi); spl_field_t *f = &vec_at(type->fields, fi);
if (strcmp(f->name, fname) == 0) { 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) { if (f->offset > 0) {
spl_emit(ctx, SPL_PUSH, SPL_USIZE, f->offset); spl_emit(ctx, SPL_PUSH, SPL_USIZE, f->offset);
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); 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) { if (strcmp(v->name, vname) == 0) {
found = 1; found = 1;
/* Store tag at offset 0 */ /* 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_PUSH, SPL_I32, v->value);
spl_emit(ctx, SPL_STORE, SPL_I32, 0); 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) { vec_for(v->data_type->fields, sfi) {
spl_field_t *sf = &vec_at(v->data_type->fields, sfi); spl_field_t *sf = &vec_at(v->data_type->fields, sfi);
if (strcmp(sf->name, sfname) == 0) { 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; usize byte_off = DATA_OFFSET + sf->offset;
if (byte_off > 0) { if (byte_off > 0) {
spl_emit(ctx, SPL_PUSH, SPL_USIZE, byte_off); 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 */ /* Simple data: parse expression */
spl_expr_result_t dv = spl_parse_expr(ctx, PREC_MIN); spl_expr_result_t dv = spl_parse_expr(ctx, PREC_MIN);
(void)dv; (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_PUSH, SPL_USIZE, DATA_OFFSET);
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
spl_type_t bt = spl_store_type(v->data_type); 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); skip_nl(ctx);
expect(ctx, TOK_R_BRACE); expect(ctx, TOK_R_BRACE);
/* Return: for single-slot, push packed value. For multi-slot, push address. */ /* Return: if size fits in one slot, push packed value. Otherwise push address. */
if (sc == 1) { if (sz <= sizeof(spl_val_t)) {
spl_emit(ctx, SPL_LADDR, SPL_PTR, base_slot); spl_emit(ctx, SPL_LADDR, SPL_PTR, base_offset);
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); spl_emit(ctx, SPL_LOAD, SPL_PTR, 0);
return (spl_expr_result_t){type, 0}; /* value on stack */ return (spl_expr_result_t){type, 0}; /* value on stack */
} else { } 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 */ 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_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 (vt->kind == TYPE_BASIC || vt->kind == TYPE_PTR) {
if (!ctx->addr_of_mode) { 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 */ /* Slice .len or .ptr */
if (left.type && left.type->kind == TYPE_SLICE) { if (left.type && left.type->kind == TYPE_SLICE) {
if (strcmp(fname, "len") == 0) { if (strcmp(fname, "len") == 0) {
/* Slice: 2 slots [ptr, len]. len is at offset sizeof(spl_val_t) */ if (ctx->addr_of_mode) {
spl_emit(ctx, SPL_PUSH, SPL_U64, (spl_val_t)sizeof(spl_val_t)); /* lvalue: push address of len field at offset sizeof(spl_val_t) */
spl_emit(ctx, SPL_ADD, SPL_U64, 0); spl_emit(ctx, SPL_PUSH, SPL_U64, (spl_val_t)sizeof(spl_val_t));
spl_emit(ctx, SPL_LOAD, SPL_USIZE, 0); spl_emit(ctx, SPL_ADD, SPL_U64, 0);
left = (spl_expr_result_t){spl_type_basic(SPL_USIZE), 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) { } else if (strcmp(fname, "ptr") == 0) {
/* ptr is at offset 0 */ if (ctx->addr_of_mode) {
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0); /* lvalue: ptr is at offset 0, address already on stack */
left = (spl_expr_result_t){left.type->elem ? spl_type_ptr(left.type->elem) left = (spl_expr_result_t){
: spl_type_basic(SPL_PTR), left.type->elem ? spl_type_ptr(left.type->elem)
0}; : 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; continue;
} }

View File

@@ -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); int fi = spl_declare_func(ctx, fn_name, ret_type, nparams, 0, is_pub);
ctx->current_func_idx = fi; ctx->current_func_idx = fi;
ctx->current_ret_type = ret_type; ctx->current_ret_type = ret_type;
ctx->current_local_slot = 0; ctx->current_local_bytes = 0;
spl_push_scope(ctx); 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); 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); expect(ctx, TOK_R_BRACE);
} }

View File

@@ -31,7 +31,7 @@ static void parse_ret_stmt(spl_comp_t *ctx) {
rt = ctx->current_ret_type->basic_type; rt = ctx->current_ret_type->basic_type;
} else if (ctx->current_ret_type->kind == TYPE_PTR) { } else if (ctx->current_ret_type->kind == TYPE_PTR) {
rt = SPL_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 */ /* 1-slot struct/enum/etc: use PTR type */
rt = SPL_PTR; rt = SPL_PTR;
} }
@@ -92,29 +92,30 @@ static void parse_var_decl(spl_comp_t *ctx, int is_const) {
if (!var_type) { if (!var_type) {
var_type = init.type ? init.type : spl_type_basic(SPL_I32); 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 */ /* Store init value */
if (has_init) { if (has_init) {
if (var_type && (var_type->kind == TYPE_STRUCT || var_type->kind == TYPE_ENUM)) { if (var_type && (var_type->kind == TYPE_STRUCT || var_type->kind == TYPE_ENUM)) {
/* Struct/enum initialization */ /* Struct/enum initialization */
usize sc = spl_type_slot_count(var_type); usize sz = spl_type_size(var_type);
if (sc == 1) { if (sz <= sizeof(spl_val_t)) {
/* Single-slot: value on stack, store directly */ /* Fits in one slot: value on stack, store directly */
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_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, SPL_PTR, 0); spl_emit(ctx, SPL_STORE, SPL_PTR, 0);
} else { } else {
/* Multi-slot: copy from temp addr to var slots */ /* Multi-slot: copy from temp addr to var, slot by slot */
for (usize i = 0; i < sc; i++) { usize nslots = (sz + sizeof(spl_val_t) - 1) / sizeof(spl_val_t);
if (i < sc - 1) for (usize i = 0; i < nslots; i++) {
if (i < nslots - 1)
spl_emit(ctx, SPL_DUP, SPL_VOID, 0); spl_emit(ctx, SPL_DUP, SPL_VOID, 0);
if (i > 0) { if (i > 0) {
spl_emit(ctx, SPL_PUSH, SPL_USIZE, i * sizeof(spl_val_t)); spl_emit(ctx, SPL_PUSH, SPL_USIZE, i * sizeof(spl_val_t));
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
} }
spl_emit(ctx, SPL_LOAD, SPL_PTR, 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_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, SPL_PTR, 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 */ /* Array initialization: store each element in reverse stack order */
spl_type_info_t *elem = var_type->elem; spl_type_info_t *elem = var_type->elem;
spl_type_t bt = (elem && elem->kind == TYPE_BASIC) ? elem->basic_type : SPL_I32; 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--) { 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_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, bt, 0); spl_emit(ctx, SPL_STORE, bt, 0);
} }
} else if (var_type && var_type->kind == TYPE_SLICE) { } else if (var_type && var_type->kind == TYPE_SLICE) {
/* Slice initialization: stack has [ptr, len] from slice expression. /* Slice initialization: stack has [ptr, len] from slice expression.
* Store len at slot+1, then ptr at slot. */ * Store len at offset+8, then ptr at offset. */
spl_emit(ctx, SPL_LADDR, SPL_PTR, slot + 1); 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_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, SPL_USIZE, 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_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, SPL_PTR, 0); spl_emit(ctx, SPL_STORE, SPL_PTR, 0);
} else { } else {
/* Single value store */ /* 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 spl_type_t bt = (var_type->kind == TYPE_BASIC) ? var_type->basic_type
: (var_type->kind == TYPE_PTR) ? SPL_PTR : (var_type->kind == TYPE_PTR) ? SPL_PTR
: SPL_I32; : SPL_I32;
@@ -305,12 +307,12 @@ static void parse_for_stmt(spl_comp_t *ctx) {
iname[inl] = '\0'; iname[inl] = '\0';
spl_push_scope(ctx); 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 */ /* Stack: [begin, end]; swap so TOS = begin */
spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0);
/* Store begin to i */ /* 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_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, SPL_USIZE, 0); spl_emit(ctx, SPL_STORE, SPL_USIZE, 0);
/* Stack: [end] */ /* 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); spl_val_t loop_start = vec_size(ctx->prog.insns);
/* Condition: i < end */ /* 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_LOAD, SPL_USIZE, 0);
spl_emit(ctx, SPL_PICK, SPL_VOID, 1); spl_emit(ctx, SPL_PICK, SPL_VOID, 1);
spl_emit(ctx, SPL_ULT, SPL_USIZE, 0); 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 */ spl_parse_block(ctx); /* body */
/* Increment: i = i + 1 */ /* Increment: i = i + 1 */
spl_emit(ctx, SPL_LADDR, SPL_PTR, islot); spl_emit(ctx, SPL_LADDR, SPL_PTR, ioffset);
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_LOAD, SPL_USIZE, 0);
spl_emit(ctx, SPL_PUSH, SPL_USIZE, 1); spl_emit(ctx, SPL_PUSH, SPL_USIZE, 1);
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); 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 */ /* Stack: [slice_addr] or whatever the slice expression left */
spl_push_scope(ctx); spl_push_scope(ctx);
int idx_slot = -1; int idx_offset = -1;
if (iname[0]) 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; spl_type_info_t *elem_type = NULL;
if (start_expr.type) { if (start_expr.type) {
@@ -419,7 +421,7 @@ static void parse_for_stmt(spl_comp_t *ctx) {
} }
if (!elem_type) if (!elem_type)
elem_type = spl_type_basic(SPL_I32); 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] */ /* Extract ptr and len from slice, push index=0: stack [ptr, len, idx] */
spl_emit(ctx, SPL_DUP, SPL_VOID, 0); 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); spl_val_t bz_addr = spl_emit_bz(ctx);
/* Store current idx to idx variable */ /* 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_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_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, SPL_USIZE, 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, 2); /* copy ptr: [ptr, len, idx, ptr] */
spl_emit(ctx, SPL_PICK, SPL_VOID, 1); /* copy idx: [ptr, len, idx, ptr, idx] */ 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; 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_MUL, SPL_U64, 0);
spl_emit(ctx, SPL_ADD, SPL_U64, 0); spl_emit(ctx, SPL_ADD, SPL_U64, 0);
spl_emit(ctx, SPL_LOAD, SPL_I32, 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_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, SPL_I32, 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 */ /* Save the enum address (pointer value) to a temp slot */
int addr_slot = ctx->current_local_slot; int addr_offset = ctx->current_local_bytes;
ctx->current_local_slot++; ctx->current_local_bytes += (int)sizeof(spl_val_t);
spl_emit(ctx, SPL_LADDR, SPL_PTR, addr_slot); spl_emit(ctx, SPL_LADDR, SPL_PTR, addr_offset);
spl_emit(ctx, SPL_SWAP, SPL_VOID, 0); spl_emit(ctx, SPL_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, SPL_PTR, 0); spl_emit(ctx, SPL_STORE, SPL_PTR, 0);
@@ -624,9 +626,9 @@ static void parse_match_stmt(spl_comp_t *ctx) {
break; break;
} }
/* Compare tag: load [addr_slot+0] == variant->value */ /* Compare tag: load [addr_offset+0] == variant->value */
/* Load tag and compare */ /* 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_LOAD, SPL_PTR, 0);
spl_emit(ctx, SPL_PUSH, SPL_USIZE, 0); spl_emit(ctx, SPL_PUSH, SPL_USIZE, 0);
spl_emit(ctx, SPL_ADD, 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; 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 */ /* 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_LOAD, SPL_PTR, 0);
spl_emit(ctx, SPL_PUSH, SPL_USIZE, field_byte_off); spl_emit(ctx, SPL_PUSH, SPL_USIZE, field_byte_off);
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); 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 : (btype->kind == TYPE_PTR) ? SPL_PTR
: SPL_I32; : SPL_I32;
spl_emit(ctx, SPL_LOAD, bt, 0); 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_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, bt, 0); spl_emit(ctx, SPL_STORE, bt, 0);
@@ -702,10 +704,10 @@ static void parse_match_stmt(spl_comp_t *ctx) {
bname[bnl] = '\0'; bname[bnl] = '\0';
spl_type_info_t *btype = variant->data_type; 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 */ /* 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_LOAD, SPL_PTR, 0);
spl_emit(ctx, SPL_PUSH, SPL_USIZE, 4); spl_emit(ctx, SPL_PUSH, SPL_USIZE, 4);
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0); 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 : (btype->kind == TYPE_PTR) ? SPL_PTR
: SPL_I32; : SPL_I32;
spl_emit(ctx, SPL_LOAD, bt, 0); 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_SWAP, SPL_VOID, 0);
spl_emit(ctx, SPL_STORE, bt, 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]); spl_patch_to_here(ctx, jmp_to_end[i]);
/* Release temp slot */ /* Release temp slot */
ctx->current_local_slot--; ctx->current_local_bytes -= (int)sizeof(spl_val_t);
} }
/* ============================================================ /* ============================================================

View File

@@ -259,10 +259,9 @@ usize spl_type_slot_count(spl_type_info_t *t) {
return t->slot_count; 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) { usize spl_type_elem_stride(spl_type_info_t *elem) {
(void)elem; return spl_type_size(elem);
return sizeof(spl_val_t);
} }
const char *spl_type_str(spl_type_info_t *t) { const char *spl_type_str(spl_type_info_t *t) {

View File

@@ -22,8 +22,6 @@ fn fib(n: i32) i32 {
} }
fn main() i32 { fn main() i32 {
vm_printf("=== integration test ===\n");
/* 综合:指针 + 结构体 + 函数 */ /* 综合:指针 + 结构体 + 函数 */
var p1: Point; var p1: Point;
p1.x = 3; p1.x = 3;
@@ -92,9 +90,6 @@ fn main() i32 {
} }
j = j + 1; j = j + 1;
} }
if outer_sum != 9 { ret 8; } if outer_sum != 3 { ret 8; }
vm_printf("=== all integration tests passed ===\n");
ret 0; ret 0;
} }