stage1 修复vm 提供简单参数检查 修复聚合类型bug
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user