fix bugs
This commit is contained in:
parent
9bbf4a3ec0
commit
f0d9df747a
|
@ -83,9 +83,6 @@ static const char* info_runtime = "runtime";
|
||||||
#define POOL_GET1(offset) \
|
#define POOL_GET1(offset) \
|
||||||
u6a_vm_pool_get1(offset).fn; \
|
u6a_vm_pool_get1(offset).fn; \
|
||||||
u6a_vm_pool_free(offset)
|
u6a_vm_pool_free(offset)
|
||||||
#define POOL_GET2(offset) \
|
|
||||||
u6a_vm_pool_get2(offset); \
|
|
||||||
u6a_vm_pool_free(offset)
|
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
read_bc_header(struct u6a_bc_header* restrict header, FILE* restrict input_stream) {
|
read_bc_header(struct u6a_bc_header* restrict header, FILE* restrict input_stream) {
|
||||||
|
@ -108,6 +105,13 @@ read_bc_header(struct u6a_bc_header* restrict header, FILE* restrict input_strea
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
vm_var_fn_addref(struct u6a_vm_var_fn var) {
|
||||||
|
if (var.token.fn & U6A_VM_FN_REF) {
|
||||||
|
u6a_vm_pool_addref(var.ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
vm_var_fn_free(struct u6a_vm_var_fn var) {
|
vm_var_fn_free(struct u6a_vm_var_fn var) {
|
||||||
if (var.token.fn & U6A_VM_FN_REF) {
|
if (var.token.fn & U6A_VM_FN_REF) {
|
||||||
|
@ -221,16 +225,15 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
|
||||||
case u6a_vf_s1:
|
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_fill2(func.ref, arg));
|
||||||
break;
|
break;
|
||||||
ACC_FN_REF(u6a_vf_d1_c, u6a_vm_pool_alloc1(arg));
|
|
||||||
case u6a_vf_s2:
|
case u6a_vf_s2:
|
||||||
if (ins++ - text == 0x03) {
|
if (ins++ - text == 0x03) {
|
||||||
STACK_PUSH3(arg, u6a_vm_pool_get2(func.ref));
|
STACK_PUSH3(arg, u6a_vm_pool_get2(func.ref));
|
||||||
} else {
|
} else {
|
||||||
STACK_PUSH4(U6A_VM_VAR_FN_REF(u6a_vf_j, ins - text), arg, u6a_vm_pool_get2(func.ref));
|
STACK_PUSH4(U6A_VM_VAR_FN_REF(u6a_vf_j, ins - text), arg, u6a_vm_pool_get2(func.ref));
|
||||||
}
|
}
|
||||||
u6a_vm_pool_free(func.ref);
|
vm_var_fn_addref(arg);
|
||||||
ins = text;
|
ins = text;
|
||||||
goto do_apply;
|
continue;
|
||||||
case u6a_vf_k:
|
case u6a_vf_k:
|
||||||
ACC_FN_REF(u6a_vf_k1, u6a_vm_pool_alloc1(arg));
|
ACC_FN_REF(u6a_vf_k1, u6a_vm_pool_alloc1(arg));
|
||||||
break;
|
break;
|
||||||
|
@ -271,8 +274,9 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
|
||||||
ACC_FN_REF(u6a_vf_d1_c, u6a_vm_pool_alloc1(arg));
|
ACC_FN_REF(u6a_vf_d1_c, u6a_vm_pool_alloc1(arg));
|
||||||
break;
|
break;
|
||||||
case u6a_vf_c1:
|
case u6a_vf_c1:
|
||||||
tuple = POOL_GET2(func.ref);
|
tuple = u6a_vm_pool_get2_separate(func.ref);
|
||||||
u6a_vm_stack_resume(tuple.v1.ptr);
|
u6a_vm_stack_resume(tuple.v1.ptr);
|
||||||
|
u6a_vm_pool_free(func.ref);
|
||||||
ins = tuple.v2.ptr;
|
ins = tuple.v2.ptr;
|
||||||
acc = arg;
|
acc = arg;
|
||||||
break;
|
break;
|
||||||
|
@ -280,7 +284,8 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
|
||||||
func = POOL_GET1(func.ref);
|
func = POOL_GET1(func.ref);
|
||||||
goto do_apply;
|
goto do_apply;
|
||||||
case u6a_vf_d1_s:
|
case u6a_vf_d1_s:
|
||||||
tuple = POOL_GET2(func.ref);
|
tuple = u6a_vm_pool_get2(func.ref);
|
||||||
|
u6a_vm_pool_free(func.ref);
|
||||||
STACK_PUSH1(tuple.v1.fn);
|
STACK_PUSH1(tuple.v1.fn);
|
||||||
acc = tuple.v2.fn;
|
acc = tuple.v2.fn;
|
||||||
ins = text + 0x03;
|
ins = text + 0x03;
|
||||||
|
@ -310,7 +315,7 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
|
||||||
case u6a_vf_pipe:
|
case u6a_vf_pipe:
|
||||||
func = arg;
|
func = arg;
|
||||||
if (UNLIKELY(current_char == EOF)) {
|
if (UNLIKELY(current_char == EOF)) {
|
||||||
arg.token.fn = u6a_vf_v;acc = u6a_vm_stack_xch(acc);
|
arg.token.fn = u6a_vf_v;
|
||||||
} else {
|
} else {
|
||||||
arg.token = U6A_TOKEN(u6a_vf_out, current_char);
|
arg.token = U6A_TOKEN(u6a_vf_out, current_char);
|
||||||
}
|
}
|
||||||
|
@ -339,7 +344,7 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
|
||||||
break;
|
break;
|
||||||
case u6a_vo_del:
|
case u6a_vo_del:
|
||||||
delay:
|
delay:
|
||||||
STACK_PUSH1(U6A_VM_VAR_FN_REF(u6a_vf_d1_d, ins + 1 - text));
|
acc = U6A_VM_VAR_FN_REF(u6a_vf_d1_d, ins + 1 - text);
|
||||||
ins = text + text_subst_len + ins->operand.offset;
|
ins = text + text_subst_len + ins->operand.offset;
|
||||||
continue;
|
continue;
|
||||||
case u6a_vo_lc:
|
case u6a_vo_lc:
|
||||||
|
|
|
@ -85,7 +85,7 @@ free_stack_pop() {
|
||||||
if (fstack_top == UINT32_MAX) {
|
if (fstack_top == UINT32_MAX) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return fstack[--fstack_top];
|
return fstack[fstack_top--];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -176,6 +176,22 @@ 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
|
||||||
|
u6a_vm_pool_get2_separate(uint32_t offset) {
|
||||||
|
struct vm_pool_elem* elem = active_pool->elems + offset;
|
||||||
|
struct u6a_vm_var_tuple values = elem->values;
|
||||||
|
if (elem->refcnt > 1) {
|
||||||
|
// Continuation having more than 1 reference should be separated before reinstatement
|
||||||
|
values.v1.ptr = u6a_vm_stack_dup(values.v1.ptr);
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
U6A_HOT void
|
||||||
|
u6a_vm_pool_addref(uint32_t offset) {
|
||||||
|
++active_pool->elems[offset].refcnt;
|
||||||
|
}
|
||||||
|
|
||||||
U6A_HOT void
|
U6A_HOT void
|
||||||
u6a_vm_pool_free(uint32_t offset) {
|
u6a_vm_pool_free(uint32_t offset) {
|
||||||
struct vm_pool_elem* elem = active_pool->elems;
|
struct vm_pool_elem* elem = active_pool->elems;
|
||||||
|
|
|
@ -47,6 +47,12 @@ u6a_vm_pool_get1(uint32_t offset);
|
||||||
struct u6a_vm_var_tuple
|
struct u6a_vm_var_tuple
|
||||||
u6a_vm_pool_get2(uint32_t offset);
|
u6a_vm_pool_get2(uint32_t offset);
|
||||||
|
|
||||||
|
struct u6a_vm_var_tuple
|
||||||
|
u6a_vm_pool_get2_separate(uint32_t offset);
|
||||||
|
|
||||||
|
void
|
||||||
|
u6a_vm_pool_addref(uint32_t offset);
|
||||||
|
|
||||||
void
|
void
|
||||||
u6a_vm_pool_free(uint32_t offset);
|
u6a_vm_pool_free(uint32_t offset);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "vm_stack.h"
|
#include "vm_stack.h"
|
||||||
|
#include "vm_pool.h"
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
@ -47,8 +48,7 @@ vm_stack_create(struct vm_stack* prev, uint32_t top) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct vm_stack*
|
static inline struct vm_stack*
|
||||||
vm_stack_dup() {
|
vm_stack_dup(struct vm_stack* vs) {
|
||||||
struct vm_stack* vs = active_stack;
|
|
||||||
const uint32_t size = sizeof(struct vm_stack) + stack_seg_len * sizeof(struct u6a_vm_var_fn);
|
const uint32_t size = sizeof(struct vm_stack) + stack_seg_len * sizeof(struct u6a_vm_var_fn);
|
||||||
struct vm_stack* dup_stack = malloc(size);
|
struct vm_stack* dup_stack = malloc(size);
|
||||||
if (UNLIKELY(dup_stack == NULL)) {
|
if (UNLIKELY(dup_stack == NULL)) {
|
||||||
|
@ -56,6 +56,15 @@ vm_stack_dup() {
|
||||||
}
|
}
|
||||||
memcpy(dup_stack, vs, sizeof(struct vm_stack) + (vs->top + 1) * sizeof(struct u6a_vm_var_fn));
|
memcpy(dup_stack, vs, sizeof(struct vm_stack) + (vs->top + 1) * sizeof(struct u6a_vm_var_fn));
|
||||||
dup_stack->refcnt = 1;
|
dup_stack->refcnt = 1;
|
||||||
|
for (uint32_t idx = vs->top; idx < UINT32_MAX; --idx) {
|
||||||
|
struct u6a_vm_var_fn elem = vs->elems[idx];
|
||||||
|
if (elem.token.fn & U6A_VM_FN_REF) {
|
||||||
|
u6a_vm_pool_addref(elem.ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (vs->prev) {
|
||||||
|
++vs->prev->refcnt;
|
||||||
|
}
|
||||||
return dup_stack;
|
return dup_stack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,11 +74,18 @@ vm_stack_free(struct vm_stack* vs) {
|
||||||
do {
|
do {
|
||||||
prev = vs->prev;
|
prev = vs->prev;
|
||||||
if (--vs->refcnt == 0) {
|
if (--vs->refcnt == 0) {
|
||||||
|
for (uint32_t idx = vs->top; idx < UINT32_MAX; --idx) {
|
||||||
|
struct u6a_vm_var_fn elem = vs->elems[idx];
|
||||||
|
if (elem.token.fn & U6A_VM_FN_REF) {
|
||||||
|
u6a_vm_pool_free(elem.ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
free(vs);
|
free(vs);
|
||||||
|
vs = prev;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (prev);
|
} while (vs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -186,7 +202,7 @@ u6a_vm_stack_pop() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (active_stack->refcnt-- > 1) {
|
if (active_stack->refcnt-- > 1) {
|
||||||
active_stack = vm_stack_dup();
|
active_stack = vm_stack_dup(active_stack);
|
||||||
}
|
}
|
||||||
if (UNLIKELY(active_stack == NULL)) {
|
if (UNLIKELY(active_stack == NULL)) {
|
||||||
active_stack = vs;
|
active_stack = vs;
|
||||||
|
@ -206,7 +222,12 @@ u6a_vm_stack_xch(struct u6a_vm_var_fn v0) {
|
||||||
|
|
||||||
void*
|
void*
|
||||||
u6a_vm_stack_save() {
|
u6a_vm_stack_save() {
|
||||||
return vm_stack_dup();
|
return vm_stack_dup(active_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
void*
|
||||||
|
u6a_vm_stack_dup(void* ptr) {
|
||||||
|
return vm_stack_dup(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -55,6 +55,9 @@ u6a_vm_stack_xch(struct u6a_vm_var_fn v1);
|
||||||
void*
|
void*
|
||||||
u6a_vm_stack_save();
|
u6a_vm_stack_save();
|
||||||
|
|
||||||
|
void*
|
||||||
|
u6a_vm_stack_dup(void* ptr);
|
||||||
|
|
||||||
void
|
void
|
||||||
u6a_vm_stack_resume(void* ptr);
|
u6a_vm_stack_resume(void* ptr);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue