stage1 修复类型体内部函数前向引用时 CALL 地址错误
This commit is contained in:
@@ -13,11 +13,13 @@ void spl_comp_init(spl_comp_t *ctx) {
|
||||
vec_init(ctx->toks);
|
||||
vec_init(ctx->scopes);
|
||||
vec_init(ctx->funcs);
|
||||
vec_init(ctx->ns_chain);
|
||||
map_init(ctx->type_defs, MAP_HASH_STR, MAP_CMP_STR);
|
||||
map_init(ctx->const_values, MAP_HASH_STR, MAP_CMP_STR);
|
||||
vec_init(ctx->call_fixups);
|
||||
vec_init(ctx->call_fixup_funcs);
|
||||
spl_prog_init(&ctx->prog);
|
||||
ctx->error_msg[0] = '\0';
|
||||
ctx->current_type_name = NULL;
|
||||
}
|
||||
|
||||
void spl_comp_drop(spl_comp_t *ctx) {
|
||||
@@ -27,9 +29,12 @@ void spl_comp_drop(spl_comp_t *ctx) {
|
||||
vec_for(ctx->scopes, i) { vec_free(vec_at(ctx->scopes, i).vars); }
|
||||
vec_free(ctx->scopes);
|
||||
vec_free(ctx->funcs);
|
||||
vec_free(ctx->ns_chain);
|
||||
/* Free type defs — complex, leak for now in bootstrap */
|
||||
map_free(ctx->type_defs);
|
||||
map_free(ctx->const_values);
|
||||
vec_free(ctx->call_fixups);
|
||||
vec_free(ctx->call_fixup_funcs);
|
||||
spl_prog_drop(&ctx->prog);
|
||||
free(ctx->break_patches);
|
||||
}
|
||||
@@ -41,6 +46,8 @@ void spl_comp_reset(spl_comp_t *ctx) {
|
||||
vec_for(ctx->scopes, i) { vec_free(vec_at(ctx->scopes, i).vars); }
|
||||
vec_free(ctx->scopes);
|
||||
vec_init(ctx->scopes);
|
||||
vec_free(ctx->ns_chain);
|
||||
vec_init(ctx->ns_chain);
|
||||
ctx->scope_depth = 0;
|
||||
ctx->tok_idx = 0;
|
||||
ctx->has_error = 0;
|
||||
@@ -56,9 +63,12 @@ void spl_comp_reset(spl_comp_t *ctx) {
|
||||
ctx->defer_count = 0;
|
||||
ctx->next_gdata_idx = 0;
|
||||
ctx->addr_of_mode = 0;
|
||||
ctx->current_type_name = NULL;
|
||||
free(ctx->break_patches);
|
||||
ctx->break_patches = NULL;
|
||||
vec_free(ctx->call_fixups);
|
||||
vec_init(ctx->call_fixups);
|
||||
vec_free(ctx->call_fixup_funcs);
|
||||
vec_init(ctx->call_fixup_funcs);
|
||||
}
|
||||
|
||||
void spl_comp_error(spl_comp_t *ctx, const char *fmt, ...) {
|
||||
@@ -164,6 +174,18 @@ void spl_pop_scope(spl_comp_t *ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Namespace chain management ---- */
|
||||
|
||||
void spl_ns_push(spl_comp_t *ctx, spl_type_info_t *type) {
|
||||
if (type)
|
||||
vec_push(ctx->ns_chain, type);
|
||||
}
|
||||
|
||||
void spl_ns_pop(spl_comp_t *ctx) {
|
||||
if (vec_size(ctx->ns_chain) > 0)
|
||||
ctx->ns_chain.size--;
|
||||
}
|
||||
|
||||
/* ---- Variable management ---- */
|
||||
|
||||
int spl_declare_var(spl_comp_t *ctx, const char *name, spl_type_info_t *type, int is_const) {
|
||||
@@ -214,6 +236,20 @@ int spl_get_var_offset(spl_comp_t *ctx, const char *name) {
|
||||
|
||||
int spl_declare_func(spl_comp_t *ctx, const char *name, spl_type_info_t *ret_type, int nparams,
|
||||
int is_extern, int is_pub) {
|
||||
/* Check if already declared — allows pre-registration */
|
||||
vec_for(ctx->funcs, i) {
|
||||
spl_func_info_t *existing = &vec_at(ctx->funcs, i);
|
||||
if (strcmp(existing->name, name) == 0) {
|
||||
existing->ret_type = ret_type;
|
||||
existing->nparams = nparams;
|
||||
existing->is_extern = is_extern;
|
||||
existing->is_pub = is_pub;
|
||||
existing->func_idx =
|
||||
spl_prog_update_func(&ctx->prog, existing->func_idx, name, nparams);
|
||||
return (int)i;
|
||||
}
|
||||
}
|
||||
|
||||
spl_func_info_t fi;
|
||||
memset(&fi, 0, sizeof(fi));
|
||||
fi.name = strdup(name);
|
||||
@@ -233,9 +269,19 @@ int spl_declare_func(spl_comp_t *ctx, const char *name, spl_type_info_t *ret_typ
|
||||
}
|
||||
|
||||
int spl_lookup_func(spl_comp_t *ctx, const char *name) {
|
||||
vec_for(ctx->funcs, i) {
|
||||
if (strcmp(vec_at(ctx->funcs, i).name, name) == 0)
|
||||
return (int)i;
|
||||
/* 1. Walk ns_chain from innermost to outermost, check each type's methods */
|
||||
for (usize i = vec_size(ctx->ns_chain); i > 0; i--) {
|
||||
spl_type_info_t *type = vec_at(ctx->ns_chain, i - 1);
|
||||
vec_for(type->methods, j) {
|
||||
if (strcmp(vec_at(type->methods, j).name, name) == 0)
|
||||
return vec_at(type->methods, j).func_idx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. Fallback to flat func table (top-level functions and qualified names) */
|
||||
vec_for(ctx->funcs, j) {
|
||||
if (strcmp(vec_at(ctx->funcs, j).name, name) == 0)
|
||||
return (int)j;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -340,6 +386,19 @@ void spl_comp_register(spl_prog_t *prog) {
|
||||
(void)prog;
|
||||
}
|
||||
|
||||
/* ---- Patch call fixups ---- */
|
||||
|
||||
void spl_patch_call_fixups(spl_comp_t *ctx) {
|
||||
for (usize i = 0; i < vec_size(ctx->call_fixups); i++) {
|
||||
spl_val_t insn_idx = vec_at(ctx->call_fixups, i);
|
||||
int pfi = vec_at(ctx->call_fixup_funcs, i);
|
||||
if (pfi >= 0 && pfi < (int)vec_size(ctx->prog.funcs)) {
|
||||
spl_val_t addr = vec_at(ctx->prog.funcs, pfi).address;
|
||||
vec_at(ctx->prog.insns, insn_idx).imm = addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Main compilation ---- */
|
||||
|
||||
int spl_compile(spl_comp_t *ctx, const char *source, const char *fname) {
|
||||
@@ -358,5 +417,9 @@ int spl_compile(spl_comp_t *ctx, const char *source, const char *fname) {
|
||||
spl_parse_prog(ctx);
|
||||
if (ctx->has_error)
|
||||
return -1;
|
||||
|
||||
/* Phase 5: Patch all function call fixups (forward references) */
|
||||
spl_patch_call_fixups(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user