stage1 修复vm 提供简单参数检查 修复聚合类型bug
This commit is contained in:
@@ -107,7 +107,7 @@ void spl_patch_to_here(spl_comp_t *ctx, spl_val_t addr) {
|
||||
spl_patch(ctx, addr, offset);
|
||||
}
|
||||
|
||||
/* ---- Multi-slot copy helper ---- */
|
||||
/* ---- Multi-slot copy helpers ---- */
|
||||
|
||||
void spl_emit_copy_slots(spl_comp_t *ctx, int dest_offset, usize nslots) {
|
||||
for (usize i = 0; i < nslots; i++) {
|
||||
@@ -124,6 +124,31 @@ void spl_emit_copy_slots(spl_comp_t *ctx, int dest_offset, usize nslots) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy nslots from source address to destination address.
|
||||
* Stack before: [..., depth_items..., dest_addr, src_addr] (src TOS)
|
||||
* Stack after: [..., depth_items...]
|
||||
* depth: number of items below dest_addr that must be preserved (e.g. 1 if
|
||||
* there's a base pointer between the rest of the stack and dest_addr). */
|
||||
void spl_emit_copy_addr_to_addr(spl_comp_t *ctx, usize nslots, int depth) {
|
||||
for (usize i = 0; i < nslots; i++) {
|
||||
spl_emit(ctx, SPL_DUP, SPL_VOID, 0);
|
||||
if (i > 0) {
|
||||
spl_emit(ctx, SPL_PUSH, SPL_USIZE, i * sizeof(spl_val_t));
|
||||
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
|
||||
}
|
||||
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0);
|
||||
spl_emit(ctx, SPL_PICK, SPL_VOID, 2 + depth);
|
||||
if (i > 0) {
|
||||
spl_emit(ctx, SPL_PUSH, SPL_USIZE, i * sizeof(spl_val_t));
|
||||
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
|
||||
}
|
||||
spl_emit(ctx, SPL_SWAP, SPL_VOID, 0);
|
||||
spl_emit(ctx, SPL_STORE, SPL_PTR, 0);
|
||||
}
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0);
|
||||
spl_emit(ctx, SPL_DROP, SPL_VOID, 0);
|
||||
}
|
||||
|
||||
/* ---- Uniform LOAD/STORE type helper ---- */
|
||||
|
||||
spl_type_t spl_type_emit_type(spl_type_info_t *type) {
|
||||
@@ -165,17 +190,22 @@ int spl_type_is_scalar(spl_type_info_t *type) {
|
||||
|
||||
void spl_emit_load_to_var(spl_comp_t *ctx, int ptr_slot_offset, usize byte_offset,
|
||||
spl_type_info_t *data_type, int var_offset) {
|
||||
spl_type_t bt = spl_type_emit_type(data_type);
|
||||
spl_emit(ctx, SPL_LADDR, SPL_PTR, ptr_slot_offset);
|
||||
spl_emit(ctx, SPL_LOAD, SPL_PTR, 0);
|
||||
if (byte_offset > 0) {
|
||||
spl_emit(ctx, SPL_PUSH, SPL_USIZE, byte_offset);
|
||||
spl_emit(ctx, SPL_ADD, SPL_USIZE, 0);
|
||||
}
|
||||
spl_emit(ctx, SPL_LOAD, bt, 0);
|
||||
spl_emit(ctx, SPL_LADDR, SPL_PTR, var_offset);
|
||||
spl_emit(ctx, SPL_SWAP, SPL_VOID, 0);
|
||||
spl_emit(ctx, SPL_STORE, bt, 0);
|
||||
if (data_type && !spl_type_is_scalar(data_type) &&
|
||||
spl_type_size(data_type) > sizeof(spl_val_t)) {
|
||||
spl_emit_copy_slots(ctx, var_offset, spl_type_slot_count(data_type));
|
||||
} else {
|
||||
spl_type_t bt = spl_type_emit_type(data_type);
|
||||
spl_emit(ctx, SPL_LOAD, bt, 0);
|
||||
spl_emit(ctx, SPL_LADDR, SPL_PTR, var_offset);
|
||||
spl_emit(ctx, SPL_SWAP, SPL_VOID, 0);
|
||||
spl_emit(ctx, SPL_STORE, bt, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---- Scope management ---- */
|
||||
|
||||
Reference in New Issue
Block a user