Skip to content

Commit

Permalink
wrap main vm in loop in macros as preparation for threaded code
Browse files Browse the repository at this point in the history
  • Loading branch information
Holodome committed Oct 18, 2023
1 parent b23d935 commit 0d8763f
Show file tree
Hide file tree
Showing 11 changed files with 91 additions and 59 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ build/%.o: hololisp/%.c
clean:
rm -rf build

format:
$(Q)find hololisp \( -name "*.c" -o -name "*.h" \) -exec clang-format -i {} \;

#
# Test rules
#
Expand Down
2 changes: 1 addition & 1 deletion hololisp/amalgamated.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "hll_builtins.c"
#include "hll_bytecode.c"
#include "hll_compiler.c"
#include "hll_gc.c"
#include "hll_mem.c"
#include "hll_meta.c"
#include "hll_value.c"
#include "hll_vm.c"
#include "hll_bytecode.c"
7 changes: 3 additions & 4 deletions hololisp/hll_bytecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -180,16 +180,15 @@ void dump_function_info(void *file, hll_value value) {
fprintf(file, "],"); // params

hll_bytecode *bc = func->bytecode;
fprintf(file,
"\"bytecode_stats\": { \"ops\": %zu, \"constants\": %zu}, ",
fprintf(file, "\"bytecode_stats\": { \"ops\": %zu, \"constants\": %zu}, ",
hll_sb_len(bc->ops), hll_sb_len(bc->constant_pool));

fprintf(file, "\"ops\": [");
const uint8_t *instruction = bc->ops;
hll_bytecode_op op;
while ((op = *instruction++)) {
fprintf(file, "{ \"offset\": %zu, \"op\": \"%s\"",
instruction - bc->ops, get_op_str(op));
fprintf(file, "{ \"offset\": %zu, \"op\": \"%s\"", instruction - bc->ops,
get_op_str(op));
switch (op) {
case HLL_BC_CONST:
case HLL_BC_MAKEFUN:
Expand Down
3 changes: 2 additions & 1 deletion hololisp/hll_bytecode.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,8 @@ typedef struct hll_bytecode {
// Constant pool dynamic array
hll_value *constant_pool;
uint32_t translation_unit;
// Name string object. It needs to be hololisp object because it comes from AST.
// Name string object. It needs to be hololisp object because it comes from
// AST.
hll_value name;
} hll_bytecode;

Expand Down
2 changes: 1 addition & 1 deletion hololisp/hll_compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ static inline hll_lexer_equivalence_class get_equivalence_class(char symb) {
default: break;
}
// clang-format on

return eqc;
}

Expand Down
1 change: 0 additions & 1 deletion hololisp/hll_mem.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,4 @@ void *hll_sb_grow_impl(void *arr, size_t inc, size_t stride);
void *hll_realloc(void *ptr, size_t old_size, size_t new_size)
__attribute__((alloc_size(3)));


#endif
3 changes: 1 addition & 2 deletions hololisp/hll_meta.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@ void hll_report_errorv(hll_meta_storage *debug, hll_loc loc, const char *fmt,
}
}

void hll_report_error(hll_meta_storage *vm, hll_loc loc, const char *fmt,
...) {
void hll_report_error(hll_meta_storage *vm, hll_loc loc, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
hll_report_errorv(vm, loc, fmt, args);
Expand Down
1 change: 0 additions & 1 deletion hololisp/hll_value.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,3 @@ size_t hll_list_length(hll_value value) {

return length;
}

14 changes: 10 additions & 4 deletions hololisp/hll_value.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
#ifndef HLL_VALUE_H
#define HLL_VALUE_H

#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <assert.h>
#include <string.h>

#include "hll_hololisp.h"
Expand Down Expand Up @@ -100,15 +100,21 @@ static inline hll_obj *nan_unbox_ptr(hll_value value) {
return (hll_obj *)(uintptr_t)(value & ~(HLL_SIGN_BIT | HLL_QNAN));
}

static inline hll_value hll_nil(void) { return nan_box_singleton(HLL_VALUE_NIL); }
static inline hll_value hll_true(void) { return nan_box_singleton(HLL_VALUE_TRUE); }
static inline hll_value hll_nil(void) {
return nan_box_singleton(HLL_VALUE_NIL);
}
static inline hll_value hll_true(void) {
return nan_box_singleton(HLL_VALUE_TRUE);
}
static inline hll_value hll_num(double num) {
hll_value value;
memcpy(&value, &num, sizeof(hll_value));
return value;
}

static inline bool hll_is_num(hll_value value) { return (value & HLL_QNAN) != HLL_QNAN; }
static inline bool hll_is_num(hll_value value) {
return (value & HLL_QNAN) != HLL_QNAN;
}
static inline bool hll_is_obj(hll_value value) {
return (((value) & (HLL_QNAN | HLL_SIGN_BIT)) == (HLL_QNAN | HLL_SIGN_BIT));
}
Expand Down
110 changes: 68 additions & 42 deletions hololisp/hll_vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,16 @@ static void call_func(hll_vm *vm, hll_value callable, hll_value args,
}
}

#ifndef HLL_USE_PRECOMPUTED_GOTO
#define HLL_VM_SWITCH() switch (*current_call_frame->ip++)
#define HLL_VM_CASE(_name) case _name:
#define HLL_VM_NEXT() \
do { \
goto vm_start; \
} while (0)
#else
#endif

hll_value hll_interpret_bytecode_internal(hll_vm *vm, hll_value env_,
hll_value compiled) {
// Setup setjump for error handling
Expand All @@ -277,35 +287,42 @@ hll_value hll_interpret_bytecode_internal(hll_vm *vm, hll_value env_,
}
hll_call_frame *current_call_frame = vm->call_stack;

while (hll_sb_len(vm->call_stack)) {
uint8_t op = *current_call_frame->ip++;
switch (op) {
case HLL_BC_END:
vm_start:
HLL_VM_SWITCH() {
HLL_VM_CASE(HLL_BC_END) {
assert(hll_sb_len(vm->stack) != 0);
vm->env = current_call_frame->env;
assert(vm->env);
(void)hll_sb_pop(vm->call_stack);
if (hll_sb_len(vm->call_stack) == 0) {
goto success;
}
current_call_frame = &hll_sb_last(vm->call_stack);
break;
case HLL_BC_POP:
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_POP) {
assert(hll_sb_len(vm->stack) != 0);
(void)hll_sb_pop(vm->stack);
break;
case HLL_BC_NIL:
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_NIL) {
hll_sb_push(vm->stack, hll_nil());
break;
case HLL_BC_TRUE:
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_TRUE) {
hll_sb_push(vm->stack, hll_true());
break;
case HLL_BC_CONST: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_CONST) {
uint16_t idx =
(current_call_frame->ip[0] << 8) | current_call_frame->ip[1];
current_call_frame->ip += 2;
assert(idx < hll_sb_len(current_call_frame->bytecode->constant_pool));
hll_value value = current_call_frame->bytecode->constant_pool[idx];
hll_sb_push(vm->stack, value);
} break;
case HLL_BC_APPEND: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_APPEND) {
assert(hll_sb_len(vm->stack) >= 3);
hll_value *headp = &hll_sb_last(vm->stack) + -2;
hll_value *tailp = &hll_sb_last(vm->stack) + -1;
Expand All @@ -326,8 +343,9 @@ hll_value hll_interpret_bytecode_internal(hll_vm *vm, hll_value env_,
*tailp = cons;
}
hll_gc_pop_temp_root(vm->gc); // obj
} break;
case HLL_BC_FIND: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_FIND) {
hll_value symb = hll_sb_pop(vm->stack);
hll_gc_push_temp_root(vm->gc, symb);
if (hll_get_value_kind(symb) != HLL_VALUE_SYMB) {
Expand All @@ -344,8 +362,9 @@ hll_value hll_interpret_bytecode_internal(hll_vm *vm, hll_value env_,
}
hll_gc_pop_temp_root(vm->gc); // symb
hll_sb_push(vm->stack, found);
} break;
case HLL_BC_MAKEFUN: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_MAKEFUN) {
uint16_t idx =
(current_call_frame->ip[0] << 8) | current_call_frame->ip[1];
current_call_frame->ip += 2;
Expand All @@ -358,8 +377,9 @@ hll_value hll_interpret_bytecode_internal(hll_vm *vm, hll_value env_,
hll_unwrap_func(value)->env = vm->env;

hll_sb_push(vm->stack, value);
} break;
case HLL_BC_MBTRCALL: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_MBTRCALL) {
hll_value args = hll_sb_pop(vm->stack);
hll_gc_push_temp_root(vm->gc, args);
hll_value callable = hll_sb_pop(vm->stack);
Expand All @@ -369,8 +389,9 @@ hll_value hll_interpret_bytecode_internal(hll_vm *vm, hll_value env_,

hll_gc_pop_temp_root(vm->gc); // args
hll_gc_pop_temp_root(vm->gc); // callable
} break;
case HLL_BC_CALL: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_CALL) {
hll_value args = hll_sb_pop(vm->stack);
hll_gc_push_temp_root(vm->gc, args);
hll_value callable = hll_sb_pop(vm->stack);
Expand All @@ -380,8 +401,9 @@ hll_value hll_interpret_bytecode_internal(hll_vm *vm, hll_value env_,

hll_gc_pop_temp_root(vm->gc); // args
hll_gc_pop_temp_root(vm->gc); // callable
} break;
case HLL_BC_JN: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_JN) {
uint16_t offset =
(current_call_frame->ip[0] << 8) | current_call_frame->ip[1];
current_call_frame->ip += 2;
Expand All @@ -395,58 +417,62 @@ hll_value hll_interpret_bytecode_internal(hll_vm *vm, hll_value env_,
&hll_sb_last(current_call_frame->bytecode->ops));
}
hll_gc_pop_temp_root(vm->gc);
} break;
case HLL_BC_LET: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_LET) {
assert(hll_sb_len(vm->stack) != 0);
hll_value value = hll_sb_pop(vm->stack);
hll_gc_push_temp_root(vm->gc, value);
hll_value name = hll_sb_last(vm->stack);
hll_add_variable(vm, vm->env, name, value);
hll_gc_pop_temp_root(vm->gc); // value
} break;
case HLL_BC_PUSHENV:
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_PUSHENV) {
vm->env = hll_new_env(vm, vm->env, hll_nil());
break;
case HLL_BC_POPENV:
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_POPENV) {
vm->env = hll_unwrap_env(vm->env)->up;
assert(vm->env);
assert(hll_get_value_kind(vm->env) == HLL_VALUE_ENV);
break;
case HLL_BC_CAR: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_CAR) {
assert(hll_sb_len(vm->stack) != 0);
hll_value cons = hll_sb_pop(vm->stack);
hll_gc_push_temp_root(vm->gc, cons);
hll_value car = hll_car(vm, cons);
hll_gc_pop_temp_root(vm->gc); // cons
hll_sb_push(vm->stack, car);
} break;
case HLL_BC_CDR: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_CDR) {
assert(hll_sb_len(vm->stack) != 0);
hll_value cons = hll_sb_pop(vm->stack);
hll_gc_push_temp_root(vm->gc, cons);
hll_value cdr = hll_cdr(vm, cons);
hll_gc_pop_temp_root(vm->gc); // cons
hll_sb_push(vm->stack, cdr);
} break;
case HLL_BC_SETCAR: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_SETCAR) {
assert(hll_sb_len(vm->stack) != 0);
hll_value car = hll_sb_pop(vm->stack);
hll_gc_push_temp_root(vm->gc, car);
hll_value cons = hll_sb_last(vm->stack);
hll_gc_pop_temp_root(vm->gc); // car
hll_unwrap_cons(cons)->car = car;
} break;
case HLL_BC_SETCDR: {
HLL_VM_NEXT();
}
HLL_VM_CASE(HLL_BC_SETCDR) {
assert(hll_sb_len(vm->stack) != 0);
hll_value cdr = hll_sb_pop(vm->stack);
hll_gc_push_temp_root(vm->gc, cdr);
hll_value cons = hll_sb_last(vm->stack);
hll_unwrap_cons(cons)->cdr = cdr;
hll_gc_pop_temp_root(vm->gc); // cdr
} break;
default:
HLL_UNREACHABLE;
break;
HLL_VM_NEXT();
}
}

Expand Down
4 changes: 2 additions & 2 deletions hololisp/hll_vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ HLL_PUB void hll_print_value(hll_vm *vm, hll_value obj);

HLL_PUB bool hll_find_var(hll_value env, hll_value car, hll_value *found);

__attribute__((format(printf, 2, 3)))
HLL_PUB void hll_runtime_error(hll_vm *vm, const char *fmt, ...);
__attribute__((format(printf, 2, 3))) HLL_PUB void
hll_runtime_error(hll_vm *vm, const char *fmt, ...);

HLL_PUB hll_value hll_interpret_bytecode_internal(hll_vm *vm, hll_value env_,
hll_value compiled);
Expand Down

0 comments on commit 0d8763f

Please sign in to comment.