Browse Source

factor out a call_func function

master
Martin Dørum 7 months ago
parent
commit
fe2b72ff69
1 changed files with 53 additions and 83 deletions
  1. 53
    83
      lib/vm/vm.c

+ 53
- 83
lib/vm/vm.c View File

@@ -284,6 +284,56 @@ void l2_vm_run(struct l2_vm *vm) {
}
}

// The 'call_func' function assumes that all relevant values have been popped off
// the stack, so that the return value can be pushed to the top of the stack
// straight away
static void call_func(
struct l2_vm *vm, l2_word func_id,
l2_word argc, l2_word *argv) {
l2_word stack_base = vm->sptr;

struct l2_vm_value *func = &vm->values[func_id];
enum l2_value_type typ = l2_vm_value_type(func);

// C functions are called differently from language functions
if (typ == L2_VAL_TYPE_CFUNCTION) {
vm->stack[vm->sptr++] = func->cfunc(vm, argc, argv);
return;
}

// Don't interpret a non-function as a function
if (typ != L2_VAL_TYPE_FUNCTION) {
vm->stack[vm->sptr++] = l2_vm_error(vm, "Attempt to call non-function");
return;
}

l2_word arr_id = alloc_val(vm);
vm->values[arr_id].flags = L2_VAL_TYPE_ARRAY;
vm->values[arr_id].array = malloc(
sizeof(struct l2_vm_array) + sizeof(l2_word) * argc);
struct l2_vm_array *arr = vm->values[arr_id].array;
arr->len = argc;
arr->size = argc;

for (l2_word i = 0; i < argc; ++i) {
arr->data[i] = argv[i];
}

vm->stack[vm->sptr++] = arr_id;

l2_word ns_id = alloc_val(vm);
func = &vm->values[func_id]; // func might be stale after alloc
vm->values[ns_id].extra.ns_parent = func->func.ns;
vm->values[ns_id].ns = NULL;
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;
}

void l2_vm_step(struct l2_vm *vm) {
enum l2_opcode opcode = (enum l2_opcode)vm->ops[vm->iptr++];

@@ -326,48 +376,7 @@ void l2_vm_step(struct l2_vm *vm) {
l2_word *argv = vm->stack + vm->sptr;

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
if (typ == L2_VAL_TYPE_CFUNCTION) {
vm->stack[vm->sptr++] = func->cfunc(vm, argc, argv);
break;
}

// Don't interpret a non-function as a function
if (typ != L2_VAL_TYPE_FUNCTION) {
vm->stack[vm->sptr++] = l2_vm_error(vm, "Attempt to call non-function");
break;
}

l2_word arr_id = alloc_val(vm);
vm->values[arr_id].flags = L2_VAL_TYPE_ARRAY;
vm->values[arr_id].array = malloc(
sizeof(struct l2_vm_array) + sizeof(l2_word) * argc);
struct l2_vm_array *arr = vm->values[arr_id].array;
arr->len = argc;
arr->size = argc;

for (l2_word i = 0; i < argc; ++i) {
arr->data[i] = argv[i];
}

vm->stack[vm->sptr++] = arr_id;

l2_word ns_id = alloc_val(vm);
func = &vm->values[func_id]; // func might be stale after alloc
vm->values[ns_id].extra.ns_parent = func->func.ns;
vm->values[ns_id].ns = NULL;
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;
call_func(vm, func_id, argc, argv);
}
break;

@@ -583,47 +592,8 @@ void l2_vm_step(struct l2_vm *vm) {
l2_word func_id = vm->stack[--vm->sptr];
l2_word lhs = 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
if (typ == L2_VAL_TYPE_CFUNCTION) {
l2_word argv[] = { lhs, rhs };
vm->stack[vm->sptr++] = func->cfunc(vm, 2, argv);
break;
}

// Don't interpret a non-function as a function
if (typ != L2_VAL_TYPE_FUNCTION) {
vm->stack[vm->sptr++] = l2_vm_error(vm, "Attempt to call non-function");
break;
}

l2_word arr_id = alloc_val(vm);
vm->values[arr_id].flags = L2_VAL_TYPE_ARRAY;
vm->values[arr_id].array = malloc(
sizeof(struct l2_vm_array) + sizeof(l2_word) * 2);
struct l2_vm_array *arr = vm->values[arr_id].array;
arr->len = 2;
arr->size = 2;
arr->data[0] = lhs;
arr->data[1] = rhs;

vm->stack[vm->sptr++] = arr_id;

l2_word ns_id = alloc_val(vm);
func = &vm->values[func_id]; // func might be stale after alloc
vm->values[ns_id].extra.ns_parent = func->func.ns;
vm->values[ns_id].ns = NULL;
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;
l2_word argv[] = {lhs, rhs};
call_func(vm, func_id, 2, argv);
}
break;


Loading…
Cancel
Save