diff --git a/README.md b/README.md index 935bdc3..ec62304 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ Usage: ```bash # Compile an Unlambda source file into bytecode. u6ac -o foo.unl.bc foo.unl -# execute the bytecode file. +# Execute the bytecode file. u6a foo.unl.bc ``` diff --git a/configure.ac b/configure.ac index be0329d..067021e 100644 --- a/configure.ac +++ b/configure.ac @@ -9,11 +9,11 @@ dnl Check for operating system AC_CANONICAL_HOST case "${host_os}" in linux*) - AC_SUBST([MANPATH_CONF], [/etc/manpath.config]) + AC_SUBST([MANPATH_CONF], [/etc/manpath.config]) AC_SUBST([REBUILD_MANDB], [mandb]) ;; darwin*) - AC_SUBST([MANPATH_CONF], [/private/etc/man.conf]) + AC_SUBST([MANPATH_CONF], [/private/etc/man.conf]) AC_SUBST([REBUILD_MANDB], [/usr/libexec/makewhatis]) ;; *) diff --git a/src/runtime.c b/src/runtime.c index c585de1..f8a8ad8 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -80,10 +80,6 @@ static const char* info_runtime = "runtime"; goto runtime_error; \ } -#define POOL_GET1(offset) \ - u6a_vm_pool_get1(offset).fn; \ - u6a_vm_pool_free(offset) - static inline bool read_bc_header(struct u6a_bc_header* restrict header, FILE* restrict input_stream) { int ch; @@ -105,11 +101,12 @@ read_bc_header(struct u6a_bc_header* restrict header, FILE* restrict input_strea return true; } -static inline void +static inline struct u6a_vm_var_fn vm_var_fn_addref(struct u6a_vm_var_fn var) { if (var.token.fn & U6A_VM_FN_REF) { u6a_vm_pool_addref(var.ref); } + return var; } static inline void @@ -223,44 +220,38 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) { ACC_FN_REF(u6a_vf_s1, u6a_vm_pool_alloc1(arg)); break; case u6a_vf_s1: - ACC_FN_REF(u6a_vf_s2, u6a_vm_pool_fill2(func.ref, arg)); + ACC_FN_REF(u6a_vf_s2, u6a_vm_pool_alloc2(u6a_vm_pool_get1(func.ref).fn, arg)); break; case u6a_vf_s2: - if (ins++ - text == 0x03) { + if (ins - text == 0x03) { STACK_PUSH3(arg, u6a_vm_pool_get2(func.ref)); } else { STACK_PUSH4(U6A_VM_VAR_FN_REF(u6a_vf_j, ins - text), arg, u6a_vm_pool_get2(func.ref)); } - vm_var_fn_addref(arg); + acc = vm_var_fn_addref(arg); ins = text; continue; case u6a_vf_k: ACC_FN_REF(u6a_vf_k1, u6a_vm_pool_alloc1(arg)); break; case u6a_vf_k1: - vm_var_fn_free(arg); - acc = POOL_GET1(func.ref); + acc = u6a_vm_pool_get1(func.ref).fn; break; case u6a_vf_i: acc = arg; break; case u6a_vf_out: acc = arg; - // May fail to print, but we don't care fputc(func.token.ch, ostream); break; case u6a_vf_j: acc = arg; ins = text + func.ref; - continue; + break; case u6a_vf_f: // Safe to assign IP here before jumping, as func won't be `j` or `f` ins = text + func.ref; func = acc; - // The `s2` function incremenets IP before pushing `j`, so decrement IP here - if (func.token.fn == u6a_vf_s2) { - --ins; - } arg = STACK_POP(); goto do_apply; case u6a_vf_c: @@ -281,7 +272,7 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) { acc = arg; break; case u6a_vf_d1_c: - func = POOL_GET1(func.ref); + func = u6a_vm_pool_get1(func.ref).fn; goto do_apply; case u6a_vf_d1_s: tuple = u6a_vm_pool_get2(func.ref); @@ -295,8 +286,8 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) { ins = text + func.ref; continue; case u6a_vf_v: - vm_var_fn_free(arg); acc.token.fn = u6a_vf_v; + vm_var_fn_free(arg); break; case u6a_vf_p: acc = arg; @@ -334,7 +325,7 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) { STACK_PUSH1(acc); break; case u6a_vo_xch: - if (acc.token.fn == u6a_vf_d) { + if (UNLIKELY(acc.token.fn == u6a_vf_d)) { func = STACK_POP(); arg = STACK_POP(); ACC_FN_REF(u6a_vf_d1_s, u6a_vm_pool_alloc2(func, arg)); diff --git a/src/vm_pool.c b/src/vm_pool.c index 5c6bcce..6d192d5 100644 --- a/src/vm_pool.c +++ b/src/vm_pool.c @@ -46,7 +46,6 @@ static struct vm_pool* active_pool; static struct vm_pool_elem_ptrs* holes; static uint32_t pool_len; static struct vm_pool_elem** fstack; -static uint32_t fstack_len; static uint32_t fstack_top; const char* err_stage; @@ -78,9 +77,9 @@ vm_pool_elem_dup(struct vm_pool_elem* elem) { } static inline void -free_stack_push(union u6a_vm_var var) { - if (var.fn.token.fn & U6A_VM_FN_REF) { - fstack[++fstack_top] = active_pool->elems + var.fn.ref; +free_stack_push(struct u6a_vm_var_fn fn) { + if (fn.token.fn & U6A_VM_FN_REF) { + fstack[++fstack_top] = active_pool->elems + fn.ref; } } @@ -118,7 +117,6 @@ u6a_vm_pool_init(uint32_t pool_len_, uint32_t ins_len, const char* err_stage_) { active_pool->pos = UINT32_MAX; holes->pos = UINT32_MAX; pool_len = pool_len_; - fstack_len = ins_len; err_stage = err_stage_; return true; } @@ -130,28 +128,11 @@ u6a_vm_pool_alloc1(struct u6a_vm_var_fn v1) { return UINT32_MAX; } elem->values.v1.fn = v1; + elem->values.v2.fn.token.fn = ~U6A_VM_FN_REF; elem->flags = 0; return elem - active_pool->elems; } -U6A_HOT uint32_t -u6a_vm_pool_fill2(uint32_t offset, struct u6a_vm_var_fn v2) { - struct vm_pool_elem* elem = active_pool->elems + offset; - if (elem->refcnt == 1) { - elem->values.v2.fn = v2; - elem->flags = 0; - return offset; - } else { - elem = vm_pool_elem_dup(elem); - if (UNLIKELY(elem == NULL)) { - return UINT32_MAX; - } - elem->values.v2.fn = v2; - elem->flags = 0; - return elem - active_pool->elems; - } -} - U6A_HOT uint32_t u6a_vm_pool_alloc2(struct u6a_vm_var_fn v1, struct u6a_vm_var_fn v2) { struct vm_pool_elem* elem = vm_pool_elem_alloc(); @@ -176,12 +157,12 @@ u6a_vm_pool_alloc2_ptr(void* v1, void* v2) { U6A_HOT union u6a_vm_var u6a_vm_pool_get1(uint32_t offset) { - return (active_pool->elems + offset)->values.v1; + return active_pool->elems[offset].values.v1; } U6A_HOT struct u6a_vm_var_tuple u6a_vm_pool_get2(uint32_t offset) { - return (active_pool->elems + offset)->values; + return active_pool->elems[offset].values; } U6A_HOT struct u6a_vm_var_tuple @@ -202,7 +183,7 @@ u6a_vm_pool_addref(uint32_t offset) { U6A_HOT void u6a_vm_pool_free(uint32_t offset) { - struct vm_pool_elem* elem = active_pool->elems; + struct vm_pool_elem* elem = active_pool->elems + offset; fstack_top = UINT32_MAX; do { if (--elem->refcnt == 0) { @@ -211,8 +192,8 @@ u6a_vm_pool_free(uint32_t offset) { // Continuation destroyed before used u6a_vm_stack_discard(elem->values.v1.ptr); } else { - free_stack_push(elem->values.v1); - free_stack_push(elem->values.v2); + free_stack_push(elem->values.v1.fn); + free_stack_push(elem->values.v2.fn); } } } while ((elem = free_stack_pop())); diff --git a/src/vm_pool.h b/src/vm_pool.h index a7d66db..881ee2b 100644 --- a/src/vm_pool.h +++ b/src/vm_pool.h @@ -32,9 +32,6 @@ u6a_vm_pool_init(uint32_t pool_len, uint32_t ins_len, const char* err_stage); uint32_t u6a_vm_pool_alloc1(struct u6a_vm_var_fn v1); -uint32_t -u6a_vm_pool_fill2(uint32_t offset, struct u6a_vm_var_fn v2); - uint32_t u6a_vm_pool_alloc2(struct u6a_vm_var_fn v1, struct u6a_vm_var_fn v2); diff --git a/src/vm_stack.c b/src/vm_stack.c index 78ecff1..e77b5a5 100644 --- a/src/vm_stack.c +++ b/src/vm_stack.c @@ -95,9 +95,9 @@ vm_stack_free(struct vm_stack* vs) { bool u6a_vm_stack_init(uint32_t stack_seg_len_, const char* err_stage_) { - active_stack = vm_stack_create(NULL, UINT32_MAX); stack_seg_len = stack_seg_len_; err_stage = err_stage_; + active_stack = vm_stack_create(NULL, UINT32_MAX); return active_stack != NULL; } @@ -222,9 +222,9 @@ u6a_vm_stack_pop() { struct u6a_vm_var_fn u6a_vm_stack_xch(struct u6a_vm_var_fn v0) { struct vm_stack* vs = active_stack; - struct u6a_vm_var_fn top = vs->elems[vs->top - 1]; + struct u6a_vm_var_fn elem = vs->elems[vs->top - 1]; vs->elems[vs->top - 1] = v0; - return top; + return elem; } void*