/* | /* | ||||
* Return from a function. | * Return from a function. | ||||
* Pop <retval> | |||||
* FSPop | * FSPop | ||||
* Pop (discard args array) | |||||
* Reset stack pointer to <stack base> | |||||
* Push <retval> | |||||
* Jump to <return address> | * Jump to <return address> | ||||
*/ | */ | ||||
L2_OP_RET, | L2_OP_RET, |
struct l2_vm_stack_frame { | struct l2_vm_stack_frame { | ||||
l2_word ns; | l2_word ns; | ||||
l2_word sptr; | |||||
l2_word retptr; | l2_word retptr; | ||||
}; | }; | ||||
void l2_vm_print_fstack(struct l2_vm *vm) { | void l2_vm_print_fstack(struct l2_vm *vm) { | ||||
for (l2_word i = 0; i < vm->fsptr; ++i) { | for (l2_word i = 0; i < vm->fsptr; ++i) { | ||||
printf(" %i: %i, ret %i\n", i, vm->fstack[i].ns, vm->fstack[i].retptr); | |||||
printf(" %i: %i, ret %i, stack base %i\n", | |||||
i, vm->fstack[i].ns, vm->fstack[i].retptr, vm->fstack[i].sptr); | |||||
} | } | ||||
} | } | ||||
l2_word func_id = vm->stack[--vm->sptr]; | l2_word func_id = vm->stack[--vm->sptr]; | ||||
struct l2_vm_value *func = &vm->values[func_id]; | struct l2_vm_value *func = &vm->values[func_id]; | ||||
l2_word stack_base = vm->sptr; | |||||
enum l2_value_type typ = l2_vm_value_type(func); | enum l2_value_type typ = l2_vm_value_type(func); | ||||
// C functions are called differently from language functions | // C functions are called differently from language functions | ||||
vm->values[ns_id].flags = L2_VAL_TYPE_NAMESPACE; | vm->values[ns_id].flags = L2_VAL_TYPE_NAMESPACE; | ||||
vm->fstack[vm->fsptr].ns = ns_id; | vm->fstack[vm->fsptr].ns = ns_id; | ||||
vm->fstack[vm->fsptr].retptr = vm->iptr; | vm->fstack[vm->fsptr].retptr = vm->iptr; | ||||
vm->fstack[vm->fsptr].sptr = stack_base; | |||||
vm->fsptr += 1; | vm->fsptr += 1; | ||||
vm->iptr = func->func.pos; | vm->iptr = func->func.pos; | ||||
case L2_OP_RET: | case L2_OP_RET: | ||||
{ | { | ||||
l2_word retval = vm->stack[--vm->sptr]; | l2_word retval = vm->stack[--vm->sptr]; | ||||
vm->sptr -= 1; // Discard arguments array | |||||
l2_word retptr = vm->fstack[--vm->fsptr].retptr; | |||||
l2_word retptr = vm->fstack[vm->fsptr - 1].retptr; | |||||
l2_word sptr = vm->fstack[vm->fsptr - 1].sptr; | |||||
vm->fsptr -= 1; | |||||
vm->sptr = sptr; | |||||
vm->stack[vm->sptr++] = retval; | vm->stack[vm->sptr++] = retval; | ||||
vm->iptr = retptr; | vm->iptr = retptr; | ||||
} | } |
static struct l2_vm_value *var_lookup(const char *name) { | static struct l2_vm_value *var_lookup(const char *name) { | ||||
l2_word atom_id = l2_strset_get(&gen.atomset, name); | l2_word atom_id = l2_strset_get(&gen.atomset, name); | ||||
l2_word id = l2_vm_namespace_get(&vm, &vm.values[vm.fstack[1].namespace], atom_id); | |||||
l2_word id = l2_vm_namespace_get(&vm, &vm.values[vm.fstack[1].ns], atom_id); | |||||
return &vm.values[id]; | return &vm.values[id]; | ||||
} | } | ||||