stage1 vm abi更新 修复更多问题
This commit is contained in:
1 parent
09d05e3a34
commit
f6a0bce9f0
6 files changed
+124
-60
No files matched your search
+6
-3
@@ -175,11 +175,14 @@ static isize parse_int_literal(const spl_tok_t *t) {
|
||||
buf[j++] = t->lexeme[i];
|
||||
}
|
||||
buf[j] = 0;
|
||||
/* 字面量按无符号位模式解析,以容纳完整的 u64 值域 */
|
||||
if (j >= 3 && buf[0] == '0' && (buf[1] == 'b' || buf[1] == 'B'))
|
||||
return (isize)strtoll(buf + 2, NULL, 2);
|
||||
return (isize)strtoull(buf + 2, NULL, 2);
|
||||
if (j >= 3 && buf[0] == '0' && (buf[1] == 'o' || buf[1] == 'O'))
|
||||
return (isize)strtoll(buf + 2, NULL, 8);
|
||||
return (isize)strtoll(buf, NULL, 0);
|
||||
return (isize)strtoull(buf + 2, NULL, 8);
|
||||
if (j >= 3 && buf[0] == '0' && (buf[1] == 'x' || buf[1] == 'X'))
|
||||
return (isize)strtoull(buf, NULL, 16);
|
||||
return (isize)strtoull(buf, NULL, 10);
|
||||
}
|
||||
|
||||
static double parse_float_literal(const spl_tok_t *t) {
|
||||
|
||||
+27
-1
@@ -630,6 +630,16 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case SPL_OP_BOOL_OR: {
|
||||
spl_ast_node_t *bmln = spl_ast_node(a->sema->ast, n->binary.left);
|
||||
spl_type_id_t op_tid = bmln ? node_ir(a, bmln) : 0;
|
||||
return spl_ir_builder_arith_or(a->ir, op_tid, l, r);
|
||||
}
|
||||
case SPL_OP_BOOL_AND: {
|
||||
spl_ast_node_t *bmln = spl_ast_node(a->sema->ast, n->binary.left);
|
||||
spl_type_id_t op_tid = bmln ? node_ir(a, bmln) : 0;
|
||||
return spl_ir_builder_arith_and(a->ir, op_tid, l, r);
|
||||
}
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -888,7 +898,23 @@ static spl_ir_node_ref_t emit_expr_raw(spl_ast2ir_t *a, spl_ast_node_ref_t ref)
|
||||
spl_lang_type_id_t usize_lang = spl_lang_make_int(a->sema->type, sizeof(void *) * 8, 0);
|
||||
spl_type_id_t usize_ir = to_ir_type(a, usize_lang);
|
||||
|
||||
spl_ir_node_ref_t base = emit_lvalue(a, n->slice.obj);
|
||||
/* base = 元素数据首地址 */
|
||||
spl_ir_node_ref_t base = 0;
|
||||
if (obj_kind == SPL_LANG_TYPE_PTR) {
|
||||
/* ptr 值本身就是首元素地址 */
|
||||
base = emit_expr(a, n->slice.obj);
|
||||
} else if (obj_kind == SPL_LANG_TYPE_SLICE) {
|
||||
/* 取 slice 的 ptr 字段 */
|
||||
spl_ir_node_ref_t slice_val = emit_expr(a, n->slice.obj);
|
||||
if (!slice_val)
|
||||
return 0;
|
||||
spl_type_id_t ptr_ir = spl_type_builder_ptr((spl_type_t *)a->sema->type, elem_ir);
|
||||
base = spl_ir_builder_agg_extract(a->ir, obj_ir, ptr_ir, SPL_SLICE_PTR_FIELD_IDX,
|
||||
slice_val);
|
||||
} else {
|
||||
/* ARRAY:&arr 即首元素地址 */
|
||||
base = emit_lvalue(a, n->slice.obj);
|
||||
}
|
||||
if (!base)
|
||||
return 0;
|
||||
|
||||
|
||||
+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;
|
||||
}
|
||||
|
||||
+25
-12
@@ -260,7 +260,12 @@ static inline void sema_push_scope(spl_sema_t *sema) {
|
||||
}
|
||||
|
||||
static inline void sema_pop_scope(spl_sema_t *sema) {
|
||||
sema->scope->current_scope = sema->store_scope;
|
||||
spl_scope_id_t cur = sema->scope->current_scope;
|
||||
if (cur != 0 && cur < vec_size(sema->scope->scopes)) {
|
||||
sema->scope->current_scope = vec_at(sema->scope->scopes, cur).parent;
|
||||
} else {
|
||||
sema->scope->current_scope = sema->store_scope;
|
||||
}
|
||||
}
|
||||
|
||||
static spl_lang_type_id_t sema_for_elem_type(spl_sema_t *sema, spl_lang_type_id_t lang_tid) {
|
||||
@@ -869,18 +874,23 @@ static spl_lang_type_id_t sema_coerce(spl_sema_t *sema, spl_ast_node_ref_t ref,
|
||||
}
|
||||
|
||||
case SPL_AST_EXPR_BLOCK: {
|
||||
sema_push_scope(sema);
|
||||
for (usize i = 0; i < vec_size(n->block.stmts); ++i)
|
||||
sema_infer(sema, vec_at(n->block.stmts, i));
|
||||
spl_lang_type_id_t r = 0;
|
||||
if (n->block.tail_expr) {
|
||||
spl_lang_type_id_t t = sema_coerce(sema, n->block.tail_expr, expected);
|
||||
if (!t)
|
||||
if (!t) {
|
||||
sema_pop_scope(sema);
|
||||
return 0;
|
||||
n->resolved_lang_tid = t;
|
||||
return t;
|
||||
}
|
||||
r = t;
|
||||
} else {
|
||||
r = spl_lang_make_unit(sema->type);
|
||||
}
|
||||
spl_lang_type_id_t u = spl_lang_make_unit(sema->type);
|
||||
n->resolved_lang_tid = u;
|
||||
return u;
|
||||
sema_pop_scope(sema);
|
||||
n->resolved_lang_tid = r;
|
||||
return r;
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -1218,11 +1228,12 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
if (!sema_coerce(sema, vec_at(n->call.args, i), pt))
|
||||
return 0;
|
||||
}
|
||||
/* varargs:默认提升到 isize */
|
||||
|
||||
if (has_varargs) {
|
||||
spl_lang_type_id_t vt = spl_lang_make_int(sema->type, sizeof(void *) * 8, 1);
|
||||
for (usize i = fixed; i < nargs; ++i)
|
||||
sema_coerce(sema, vec_at(n->call.args, i), vt);
|
||||
for (usize i = fixed; i < nargs; ++i) {
|
||||
if (!sema_infer(sema, vec_at(n->call.args, i)))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
spl_lang_type_id_t ret = fn->extra.fn.ret;
|
||||
@@ -1495,11 +1506,13 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
||||
|
||||
/* ---------- BLOCK ---------- */
|
||||
case SPL_AST_EXPR_BLOCK: {
|
||||
sema_push_scope(sema);
|
||||
spl_lang_type_id_t last = 0;
|
||||
for (usize i = 0; i < vec_size(n->block.stmts); ++i)
|
||||
last = sema_infer(sema, vec_at(n->block.stmts, i));
|
||||
sema_infer(sema, vec_at(n->block.stmts, i));
|
||||
if (n->block.tail_expr)
|
||||
last = sema_infer(sema, n->block.tail_expr);
|
||||
sema_pop_scope(sema);
|
||||
n->resolved_lang_tid = last;
|
||||
return last;
|
||||
}
|
||||
|
||||
+4
-9
@@ -575,20 +575,15 @@ bool spl_lang_mpa_int_fits(const spl_type_t *type, spl_lang_type_id_t target, sp
|
||||
if (bits == 0)
|
||||
return true;
|
||||
bool target_signed = ir->int_type.is_signed != 0;
|
||||
|
||||
int64_t val = (int64_t)v.bits;
|
||||
/* 字面量是无符号位模式:负号由 unary MINUS 承担 */
|
||||
uint64_t uval = v.bits;
|
||||
|
||||
if (target_signed) {
|
||||
if (bits >= 64)
|
||||
return true;
|
||||
int64_t lo = -((int64_t)1 << (bits - 1));
|
||||
int64_t hi = ((int64_t)1 << (bits - 1)) - 1;
|
||||
return val >= lo && val <= hi;
|
||||
uint64_t hi = ((uint64_t)1 << (bits - 1)) - 1;
|
||||
return uval <= hi;
|
||||
}
|
||||
|
||||
if (val < 0)
|
||||
return false;
|
||||
uint64_t uval = (uint64_t)val;
|
||||
if (bits >= 64)
|
||||
return true;
|
||||
uint64_t hi = ((uint64_t)1 << bits) - 1;
|
||||
|
||||
Reference in new issue
Block a user