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