stage1 修复vm 提供简单参数检查 修复聚合类型bug

This commit is contained in:
zzy
2026-07-14 22:30:19 +08:00
parent f7f71c5f52
commit ab63c8ed90
7 changed files with 367 additions and 32 deletions

View File

@@ -86,14 +86,49 @@ static int parse_fn_body(spl_comp_t *ctx, const char *fn_name, spl_type_info_t *
skip_nl(ctx);
}
spl_patch(ctx, alloc_addr, ctx->peak_local_bytes / (int)sizeof(spl_val_t) - nparams);
/* Compute physical param slot count (1 slot = 8 bytes).
* Multi-slot struct params occupy ceil(size/8) slots; scalar params occupy 1 each. */
int total_phys_slots = 0;
for (int i = 0; i < nparams; i++) {
usize psz = spl_type_size(ptypes[i]);
total_phys_slots += (int)((psz + sizeof(spl_val_t) - 1) / sizeof(spl_val_t));
}
/* Ensure ALLOC provides enough space for multi-slot return value
* pre-placed at fp[0..nslots-1] (above saved_sp). */
if (ret_type && !spl_type_is_scalar(ret_type) &&
spl_type_size(ret_type) > sizeof(spl_val_t)) {
usize min_bytes = spl_type_slot_count(ret_type) * sizeof(spl_val_t);
if ((usize)ctx->peak_local_bytes < min_bytes)
ctx->peak_local_bytes = (int)min_bytes;
}
spl_patch(ctx, alloc_addr,
ctx->peak_local_bytes / (int)sizeof(spl_val_t) - total_phys_slots);
expect(ctx, TOK_R_BRACE);
}
spl_emit_defer_epilogue(ctx, ctx->scope_depth);
spl_pop_scope(ctx);
spl_emit(ctx, SPL_RET, SPL_VOID, 0);
/* Store param_types for call-site type checking and multi-slot expansion */
{
spl_func_info_t *f = &vec_at(ctx->funcs, fi);
f->param_types = calloc(nparams, sizeof(spl_type_info_t *));
f->param_names = calloc(nparams, sizeof(char *));
for (int i = 0; i < nparams; i++) {
f->param_types[i] = ptypes[i];
f->param_names[i] = strdup(pnames[i]);
}
}
/* Epilogue return: for multi-slot returns, return address of fp[1]
* (fp[0] is a gap slot that absorbs the RET PUSH, data at fp[1..nslots]). */
if (ctx->current_ret_type && !spl_type_is_scalar(ctx->current_ret_type) &&
spl_type_size(ctx->current_ret_type) > sizeof(spl_val_t)) {
spl_emit(ctx, SPL_LADDR, SPL_PTR, (int)sizeof(spl_val_t));
spl_emit(ctx, SPL_RET, SPL_PTR, 0);
} else {
spl_emit(ctx, SPL_RET, SPL_VOID, 0);
}
spl_prog_end_func(&ctx->prog, fi);
ctx->current_func_idx = -1;
ctx->current_ret_type = NULL;
@@ -183,16 +218,6 @@ static void parse_method_decl(spl_comp_t *ctx, spl_type_info_t *container) {
int fi = parse_fn_body(ctx, qualified, ret_type, nparams, pnames, ptypes, 0);
{
spl_func_info_t *f = &vec_at(ctx->funcs, fi);
f->param_types = calloc(nparams, sizeof(spl_type_info_t *));
f->param_names = calloc(nparams, sizeof(char *));
for (int i = 0; i < nparams; i++) {
f->param_types[i] = ptypes[i];
f->param_names[i] = strdup(pnames[i]);
}
}
spl_type_add_method(container, mname, fi);
}