| @@ -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]; | |||
| } | |||