stage1 - 全面重构 stage1 编译器架构:类型系统(arena + items)、IR 发射层(spl_emit.h/c)、统一所有 emit 调用点。
- 实现 as 类型转换运算符、修复 &&/|| 短路求值 bug。 - 在 splc1.spl 中实现 Vec/Map/Emit 基础库(~50 个方法)。 - 修复实例方法调用中 self 参数被错误丢弃的 bug。
This commit is contained in:
@@ -52,8 +52,7 @@ static int tok_prec(spl_tok_type_t t) {
|
||||
}
|
||||
|
||||
static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, spl_tok_type_t op);
|
||||
static void emit_load_or_addr_type(spl_comp_t *ctx, spl_expr_result_t *result,
|
||||
int type_idx);
|
||||
static void emit_load_or_addr_type(spl_comp_t *ctx, spl_expr_result_t *result, int type_idx);
|
||||
static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t left);
|
||||
|
||||
static void emit_slice_create(spl_comp_t *ctx, usize stride) {
|
||||
@@ -90,7 +89,8 @@ static int spl_resolve_type_member(spl_comp_t *ctx, int type_idx, const char *fi
|
||||
spl_type_item_vec_t *items = spl_type_items(&ctx->tctx, type_idx);
|
||||
vec_for(*items, i) {
|
||||
spl_type_item_t *it = &vec_at(*items, i);
|
||||
if (it->item_kind != ITEM_VARIANT) continue;
|
||||
if (it->item_kind != ITEM_VARIANT)
|
||||
continue;
|
||||
if (strcmp(it->name, field) == 0) {
|
||||
emit_push_i32(&ctx->emit, it->enum_field.value);
|
||||
*result = (spl_expr_result_t){type_idx, 0};
|
||||
@@ -365,7 +365,8 @@ static void parse_one_field_init(spl_comp_t *ctx, spl_type_item_vec_t *items, in
|
||||
|
||||
vec_for(*items, fi) {
|
||||
spl_type_item_t *it = &vec_at(*items, fi);
|
||||
if (it->item_kind != ITEM_FIELD) continue;
|
||||
if (it->item_kind != ITEM_FIELD)
|
||||
continue;
|
||||
if (strcmp(it->name, fname) == 0) {
|
||||
emit_laddr(&ctx->emit, base_offset);
|
||||
usize byte_off = extra_offset + it->aggregate_field.offset;
|
||||
@@ -403,7 +404,8 @@ static void parse_one_field_init(spl_comp_t *ctx, spl_type_item_vec_t *items, in
|
||||
emit_ptr_add(&ctx->emit, i * stride);
|
||||
spl_parse_expr(ctx, PREC_MIN);
|
||||
if (elem_type_idx >= 0 && !spl_type_is_scalar(&ctx->tctx, elem_type_idx)) {
|
||||
emit_copy_addr_to_addr(&ctx->emit, spl_type_slot_count(&ctx->tctx, elem_type_idx), 1);
|
||||
emit_copy_addr_to_addr(&ctx->emit,
|
||||
spl_type_slot_count(&ctx->tctx, elem_type_idx), 1);
|
||||
} else {
|
||||
emit_store_type(&ctx->emit, st);
|
||||
}
|
||||
@@ -425,8 +427,11 @@ static void parse_one_field_init(spl_comp_t *ctx, spl_type_item_vec_t *items, in
|
||||
fv = spl_parse_expr(ctx, PREC_MIN);
|
||||
}
|
||||
(void)fv;
|
||||
usize nslots = (spl_type_size(&ctx->tctx, ft_idx) + sizeof(spl_val_t) - 1) / sizeof(spl_val_t);
|
||||
emit_frame_copy(&ctx->emit, base_offset + (int)extra_offset + (int)it->aggregate_field.offset, nslots);
|
||||
usize nslots =
|
||||
(spl_type_size(&ctx->tctx, ft_idx) + sizeof(spl_val_t) - 1) / sizeof(spl_val_t);
|
||||
emit_frame_copy(&ctx->emit,
|
||||
base_offset + (int)extra_offset + (int)it->aggregate_field.offset,
|
||||
nslots);
|
||||
emit_drop(&ctx->emit);
|
||||
} else {
|
||||
spl_expr_result_t fv = spl_parse_expr(ctx, PREC_MIN);
|
||||
@@ -512,7 +517,8 @@ spl_expr_result_t spl_parse_struct_literal(spl_comp_t *ctx, int type_idx) {
|
||||
spl_type_item_vec_t *items = spl_type_items(&ctx->tctx, type_idx);
|
||||
vec_for(*items, vi) {
|
||||
spl_type_item_t *v = &vec_at(*items, vi);
|
||||
if (v->item_kind != ITEM_VARIANT) continue;
|
||||
if (v->item_kind != ITEM_VARIANT)
|
||||
continue;
|
||||
if (strcmp(v->name, vname) == 0) {
|
||||
found = 1;
|
||||
emit_laddr(&ctx->emit, base_offset);
|
||||
@@ -620,15 +626,16 @@ static void spl_check_arg_type(spl_comp_t *ctx, const char *fname, int arg_type_
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_call_args_checked(spl_comp_t *ctx, const char *fname,
|
||||
int *param_type_indices, int nparams) {
|
||||
static int parse_call_args_checked(spl_comp_t *ctx, const char *fname, int *param_type_indices,
|
||||
int nparams) {
|
||||
int nargs = 0;
|
||||
int nlogical = 0;
|
||||
if (peek(ctx)->type != TOK_R_PAREN) {
|
||||
for (;;) {
|
||||
spl_expr_result_t arg = spl_parse_expr(ctx, PREC_MIN);
|
||||
if (param_type_indices && nlogical < nparams && param_type_indices[nlogical] >= 0)
|
||||
spl_check_arg_type(ctx, fname, arg.type_idx, param_type_indices[nlogical], nlogical);
|
||||
spl_check_arg_type(ctx, fname, arg.type_idx, param_type_indices[nlogical],
|
||||
nlogical);
|
||||
|
||||
int arg_slots = 1;
|
||||
if (param_type_indices && nlogical < nparams && param_type_indices[nlogical] >= 0 &&
|
||||
@@ -636,7 +643,8 @@ static int parse_call_args_checked(spl_comp_t *ctx, const char *fname,
|
||||
spl_type_kind(&ctx->tctx, param_type_indices[nlogical]) != TYPE_PTR &&
|
||||
spl_type_needs_multi_slot(&ctx->tctx, param_type_indices[nlogical])) {
|
||||
usize nslots = (spl_type_size(&ctx->tctx, param_type_indices[nlogical]) +
|
||||
sizeof(spl_val_t) - 1) / sizeof(spl_val_t);
|
||||
sizeof(spl_val_t) - 1) /
|
||||
sizeof(spl_val_t);
|
||||
for (usize i = 0; i < nslots; i++) {
|
||||
emit_dup(&ctx->emit);
|
||||
emit_ptr_add(&ctx->emit, i * sizeof(spl_val_t));
|
||||
@@ -738,8 +746,7 @@ static spl_expr_result_t parse_group(spl_comp_t *ctx) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static void emit_load_or_addr_type(spl_comp_t *ctx, spl_expr_result_t *result,
|
||||
int type_idx) {
|
||||
static void emit_load_or_addr_type(spl_comp_t *ctx, spl_expr_result_t *result, int type_idx) {
|
||||
if (spl_type_is_scalar(&ctx->tctx, type_idx)) {
|
||||
if (!ctx->addr_of_mode) {
|
||||
emit_load_type(&ctx->emit, spl_type_emit_type(&ctx->tctx, type_idx));
|
||||
@@ -776,8 +783,7 @@ static spl_expr_result_t parse_prefix_op(spl_comp_t *ctx) {
|
||||
}
|
||||
break;
|
||||
case TOK_MUL:
|
||||
if (right.type_idx >= 0 &&
|
||||
spl_type_kind(&ctx->tctx, right.type_idx) == TYPE_PTR &&
|
||||
if (right.type_idx >= 0 && spl_type_kind(&ctx->tctx, right.type_idx) == TYPE_PTR &&
|
||||
spl_type_elem_type(&ctx->tctx, right.type_idx) >= 0) {
|
||||
if (right.is_lvalue) {
|
||||
emit_load_ptr(&ctx->emit);
|
||||
@@ -907,9 +913,8 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
int is_ptr_self = 0;
|
||||
if (spl_type_kind(&ctx->tctx, methods_type_idx) == TYPE_PTR) {
|
||||
int elem_idx = spl_type_elem_type(&ctx->tctx, methods_type_idx);
|
||||
if (elem_idx >= 0 &&
|
||||
(spl_type_kind(&ctx->tctx, elem_idx) == TYPE_STRUCT ||
|
||||
spl_type_kind(&ctx->tctx, elem_idx) == TYPE_ENUM)) {
|
||||
if (elem_idx >= 0 && (spl_type_kind(&ctx->tctx, elem_idx) == TYPE_STRUCT ||
|
||||
spl_type_kind(&ctx->tctx, elem_idx) == TYPE_ENUM)) {
|
||||
is_ptr_self = 1;
|
||||
methods_type_idx = elem_idx;
|
||||
}
|
||||
@@ -919,7 +924,8 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
spl_type_item_vec_t *m_items = spl_type_items(&ctx->tctx, methods_type_idx);
|
||||
vec_for(*m_items, mi) {
|
||||
spl_type_item_t *mit = &vec_at(*m_items, mi);
|
||||
if (mit->item_kind != ITEM_METHOD) continue;
|
||||
if (mit->item_kind != ITEM_METHOD)
|
||||
continue;
|
||||
if (strcmp(mit->name, fname) == 0) {
|
||||
spl_func_info_t *func = &vec_at(ctx->funcs, mit->method.func_idx);
|
||||
|
||||
@@ -931,7 +937,8 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
int is_instance = 0;
|
||||
if (func->nparams > 0 && func->param_type_indices[0] >= 0 &&
|
||||
spl_type_kind(&ctx->tctx, func->param_type_indices[0]) == TYPE_PTR &&
|
||||
spl_type_elem_type(&ctx->tctx, func->param_type_indices[0]) == methods_type_idx) {
|
||||
spl_type_elem_type(&ctx->tctx, func->param_type_indices[0]) ==
|
||||
methods_type_idx) {
|
||||
is_instance = 1;
|
||||
}
|
||||
|
||||
@@ -978,7 +985,8 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
spl_type_item_vec_t *f_items = spl_type_items(&ctx->tctx, left.type_idx);
|
||||
vec_for(*f_items, fi) {
|
||||
spl_type_item_t *fit = &vec_at(*f_items, fi);
|
||||
if (fit->item_kind != ITEM_FIELD) continue;
|
||||
if (fit->item_kind != ITEM_FIELD)
|
||||
continue;
|
||||
if (strcmp(fit->name, fname) == 0) {
|
||||
emit_ptr_add(&ctx->emit, fit->aggregate_field.offset);
|
||||
emit_load_or_addr_type(ctx, &left, fit->aggregate_field.type_idx);
|
||||
@@ -997,7 +1005,8 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
spl_type_item_vec_t *st_items = spl_type_items(&ctx->tctx, elem_idx);
|
||||
vec_for(*st_items, si) {
|
||||
spl_type_item_t *sit = &vec_at(*st_items, si);
|
||||
if (sit->item_kind != ITEM_FIELD) continue;
|
||||
if (sit->item_kind != ITEM_FIELD)
|
||||
continue;
|
||||
if (strcmp(sit->name, fname) == 0) {
|
||||
emit_ptr_add(&ctx->emit, sit->aggregate_field.offset);
|
||||
emit_load_or_addr_type(ctx, &left, sit->aggregate_field.type_idx);
|
||||
@@ -1024,13 +1033,15 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
int sl_elem_idx = spl_type_elem_type(&ctx->tctx, left.type_idx);
|
||||
if (ctx->addr_of_mode) {
|
||||
left = (spl_expr_result_t){sl_elem_idx >= 0
|
||||
? spl_type_ptr(&ctx->tctx, sl_elem_idx)
|
||||
: spl_type_basic(&ctx->tctx, SPL_PTR), 1};
|
||||
? spl_type_ptr(&ctx->tctx, sl_elem_idx)
|
||||
: spl_type_basic(&ctx->tctx, SPL_PTR),
|
||||
1};
|
||||
} else {
|
||||
emit_load_ptr(&ctx->emit);
|
||||
left = (spl_expr_result_t){sl_elem_idx >= 0
|
||||
? spl_type_ptr(&ctx->tctx, sl_elem_idx)
|
||||
: spl_type_basic(&ctx->tctx, SPL_PTR), 0};
|
||||
? spl_type_ptr(&ctx->tctx, sl_elem_idx)
|
||||
: spl_type_basic(&ctx->tctx, SPL_PTR),
|
||||
0};
|
||||
}
|
||||
}
|
||||
continue;
|
||||
@@ -1072,9 +1083,11 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
expect(ctx, TOK_R_BRACKET);
|
||||
|
||||
if (!has_explicit_end) {
|
||||
if (left.type_idx >= 0 && spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_ARRAY) {
|
||||
if (left.type_idx >= 0 &&
|
||||
spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_ARRAY) {
|
||||
emit_push_u64(&ctx->emit, spl_type_array_len(&ctx->tctx, left.type_idx));
|
||||
} else if (left.type_idx >= 0 && spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_SLICE) {
|
||||
} else if (left.type_idx >= 0 &&
|
||||
spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_SLICE) {
|
||||
emit_pick(&ctx->emit, 1);
|
||||
emit_push_u64(&ctx->emit, sizeof(spl_val_t));
|
||||
emit_add_u64(&ctx->emit);
|
||||
@@ -1108,18 +1121,19 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
emit_slice_create(ctx, stride);
|
||||
}
|
||||
}
|
||||
left = (spl_expr_result_t){left.type_idx >= 0
|
||||
left = (spl_expr_result_t){
|
||||
left.type_idx >= 0
|
||||
? spl_type_slice(&ctx->tctx, spl_type_elem_type(&ctx->tctx, left.type_idx))
|
||||
: -1, 0};
|
||||
: -1,
|
||||
0};
|
||||
continue;
|
||||
}
|
||||
|
||||
expect(ctx, TOK_R_BRACKET);
|
||||
|
||||
if (left.type_idx >= 0 &&
|
||||
(spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_ARRAY ||
|
||||
spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_PTR ||
|
||||
spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_SLICE)) {
|
||||
if (left.type_idx >= 0 && (spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_ARRAY ||
|
||||
spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_PTR ||
|
||||
spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_SLICE)) {
|
||||
int idx_elem_idx = spl_type_elem_type(&ctx->tctx, left.type_idx);
|
||||
|
||||
if (spl_type_kind(&ctx->tctx, left.type_idx) == TYPE_SLICE) {
|
||||
@@ -1141,6 +1155,34 @@ static spl_expr_result_t parse_postfix_expr(spl_comp_t *ctx, spl_expr_result_t l
|
||||
continue;
|
||||
}
|
||||
|
||||
if (opt == KW_AS) {
|
||||
usize saved = ctx->tok_idx;
|
||||
int saved_err = ctx->has_error;
|
||||
char saved_msg[COMP_ERROR_MAX];
|
||||
memcpy(saved_msg, ctx->error_msg, COMP_ERROR_MAX);
|
||||
advance(ctx); /* as */
|
||||
skip_nl(ctx);
|
||||
int target_type_idx = spl_type_parse(&ctx->tctx, ctx);
|
||||
if (target_type_idx < 0) {
|
||||
ctx->tok_idx = saved;
|
||||
ctx->has_error = saved_err;
|
||||
memcpy(ctx->error_msg, saved_msg, COMP_ERROR_MAX);
|
||||
break;
|
||||
}
|
||||
usize src_sz = spl_type_size(&ctx->tctx, left.type_idx);
|
||||
usize dst_sz = spl_type_size(&ctx->tctx, target_type_idx);
|
||||
if (dst_sz > src_sz) {
|
||||
int src_signed =
|
||||
spl_type_is_integer(spl_type_basic_type(&ctx->tctx, left.type_idx));
|
||||
uint16_t opc = src_signed ? SPL_SEXT : SPL_ZEXT;
|
||||
emit_raw(&ctx->emit, opc, 0, dst_sz * 8);
|
||||
} else if (dst_sz < src_sz) {
|
||||
emit_raw(&ctx->emit, SPL_TRUNC, 0, dst_sz * 8);
|
||||
}
|
||||
left = (spl_expr_result_t){target_type_idx, 0};
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
return left;
|
||||
@@ -1175,13 +1217,19 @@ static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, sp
|
||||
if (op == TOK_AND_AND) {
|
||||
spl_val_t bz_addr = emit_bz_here(&ctx->emit);
|
||||
spl_parse_expr(ctx, next_prec);
|
||||
spl_val_t jmp_addr = emit_jmp_here(&ctx->emit);
|
||||
emit_patch_here(&ctx->emit, bz_addr);
|
||||
emit_push_i32(&ctx->emit, 0);
|
||||
emit_patch_here(&ctx->emit, jmp_addr);
|
||||
return (spl_expr_result_t){spl_type_basic(&ctx->tctx, SPL_I32), 0};
|
||||
}
|
||||
if (op == TOK_OR_OR) {
|
||||
spl_val_t bnz_addr = emit_bnz_here(&ctx->emit);
|
||||
spl_parse_expr(ctx, next_prec);
|
||||
spl_val_t jmp_addr = emit_jmp_here(&ctx->emit);
|
||||
emit_patch_here(&ctx->emit, bnz_addr);
|
||||
emit_push_i32(&ctx->emit, 1);
|
||||
emit_patch_here(&ctx->emit, jmp_addr);
|
||||
return (spl_expr_result_t){spl_type_basic(&ctx->tctx, SPL_I32), 0};
|
||||
}
|
||||
|
||||
@@ -1198,9 +1246,9 @@ static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, sp
|
||||
if (left.is_lvalue) {
|
||||
spl_type_t bt = spl_type_emit_type(&ctx->tctx, left.type_idx);
|
||||
if (op == TOK_ASSIGN && left.type_idx >= 0 &&
|
||||
!spl_type_is_scalar(&ctx->tctx, left.type_idx) &&
|
||||
right.is_lvalue) {
|
||||
emit_copy_addr_to_addr(&ctx->emit, spl_type_slot_count(&ctx->tctx, left.type_idx), 0);
|
||||
!spl_type_is_scalar(&ctx->tctx, left.type_idx) && right.is_lvalue) {
|
||||
emit_copy_addr_to_addr(&ctx->emit, spl_type_slot_count(&ctx->tctx, left.type_idx),
|
||||
0);
|
||||
} else if (op == TOK_ASSIGN) {
|
||||
emit_store_type(&ctx->emit, bt);
|
||||
} else {
|
||||
@@ -1233,8 +1281,7 @@ static spl_expr_result_t parse_infix(spl_comp_t *ctx, spl_expr_result_t left, sp
|
||||
return (spl_expr_result_t){result_type_idx, 0};
|
||||
}
|
||||
|
||||
int spl_emit_match_enum_cmp(spl_comp_t *ctx, int enum_type_idx,
|
||||
int val_offset, int by_value) {
|
||||
int spl_emit_match_enum_cmp(spl_comp_t *ctx, int enum_type_idx, int val_offset, int by_value) {
|
||||
char vname[256];
|
||||
|
||||
if (peek(ctx)->type == TOK_DOT) {
|
||||
@@ -1259,27 +1306,27 @@ int spl_emit_match_enum_cmp(spl_comp_t *ctx, int enum_type_idx,
|
||||
spl_tok_copy_name(vtok, vname, sizeof(vname));
|
||||
}
|
||||
|
||||
lookup:
|
||||
{
|
||||
spl_type_item_vec_t *e_items = spl_type_items(&ctx->tctx, enum_type_idx);
|
||||
vec_for(*e_items, vi) {
|
||||
spl_type_item_t *vit = &vec_at(*e_items, vi);
|
||||
if (vit->item_kind != ITEM_VARIANT) continue;
|
||||
if (strcmp(vit->name, vname) == 0) {
|
||||
emit_laddr(&ctx->emit, val_offset);
|
||||
if (by_value) {
|
||||
emit_load_type(&ctx->emit, SPL_I32);
|
||||
} else {
|
||||
emit_load_ptr(&ctx->emit);
|
||||
emit_ptr_add(&ctx->emit, 0);
|
||||
emit_load_type(&ctx->emit, SPL_I32);
|
||||
}
|
||||
emit_push_i32(&ctx->emit, vit->enum_field.value);
|
||||
emit_binop(&ctx->emit, SPL_EQ, SPL_I32);
|
||||
return (int)vi;
|
||||
lookup: {
|
||||
spl_type_item_vec_t *e_items = spl_type_items(&ctx->tctx, enum_type_idx);
|
||||
vec_for(*e_items, vi) {
|
||||
spl_type_item_t *vit = &vec_at(*e_items, vi);
|
||||
if (vit->item_kind != ITEM_VARIANT)
|
||||
continue;
|
||||
if (strcmp(vit->name, vname) == 0) {
|
||||
emit_laddr(&ctx->emit, val_offset);
|
||||
if (by_value) {
|
||||
emit_load_type(&ctx->emit, SPL_I32);
|
||||
} else {
|
||||
emit_load_ptr(&ctx->emit);
|
||||
emit_ptr_add(&ctx->emit, 0);
|
||||
emit_load_type(&ctx->emit, SPL_I32);
|
||||
}
|
||||
emit_push_i32(&ctx->emit, vit->enum_field.value);
|
||||
emit_binop(&ctx->emit, SPL_EQ, SPL_I32);
|
||||
return (int)vi;
|
||||
}
|
||||
}
|
||||
}
|
||||
spl_comp_error(ctx, "unknown variant '%s' in match", vname);
|
||||
return -1;
|
||||
}
|
||||
@@ -1290,49 +1337,3 @@ void spl_emit_match_value_cmp(spl_comp_t *ctx, int val_offset) {
|
||||
spl_parse_expr(ctx, PREC_LOGOR);
|
||||
emit_binop(&ctx->emit, SPL_EQ, SPL_I32);
|
||||
}
|
||||
|
||||
void spl_emit_ret(spl_comp_t *ctx, int ret_type_idx) {
|
||||
if (spl_type_needs_multi_slot(&ctx->tctx, ret_type_idx)) {
|
||||
/* Stack: [src_addr] — copy from src into fp+sizeof(spl_val_t) return area */
|
||||
emit_laddr(&ctx->emit, (int)sizeof(spl_val_t));
|
||||
emit_swap(&ctx->emit);
|
||||
emit_copy_addr_to_addr(&ctx->emit,
|
||||
spl_type_slot_count(&ctx->tctx, ret_type_idx), 0);
|
||||
/* Stack empty after copy. emit_return pushes laddr + ret. */
|
||||
}
|
||||
emit_return(&ctx->emit, &ctx->tctx, ret_type_idx);
|
||||
}
|
||||
|
||||
void spl_emit_store_init(spl_comp_t *ctx, int var_offset, int var_type_idx) {
|
||||
if (var_type_idx >= 0 &&
|
||||
(spl_type_kind(&ctx->tctx, var_type_idx) == TYPE_STRUCT ||
|
||||
spl_type_kind(&ctx->tctx, var_type_idx) == TYPE_ENUM)) {
|
||||
usize sz = spl_type_size(&ctx->tctx, var_type_idx);
|
||||
if (sz <= sizeof(spl_val_t)) {
|
||||
emit_store_to_laddr(&ctx->emit, var_offset, spl_type_emit_type(&ctx->tctx, var_type_idx));
|
||||
} else {
|
||||
usize nslots = (sz + sizeof(spl_val_t) - 1) / sizeof(spl_val_t);
|
||||
emit_frame_copy(&ctx->emit, var_offset, nslots);
|
||||
}
|
||||
} else if (var_type_idx >= 0 && spl_type_kind(&ctx->tctx, var_type_idx) == TYPE_ARRAY) {
|
||||
int elem_idx = spl_type_elem_type(&ctx->tctx, var_type_idx);
|
||||
spl_type_t bt = spl_type_emit_type(&ctx->tctx, elem_idx);
|
||||
usize stride = spl_type_elem_stride(&ctx->tctx, elem_idx);
|
||||
int arr_len = (int)spl_type_array_len(&ctx->tctx, var_type_idx);
|
||||
for (int i = arr_len - 1; i >= 0; i--) {
|
||||
emit_laddr(&ctx->emit, var_offset + (int)(i * stride));
|
||||
emit_swap(&ctx->emit);
|
||||
if (elem_idx >= 0 && !spl_type_is_scalar(&ctx->tctx, elem_idx)) {
|
||||
emit_copy_addr_to_addr(&ctx->emit, spl_type_slot_count(&ctx->tctx, elem_idx), 0);
|
||||
} else {
|
||||
emit_store_type(&ctx->emit, bt);
|
||||
}
|
||||
}
|
||||
} else if (var_type_idx >= 0 && spl_type_kind(&ctx->tctx, var_type_idx) == TYPE_SLICE) {
|
||||
emit_store_to_laddr(&ctx->emit, var_offset + (int)sizeof(spl_val_t), SPL_USIZE);
|
||||
emit_store_to_laddr(&ctx->emit, var_offset, SPL_PTR);
|
||||
} else {
|
||||
spl_type_t bt = spl_type_emit_type(&ctx->tctx, var_type_idx);
|
||||
emit_store_to_laddr(&ctx->emit, var_offset, bt);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user