stage1 vm abi更新 修复更多问题
This commit is contained in:
1 parent
09d05e3a34
commit
f6a0bce9f0
6 files changed
+124
-60
No files matched your search
+46
-7
@@ -306,7 +306,10 @@ static void frame_build(frame_layout_t *fl, spl_ir2vm_t *ctx, spl_ir_func_ref_t
|
||||
|
||||
spl_type_node_t *ftn = spl_type_node(ctx->type, f->fn_tid);
|
||||
usize nargs = (ftn && ftn->kind == SPL_TYPE_FN) ? vec_size(ftn->fn_type.params) : 0;
|
||||
fl->args_bytes = nargs * sizeof(spl_vm_val_t);
|
||||
spl_type_id_t ret_t = (ftn && ftn->kind == SPL_TYPE_FN) ? ftn->fn_type.ret : 0;
|
||||
/* 聚合返回时 fp+0 是 caller 传入的 sret 指针,占用一个隐藏参数槽 */
|
||||
usize hidden_sret = ir_is_aggregate(ctx, ret_t) ? 1 : 0;
|
||||
fl->args_bytes = (nargs + hidden_sret) * sizeof(spl_vm_val_t);
|
||||
|
||||
usize off = fl->args_bytes;
|
||||
|
||||
@@ -743,14 +746,35 @@ static void cg_control(cgen_t *cg, usize ref, const spl_ir_node_t *n) {
|
||||
if (idx_node->kind == SPL_IR_TYPE_CONST)
|
||||
idx = (usize)idx_node->type_const.int_lit;
|
||||
}
|
||||
CG_LADDR(cg, idx * sizeof(spl_vm_val_t));
|
||||
/* 聚合返回时 fp+0 是 sret 指针,实参从 fp+8 起 */
|
||||
spl_type_node_t *ftn = spl_type_node(ctx->type, cg->irf->fn_tid);
|
||||
spl_type_id_t cur_ret = (ftn && ftn->kind == SPL_TYPE_FN) ? ftn->fn_type.ret : 0;
|
||||
usize shift = ir_is_aggregate(ctx, cur_ret) ? 1 : 0;
|
||||
CG_LADDR(cg, (idx + shift) * sizeof(spl_vm_val_t));
|
||||
CG_LOAD(cg, k);
|
||||
cg_store_slot(cg, ref, k);
|
||||
break;
|
||||
}
|
||||
|
||||
case SPL_IR_CONTROL_RET: {
|
||||
uint8_t k = vm_kind_of(ctx, n->control_ret.tid);
|
||||
spl_type_id_t ret_tid = n->control_ret.tid;
|
||||
if (ir_is_aggregate(ctx, ret_tid)) {
|
||||
/* sret:把返回值写入 *(fp+0),然后以 void 返回 */
|
||||
if (n->control_ret.val) {
|
||||
usize sz = ir_type_size(ctx, ret_tid);
|
||||
CG_LADDR(cg, 0);
|
||||
CG_LOAD(cg, SPL_PTR);
|
||||
cg_load_slot(cg, n->control_ret.val, SPL_PTR);
|
||||
CG_PUSH(cg, SPL_U64, sz);
|
||||
int nat = get_or_add_native(ctx, "vm_memcpy");
|
||||
CG_PUSH(cg, SPL_U64, (spl_vm_val_t)nat);
|
||||
emit(cg, SPL_NCALL, SPL_VOID, 3);
|
||||
emit(cg, SPL_DROP, SPL_VOID, 0);
|
||||
}
|
||||
emit(cg, SPL_RET, SPL_VOID, 0);
|
||||
break;
|
||||
}
|
||||
uint8_t k = vm_kind_of(ctx, ret_tid);
|
||||
if (k != SPL_VOID && n->control_ret.val)
|
||||
cg_load_slot(cg, n->control_ret.val, k);
|
||||
emit(cg, SPL_RET, k, 0);
|
||||
@@ -807,6 +831,14 @@ static void cg_control(cgen_t *cg, usize ref, const spl_ir_node_t *n) {
|
||||
else
|
||||
cg_store_slot(cg, ref, rk);
|
||||
} else {
|
||||
spl_type_id_t ret_t = n->control_call.tid;
|
||||
bool ret_is_sret = ir_is_aggregate(ctx, ret_t);
|
||||
usize sret_off = 0;
|
||||
|
||||
if (ret_is_sret) {
|
||||
sret_off = vec_at(cg->frame.slots, ref).data_off;
|
||||
CG_LADDR(cg, sret_off);
|
||||
}
|
||||
for (usize i = 0; i < nargs; ++i) {
|
||||
spl_ir_node_ref_t pref = vec_at(n->control_call.params, i);
|
||||
const spl_ir_node_t *pn = &vec_at(cg->irf->nodes, pref);
|
||||
@@ -815,11 +847,18 @@ static void cg_control(cgen_t *cg, usize ref, const spl_ir_node_t *n) {
|
||||
cg_load_slot(cg, pref, pk);
|
||||
}
|
||||
cg_load_slot(cg, fref, SPL_PTR);
|
||||
emit(cg, SPL_CALL, SPL_VOID, (spl_vm_val_t)nargs);
|
||||
spl_vm_val_t actual_nargs = nargs + (ret_is_sret ? 1 : 0);
|
||||
emit(cg, SPL_CALL, SPL_VOID, actual_nargs);
|
||||
|
||||
uint8_t rk = vm_kind_of(ctx, n->control_call.tid);
|
||||
if (rk != SPL_VOID)
|
||||
cg_store_slot(cg, ref, rk);
|
||||
if (ret_is_sret) {
|
||||
/* 结果槽保存 sret 指针,后续 agg_extract 把它当聚合首地址 */
|
||||
CG_LADDR(cg, sret_off);
|
||||
cg_store_slot(cg, ref, SPL_PTR);
|
||||
} else {
|
||||
uint8_t rk = vm_kind_of(ctx, ret_t);
|
||||
if (rk != SPL_VOID)
|
||||
cg_store_slot(cg, ref, rk);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user