stage1 将数组和聚合类型使用byte offset而不是slot idx
This commit is contained in:
@@ -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 ---- */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user