@@ -78,8 +78,10 @@ enum l2_opcode { | |||
/* | |||
* Return from a function. | |||
* Pop <retval> | |||
* FSPop | |||
* Pop (discard args array) | |||
* Reset stack pointer to <stack base> | |||
* Push <retval> | |||
* Jump to <return address> | |||
*/ | |||
L2_OP_RET, |
@@ -77,6 +77,7 @@ struct l2_vm_namespace { | |||
struct l2_vm_stack_frame { | |||
l2_word ns; | |||
l2_word sptr; | |||
l2_word retptr; | |||
}; | |||
@@ -101,7 +101,8 @@ void l2_vm_print_stack(struct l2_vm *vm) { | |||
void l2_vm_print_fstack(struct l2_vm *vm) { | |||
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); | |||
} | |||
} | |||
@@ -261,6 +261,8 @@ void l2_vm_step(struct l2_vm *vm) { | |||
l2_word func_id = vm->stack[--vm->sptr]; | |||
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); | |||
// C functions are called differently from language functions | |||
@@ -284,6 +286,7 @@ void l2_vm_step(struct l2_vm *vm) { | |||
vm->values[ns_id].flags = L2_VAL_TYPE_NAMESPACE; | |||
vm->fstack[vm->fsptr].ns = ns_id; | |||
vm->fstack[vm->fsptr].retptr = vm->iptr; | |||
vm->fstack[vm->fsptr].sptr = stack_base; | |||
vm->fsptr += 1; | |||
vm->iptr = func->func.pos; | |||
@@ -323,8 +326,10 @@ void l2_vm_step(struct l2_vm *vm) { | |||
case L2_OP_RET: | |||
{ | |||
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->iptr = retptr; | |||
} |
@@ -13,7 +13,7 @@ static struct l2_vm vm; | |||
static struct l2_vm_value *var_lookup(const char *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]; | |||
} | |||