stage1 支持函数指针
This commit is contained in:
1 parent
73c9a40abd
commit
70ac7380e9
4 files changed
+36
-1
No files matched your search
+3
-1
@@ -1917,7 +1917,9 @@ static spl_ir_node_ref_t emit_implicit_cast(spl_ast2ir_t *a, spl_ast_node_t *n,
|
|||||||
if (fs->kind == SPL_TYPE_BOOL && ts->kind == SPL_TYPE_INT)
|
if (fs->kind == SPL_TYPE_BOOL && ts->kind == SPL_TYPE_INT)
|
||||||
return spl_ir_builder_cast_bool2int(a->ir, ft, tt, v);
|
return spl_ir_builder_cast_bool2int(a->ir, ft, tt, v);
|
||||||
|
|
||||||
if (fs->kind == SPL_TYPE_PTR && ts->kind == SPL_TYPE_PTR)
|
bool fs_ptr_like = fs->kind == SPL_TYPE_PTR || fs->kind == SPL_TYPE_FN;
|
||||||
|
bool ts_ptr_like = ts->kind == SPL_TYPE_PTR || ts->kind == SPL_TYPE_FN;
|
||||||
|
if (fs_ptr_like && ts_ptr_like)
|
||||||
return v;
|
return v;
|
||||||
|
|
||||||
if (fs->kind == SPL_TYPE_PTR && ts->kind == SPL_TYPE_INT)
|
if (fs->kind == SPL_TYPE_PTR && ts->kind == SPL_TYPE_INT)
|
||||||
|
|||||||
@@ -1182,6 +1182,10 @@ int spl_ir2vm_run(spl_ir2vm_t *ctx) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 保留 insn 0 作为哨兵:确保真实函数入口地址非零,
|
||||||
|
从而 0 可唯一表示 null 函数指针(函数指针与 null 比较)。 */
|
||||||
|
spl_prog_add_instr(&ctx->prog, SPL_HALT, SPL_VOID, 0);
|
||||||
|
|
||||||
/* Pass 2:翻译非 extern 的函数 */
|
/* Pass 2:翻译非 extern 的函数 */
|
||||||
usize *fid_ip = calloc(n, sizeof(usize));
|
usize *fid_ip = calloc(n, sizeof(usize));
|
||||||
fix_vec_t all_fixups;
|
fix_vec_t all_fixups;
|
||||||
|
|||||||
@@ -482,6 +482,13 @@ bool spl_lang_type_is_subtype(const spl_lang_type_t *type, spl_lang_type_id_t su
|
|||||||
return ir_sub->float_type.bits == 0;
|
return ir_sub->float_type.bits == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* null(*never)可隐式转换为函数指针:函数值按指针布局,可空。 */
|
||||||
|
if (nsuper->kind == SPL_LANG_TYPE_FN && nsub->kind == SPL_LANG_TYPE_PTR) {
|
||||||
|
spl_lang_type_node_t *sub_elem = spl_lang_type_node(type, nsub->extra.elem);
|
||||||
|
if (sub_elem && sub_elem->kind == SPL_LANG_TYPE_NEVER)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (nsub->kind == SPL_LANG_TYPE_PTR && nsuper->kind == SPL_LANG_TYPE_PTR) {
|
if (nsub->kind == SPL_LANG_TYPE_PTR && nsuper->kind == SPL_LANG_TYPE_PTR) {
|
||||||
if (nsub->extra.elem == nsuper->extra.elem)
|
if (nsub->extra.elem == nsuper->extra.elem)
|
||||||
return true;
|
return true;
|
||||||
@@ -568,6 +575,18 @@ spl_lang_type_id_t spl_lang_type_join(const spl_lang_type_t *type, spl_lang_type
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 函数指针可空:fn 与 null(*never)求交得到 fn。 */
|
||||||
|
if (na->kind == SPL_LANG_TYPE_FN && nb->kind == SPL_LANG_TYPE_PTR) {
|
||||||
|
spl_lang_type_node_t *eb = spl_lang_type_node(type, nb->extra.elem);
|
||||||
|
if (eb && eb->kind == SPL_LANG_TYPE_NEVER)
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
if (na->kind == SPL_LANG_TYPE_PTR && nb->kind == SPL_LANG_TYPE_FN) {
|
||||||
|
spl_lang_type_node_t *ea = spl_lang_type_node(type, na->extra.elem);
|
||||||
|
if (ea && ea->kind == SPL_LANG_TYPE_NEVER)
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
if (na->kind == SPL_LANG_TYPE_PTR && nb->kind == SPL_LANG_TYPE_PTR) {
|
if (na->kind == SPL_LANG_TYPE_PTR && nb->kind == SPL_LANG_TYPE_PTR) {
|
||||||
if (na->extra.elem == nb->extra.elem)
|
if (na->extra.elem == nb->extra.elem)
|
||||||
return a;
|
return a;
|
||||||
|
|||||||
@@ -1775,6 +1775,16 @@ static spl_lang_type_id_t sema_infer(spl_sema_t *sema, spl_ast_node_ref_t ref) {
|
|||||||
return bt;
|
return bt;
|
||||||
}
|
}
|
||||||
case SPL_UNARY_OP_ADDRESS: {
|
case SPL_UNARY_OP_ADDRESS: {
|
||||||
|
spl_ast_node_t *operand = spl_ast_node(sema->ast, n->unary.operand);
|
||||||
|
if (operand && operand->kind == SPL_AST_EXPR_IDENT) {
|
||||||
|
spl_def_node_t *def = spl_def_node(sema->type, operand->resolved_def_id);
|
||||||
|
if (def && def->kind == SPL_DEF_FN) {
|
||||||
|
spl_diag_error(sema->diag, SPL_DIAG_KIND_TYPE_MISMATCH, &n->dbg,
|
||||||
|
"cannot take address of a function: the function name "
|
||||||
|
"itself is a function pointer");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
spl_lang_type_id_t p = spl_lang_make_ptr(sema->type, op);
|
spl_lang_type_id_t p = spl_lang_make_ptr(sema->type, op);
|
||||||
n->resolved_lang_tid = p;
|
n->resolved_lang_tid = p;
|
||||||
return p;
|
return p;
|
||||||
|
|||||||
Reference in new issue
Block a user