Browse Source

don't allocate arguments array for builtins

master
Martin Dørum 3 years ago
parent
commit
928f7cfc33
4 changed files with 50 additions and 41 deletions
  1. 1
    1
      include/lang2/vm/builtins.h
  2. 6
    1
      include/lang2/vm/vm.h
  3. 29
    26
      lib/vm/builtins.c
  4. 14
    13
      lib/vm/vm.c

+ 1
- 1
include/lang2/vm/builtins.h View File

@@ -1,6 +1,6 @@
#include "vm.h"

#define X(name, f) \
l2_word f(struct l2_vm *vm, struct l2_vm_array *args);
l2_word f(struct l2_vm *vm, l2_word argc, l2_word *argv);
#include "../builtins.x.h"
#undef X

+ 6
- 1
include/lang2/vm/vm.h View File

@@ -9,7 +9,12 @@

struct l2_vm;
struct l2_vm_array;
typedef l2_word (*l2_vm_cfunction)(struct l2_vm *vm, struct l2_vm_array *args);
struct l2_vm_args;
typedef l2_word (*l2_vm_cfunction)(struct l2_vm *vm, l2_word argc, l2_word *argv);

struct l2_vm_args {
l2_word argc;
};

enum l2_value_type {
L2_VAL_TYPE_NONE,

+ 29
- 26
lib/vm/builtins.c View File

@@ -54,19 +54,19 @@ static void print_val(struct l2_vm *vm, struct l2_io_writer *out, struct l2_vm_v
}
}

l2_word l2_builtin_add(struct l2_vm *vm, struct l2_vm_array *args) {
if (args->len < 1) {
l2_word l2_builtin_add(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 1) {
return 0;
}

struct l2_vm_value *val = &vm->values[args->data[0]];
struct l2_vm_value *val = &vm->values[argv[0]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val);
}

double sum = val->real;
for (size_t i = 1; i < args->len; ++i) {
val = &vm->values[args->data[i]];
for (l2_word i = 1; i < argc; ++i) {
val = &vm->values[argv[i]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val);
}
@@ -79,19 +79,19 @@ l2_word l2_builtin_add(struct l2_vm *vm, struct l2_vm_array *args) {
return id;
}

l2_word l2_builtin_sub(struct l2_vm *vm, struct l2_vm_array *args) {
if (args->len < 1) {
l2_word l2_builtin_sub(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 1) {
return 0;
}

struct l2_vm_value *val = &vm->values[args->data[0]];
struct l2_vm_value *val = &vm->values[argv[0]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val);
}

double sum = val->real;
for (size_t i = 1; i < args->len; ++i) {
val = &vm->values[args->data[i]];
for (l2_word i = 1; i < argc; ++i) {
val = &vm->values[argv[i]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val);
}
@@ -104,19 +104,19 @@ l2_word l2_builtin_sub(struct l2_vm *vm, struct l2_vm_array *args) {
return id;
}

l2_word l2_builtin_mul(struct l2_vm *vm, struct l2_vm_array *args) {
if (args->len < 1) {
l2_word l2_builtin_mul(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 1) {
return 0;
}

struct l2_vm_value *val = &vm->values[args->data[0]];
struct l2_vm_value *val = &vm->values[argv[0]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val);
}

double sum = val->real;
for (size_t i = 1; i < args->len; ++i) {
val = &vm->values[args->data[i]];
for (l2_word i = 1; i < argc; ++i) {
val = &vm->values[argv[i]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val);
}
@@ -129,19 +129,19 @@ l2_word l2_builtin_mul(struct l2_vm *vm, struct l2_vm_array *args) {
return id;
}

l2_word l2_builtin_div(struct l2_vm *vm, struct l2_vm_array *args) {
if (args->len < 1) {
l2_word l2_builtin_div(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 1) {
return 0;
}

struct l2_vm_value *val = &vm->values[args->data[0]];
struct l2_vm_value *val = &vm->values[argv[0]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val);
}

double sum = val->real;
for (size_t i = 1; i < args->len; ++i) {
val = &vm->values[args->data[i]];
for (l2_word i = 1; i < argc; ++i) {
val = &vm->values[argv[i]];
if (l2_vm_value_type(val) != L2_VAL_TYPE_REAL) {
return l2_vm_type_error(vm, val);
}
@@ -154,13 +154,13 @@ l2_word l2_builtin_div(struct l2_vm *vm, struct l2_vm_array *args) {
return id;
}

l2_word l2_builtin_print(struct l2_vm *vm, struct l2_vm_array *args) {
for (size_t i = 0; i < args->len; ++i) {
l2_word l2_builtin_print(struct l2_vm *vm, l2_word argc, l2_word *argv) {
for (size_t i = 0; i < argc; ++i) {
if (i != 0) {
vm->std_output->write(vm->std_output, " ", 1);
}

struct l2_vm_value *val = &vm->values[args->data[i]];
struct l2_vm_value *val = &vm->values[argv[i]];
print_val(vm, vm->std_output, val);
}

@@ -168,13 +168,16 @@ l2_word l2_builtin_print(struct l2_vm *vm, struct l2_vm_array *args) {
return 0;
}

l2_word l2_builtin_len(struct l2_vm *vm, struct l2_vm_array *args) {
// TODO: error if wrong argc
l2_word l2_builtin_len(struct l2_vm *vm, l2_word argc, l2_word *argv) {
if (argc < 1) {
return l2_vm_error(vm, "Expected at least 1 argument");
}

l2_word ret_id = l2_vm_alloc(vm, L2_VAL_TYPE_REAL, 0);
struct l2_vm_value *ret = &vm->values[ret_id];
ret->real = 0;

struct l2_vm_value *val = &vm->values[args->data[0]];
struct l2_vm_value *val = &vm->values[argv[0]];
switch (l2_vm_value_type(val)) {
case L2_VAL_TYPE_NONE:
case L2_VAL_TYPE_ATOM:

+ 14
- 13
lib/vm/vm.c View File

@@ -312,19 +312,8 @@ void l2_vm_step(struct l2_vm *vm) {
case L2_OP_FUNC_CALL:
{
l2_word argc = vm->ops[vm->iptr++];

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;

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

l2_word func_id = vm->stack[--vm->sptr];
struct l2_vm_value *func = &vm->values[func_id];
@@ -335,7 +324,7 @@ void l2_vm_step(struct l2_vm *vm) {

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

@@ -345,6 +334,18 @@ void l2_vm_step(struct l2_vm *vm) {
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);

Loading…
Cancel
Save