fix bug for promises; refactor vm_stack

This commit is contained in:
CismonX 2020-06-13 18:33:56 +08:00
parent af42c44645
commit 300c1a09a1
No known key found for this signature in database
GPG Key ID: 315D6652268C5007
3 changed files with 56 additions and 52 deletions

View File

@ -46,56 +46,58 @@ static const uint32_t text_subst_len = sizeof(text_subst) / sizeof(struct u6a_vm
static const char* err_runtime = "runtime error"; static const char* err_runtime = "runtime error";
static const char* info_runtime = "runtime"; static const char* info_runtime = "runtime";
#define CHECK_BC_HEADER_VER(file_header) \ #define CHECK_BC_HEADER_VER(file_header) \
( (file_header).ver_major == U6A_VER_MAJOR && (file_header).ver_minor == U6A_VER_MINOR ) ( (file_header).ver_major == U6A_VER_MAJOR && (file_header).ver_minor == U6A_VER_MINOR )
// Addref before free, for acc may equal to fn // Addref before free, for acc may equal to fn
#define ACC_FN(fn_) \ #define ACC_FN(fn_) \
vm_var_fn_addref(fn_); \ vm_var_fn_addref(fn_); \
vm_var_fn_free(acc); \ vm_var_fn_free(acc); \
acc = fn_ acc = fn_
#define ACC_FN_INIT(fn_) \ #define ACC_FN_INIT(fn_) \
vm_var_fn_free(acc); \ vm_var_fn_free(acc); \
acc = fn_ acc = fn_
#define ACC_FN_REF(fn_, ref_) \ #define ACC_FN_REF(fn_, ref_) \
vm_var_fn_free(acc); \ vm_var_fn_free(acc); \
acc = U6A_VM_VAR_FN_REF(fn_, ref_); \ acc = U6A_VM_VAR_FN_REF(fn_, ref_); \
if (UNLIKELY(acc.ref == UINT32_MAX)) { \ if (UNLIKELY(acc.ref == UINT32_MAX)) { \
goto runtime_error; \ goto runtime_error; \
} }
#define VM_JMP(dest) \ #define VM_JMP(dest) \
ins = text + (dest); \ ins = text + (dest); \
continue continue
#define VM_VAR_JMP \ #define VM_VAR_JMP \
U6A_VM_VAR_FN_REF(u6a_vf_j, ins - text) U6A_VM_VAR_FN_REF(u6a_vf_j, ins - text)
#define CHECK_FORCE(log_func, err_val) \ #define VM_VAR_FINALIZE \
if (!force_exec) { \ U6A_VM_VAR_FN_REF(u6a_vf_f, ins - text)
log_func(err_runtime, err_val); \ #define CHECK_FORCE(log_func, err_val) \
goto runtime_error; \ if (!force_exec) { \
log_func(err_runtime, err_val); \
goto runtime_error; \
} }
#define STACK_PUSH1(fn_0) \ #define STACK_PUSH1(fn_0) \
vm_var_fn_addref(fn_0); \ vm_var_fn_addref(fn_0); \
if (UNLIKELY(!u6a_vm_stack_push1(fn_0))) { \ if (UNLIKELY(!u6a_vm_stack_push1(fn_0))) { \
goto runtime_error; \ goto runtime_error; \
} }
#define STACK_PUSH2(fn_0, fn_1) \ #define STACK_PUSH2(fn_0, fn_1) \
if (UNLIKELY(!u6a_vm_stack_push2(fn_0, fn_1))) { \ if (UNLIKELY(!u6a_vm_stack_push2(fn_0, fn_1))) { \
goto runtime_error; \ goto runtime_error; \
} }
#define STACK_PUSH3(fn_0, fn_12) \ #define STACK_PUSH3(fn_0, fn_1, fn_2) \
if (UNLIKELY(!u6a_vm_stack_push3(fn_0, fn_12))) { \ if (UNLIKELY(!u6a_vm_stack_push3(fn_0, fn_1, fn_2))) { \
goto runtime_error; \ goto runtime_error; \
} }
#define STACK_PUSH4(fn_0, fn_1, fn_23) \ #define STACK_PUSH4(fn_0, fn_1, fn_2, fn_3) \
if (UNLIKELY(!u6a_vm_stack_push4(fn_0, fn_1, fn_23))) { \ if (UNLIKELY(!u6a_vm_stack_push4(fn_0, fn_1, fn_2, fn_3))) { \
goto runtime_error; \ goto runtime_error; \
} }
#define STACK_POP() \ #define STACK_POP() \
vm_var_fn_free(top); \ vm_var_fn_free(top); \
top = u6a_vm_stack_top(); \ top = u6a_vm_stack_top(); \
if (UNLIKELY(!u6a_vm_stack_pop())) { \ if (UNLIKELY(!u6a_vm_stack_pop())) { \
goto runtime_error; \ goto runtime_error; \
} }
static inline bool static inline bool
@ -251,9 +253,9 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
vm_var_fn_addref(tuple.v2.fn); vm_var_fn_addref(tuple.v2.fn);
vm_var_fn_addref(arg); vm_var_fn_addref(arg);
if (ins - text == 0x03) { if (ins - text == 0x03) {
STACK_PUSH3(arg, tuple); STACK_PUSH3(arg, tuple.v2.fn, tuple.v1.fn);
} else { } else {
STACK_PUSH4(VM_VAR_JMP, arg, tuple); STACK_PUSH4(VM_VAR_JMP, arg, tuple.v2.fn, tuple.v1.fn);
} }
ACC_FN(arg); ACC_FN(arg);
VM_JMP(0x00); VM_JMP(0x00);
@ -305,11 +307,11 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
VM_JMP(0x03); VM_JMP(0x03);
case u6a_vf_d1_s: case u6a_vf_d1_s:
tuple = u6a_vm_pool_get2(func.ref); tuple = u6a_vm_pool_get2(func.ref);
STACK_PUSH1(tuple.v1.fn); STACK_PUSH3(vm_var_fn_addref(arg), VM_VAR_FINALIZE, tuple.v1.fn);
ACC_FN(tuple.v2.fn); ACC_FN(tuple.v2.fn);
VM_JMP(0x03); VM_JMP(0x03);
case u6a_vf_d1_d: case u6a_vf_d1_d:
STACK_PUSH2(vm_var_fn_addref(arg), U6A_VM_VAR_FN_REF(u6a_vf_f, ins - text)); STACK_PUSH2(vm_var_fn_addref(arg), VM_VAR_FINALIZE);
VM_JMP(func.ref); VM_JMP(func.ref);
case u6a_vf_v: case u6a_vf_v:
vm_var_fn_free(acc); vm_var_fn_free(acc);

View File

@ -154,12 +154,12 @@ u6a_vm_stack_push2(struct u6a_vm_var_fn v0, struct u6a_vm_var_fn v1) {
} }
U6A_HOT bool U6A_HOT bool
u6a_vm_stack_push3(struct u6a_vm_var_fn v0, struct u6a_vm_var_tuple v12) { u6a_vm_stack_push3(struct u6a_vm_var_fn v0, struct u6a_vm_var_fn v1, struct u6a_vm_var_fn v2) {
struct vm_stack* vs = active_stack; struct vm_stack* vs = active_stack;
if (LIKELY(vs->top + 3 < stack_seg_len)) { if (LIKELY(vs->top + 3 < stack_seg_len)) {
vs->elems[++vs->top] = v0; vs->elems[++vs->top] = v0;
vs->elems[++vs->top] = v12.v2.fn; vs->elems[++vs->top] = v1;
vs->elems[++vs->top] = v12.v1.fn; vs->elems[++vs->top] = v2;
return true; return true;
} }
active_stack = vm_stack_create(vs, 2); active_stack = vm_stack_create(vs, 2);
@ -169,19 +169,20 @@ u6a_vm_stack_push3(struct u6a_vm_var_fn v0, struct u6a_vm_var_tuple v12) {
} }
++vs->refcnt; ++vs->refcnt;
active_stack->elems[0] = v0; active_stack->elems[0] = v0;
active_stack->elems[1] = v12.v2.fn; active_stack->elems[1] = v1;
active_stack->elems[2] = v12.v1.fn; active_stack->elems[2] = v2;
return true; return true;
} }
U6A_HOT bool U6A_HOT bool
u6a_vm_stack_push4(struct u6a_vm_var_fn v0, struct u6a_vm_var_fn v1, struct u6a_vm_var_tuple v23) { u6a_vm_stack_push4(struct u6a_vm_var_fn v0, struct u6a_vm_var_fn v1,
struct u6a_vm_var_fn v2, struct u6a_vm_var_fn v3) {
struct vm_stack* vs = active_stack; struct vm_stack* vs = active_stack;
if (LIKELY(vs->top + 4 < stack_seg_len)) { if (LIKELY(vs->top + 4 < stack_seg_len)) {
vs->elems[++vs->top] = v0; vs->elems[++vs->top] = v0;
vs->elems[++vs->top] = v1; vs->elems[++vs->top] = v1;
vs->elems[++vs->top] = v23.v2.fn; vs->elems[++vs->top] = v2;
vs->elems[++vs->top] = v23.v1.fn; vs->elems[++vs->top] = v3;
return true; return true;
} }
active_stack = vm_stack_create(vs, 3); active_stack = vm_stack_create(vs, 3);
@ -192,8 +193,8 @@ u6a_vm_stack_push4(struct u6a_vm_var_fn v0, struct u6a_vm_var_fn v1, struct u6a_
++vs->refcnt; ++vs->refcnt;
active_stack->elems[0] = v0; active_stack->elems[0] = v0;
active_stack->elems[1] = v1; active_stack->elems[1] = v1;
active_stack->elems[2] = v23.v2.fn; active_stack->elems[2] = v2;
active_stack->elems[3] = v23.v1.fn; active_stack->elems[3] = v3;
return true; return true;
} }

View File

@ -41,10 +41,11 @@ u6a_vm_stack_push2(struct u6a_vm_var_fn v0, struct u6a_vm_var_fn v1);
// Functions push3 and push4 are made for the s2 function to alleviate overhead caused by hot split // Functions push3 and push4 are made for the s2 function to alleviate overhead caused by hot split
bool bool
u6a_vm_stack_push3(struct u6a_vm_var_fn v0, struct u6a_vm_var_tuple v12); u6a_vm_stack_push3(struct u6a_vm_var_fn v0, struct u6a_vm_var_fn v1, struct u6a_vm_var_fn v2);
bool bool
u6a_vm_stack_push4(struct u6a_vm_var_fn v0, struct u6a_vm_var_fn v1, struct u6a_vm_var_tuple v23); u6a_vm_stack_push4(struct u6a_vm_var_fn v0, struct u6a_vm_var_fn v1,
struct u6a_vm_var_fn v2, struct u6a_vm_var_fn v3);
bool bool
u6a_vm_stack_pop(); u6a_vm_stack_pop();