This commit is contained in:
CismonX 2020-06-22 01:34:33 +08:00
parent d92a036663
commit 6a4af125d6
No known key found for this signature in database
GPG Key ID: 315D6652268C5007
1 changed files with 24 additions and 38 deletions

View File

@ -53,16 +53,7 @@ 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
#define ACC_FN(fn_) \
vm_var_fn_addref(fn_); \
vm_var_fn_free(acc); \
acc = fn_
#define ACC_FN_INIT(fn_) \
vm_var_fn_free(acc); \
acc = fn_
#define ACC_FN_REF(fn_, ref_) \ #define ACC_FN_REF(fn_, ref_) \
vm_var_fn_free(acc); \
acc = U6A_VM_VAR_FN_REF(fn_, ref_) acc = U6A_VM_VAR_FN_REF(fn_, ref_)
#define VM_JMP(dest) \ #define VM_JMP(dest) \
ins = text + (dest); \ ins = text + (dest); \
@ -125,7 +116,7 @@ vm_var_fn_addref(struct u6a_vm_var_fn var) {
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) {
//u6a_vm_pool_free(pool_ctx.active_pool, var.ref); u6a_vm_pool_free(&pool_ctx, var.ref);
} }
} }
@ -237,13 +228,11 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
do_apply: do_apply:
switch (func.token.fn) { switch (func.token.fn) {
case u6a_vf_s: case u6a_vf_s:
vm_var_fn_addref(arg); ACC_FN_REF(u6a_vf_s1, POOL_ALLOC1(vm_var_fn_addref(arg)));
ACC_FN_REF(u6a_vf_s1, POOL_ALLOC1(arg));
break; break;
case u6a_vf_s1: case u6a_vf_s1:
vm_var_fn_addref(arg); vm_var_fn_addref(arg);
vm_var_fn_addref(POOL_GET1(func.ref).fn); ACC_FN_REF(u6a_vf_s2, POOL_ALLOC2(vm_var_fn_addref(POOL_GET1(func.ref).fn), arg));
ACC_FN_REF(u6a_vf_s2, POOL_ALLOC2(POOL_GET1(func.ref).fn, arg));
break; break;
case u6a_vf_s2: case u6a_vf_s2:
tuple = POOL_GET2(func.ref); tuple = POOL_GET2(func.ref);
@ -255,31 +244,30 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
} else { } else {
STACK_PUSH4(VM_VAR_JMP, arg, tuple.v2.fn, tuple.v1.fn); STACK_PUSH4(VM_VAR_JMP, arg, tuple.v2.fn, tuple.v1.fn);
} }
ACC_FN(arg); acc = arg;
VM_JMP(0x00); VM_JMP(0x00);
case u6a_vf_k: case u6a_vf_k:
vm_var_fn_addref(arg); ACC_FN_REF(u6a_vf_k1, POOL_ALLOC1(vm_var_fn_addref(arg)));
ACC_FN_REF(u6a_vf_k1, POOL_ALLOC1(arg));
break; break;
case u6a_vf_k1: case u6a_vf_k1:
ACC_FN(POOL_GET1(func.ref).fn); acc = vm_var_fn_addref(POOL_GET1(func.ref).fn);
break; break;
case u6a_vf_i: case u6a_vf_i:
ACC_FN(arg); acc = arg;
break; break;
case u6a_vf_out: case u6a_vf_out:
ACC_FN(arg); acc = arg;
fputc(func.token.ch, ostream); fputc(func.token.ch, ostream);
break; break;
case u6a_vf_j: case u6a_vf_j:
ACC_FN(arg); acc = arg;
ins = text + func.ref; ins = text + func.ref;
break; break;
case u6a_vf_f: case u6a_vf_f:
ins = text + func.ref; ins = text + func.ref;
STACK_POP(); STACK_POP();
STACK_PUSH2(U6A_VM_VAR_FN_REF(u6a_vf_j, func.ref), vm_var_fn_addref(arg)); STACK_PUSH2(U6A_VM_VAR_FN_REF(u6a_vf_j, func.ref), vm_var_fn_addref(arg));
ACC_FN(top); acc = top;
VM_JMP(0x03); VM_JMP(0x03);
case u6a_vf_c: case u6a_vf_c:
cont = u6a_vm_stack_save(&stack_ctx); cont = u6a_vm_stack_save(&stack_ctx);
@ -287,33 +275,31 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
ACC_FN_REF(u6a_vf_c1, POOL_ALLOC2_PTR(cont, ins)); ACC_FN_REF(u6a_vf_c1, POOL_ALLOC2_PTR(cont, ins));
VM_JMP(0x03); VM_JMP(0x03);
case u6a_vf_d: case u6a_vf_d:
vm_var_fn_addref(arg); ACC_FN_REF(u6a_vf_d1_c, POOL_ALLOC1(vm_var_fn_addref(arg)));
ACC_FN_REF(u6a_vf_d1_c, POOL_ALLOC1(arg));
break; break;
case u6a_vf_c1: case u6a_vf_c1:
tuple = POOL_GET2_SEPARATE(func.ref); tuple = POOL_GET2_SEPARATE(func.ref);
u6a_vm_stack_resume(&stack_ctx, tuple.v1.ptr); u6a_vm_stack_resume(&stack_ctx, tuple.v1.ptr);
ins = tuple.v2.ptr; ins = tuple.v2.ptr;
ACC_FN(arg); acc = arg;
break; break;
case u6a_vf_d1_c: case u6a_vf_d1_c:
STACK_PUSH2(VM_VAR_JMP, vm_var_fn_addref(POOL_GET1(func.ref).fn)); STACK_PUSH2(VM_VAR_JMP, vm_var_fn_addref(POOL_GET1(func.ref).fn));
ACC_FN(arg); acc = arg;
VM_JMP(0x03); VM_JMP(0x03);
case u6a_vf_d1_s: case u6a_vf_d1_s:
tuple = POOL_GET2(func.ref); tuple = POOL_GET2(func.ref);
STACK_PUSH3(vm_var_fn_addref(arg), VM_VAR_FINALIZE, tuple.v1.fn); STACK_PUSH3(vm_var_fn_addref(arg), VM_VAR_FINALIZE, vm_var_fn_addref(tuple.v1.fn));
ACC_FN(tuple.v2.fn); acc = 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), VM_VAR_FINALIZE); 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);
acc.token.fn = u6a_vf_v; acc.token.fn = u6a_vf_v;
break; break;
case u6a_vf_p: case u6a_vf_p:
ACC_FN(arg); acc = arg;
fputs(rodata + func.ref, ostream); fputs(rodata + func.ref, ostream);
break; break;
case u6a_vf_in: case u6a_vf_in:
@ -324,12 +310,12 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
} else { } else {
arg.token.fn = u6a_vf_i; arg.token.fn = u6a_vf_i;
} }
ACC_FN(arg); acc = arg;
VM_JMP(0x03); VM_JMP(0x03);
case u6a_vf_cmp: case u6a_vf_cmp:
STACK_PUSH2(VM_VAR_JMP, vm_var_fn_addref(arg)); STACK_PUSH2(VM_VAR_JMP, vm_var_fn_addref(arg));
arg.token.fn = func.token.ch == current_char ? u6a_vf_i : u6a_vf_v; arg.token.fn = func.token.ch == current_char ? u6a_vf_i : u6a_vf_v;
ACC_FN(arg); acc = arg;
VM_JMP(0x03); VM_JMP(0x03);
case u6a_vf_pipe: case u6a_vf_pipe:
STACK_PUSH2(VM_VAR_JMP, vm_var_fn_addref(arg)); STACK_PUSH2(VM_VAR_JMP, vm_var_fn_addref(arg));
@ -338,7 +324,7 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
} else { } else {
arg.token = U6A_TOKEN(u6a_vf_out, current_char); arg.token = U6A_TOKEN(u6a_vf_out, current_char);
} }
ACC_FN(arg); acc = arg;
VM_JMP(0x03); VM_JMP(0x03);
case u6a_vf_e: case u6a_vf_e:
// Every program should terminate with explicit `e` function // Every program should terminate with explicit `e` function
@ -351,14 +337,14 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
if (UNLIKELY(acc.token.fn == u6a_vf_d)) { if (UNLIKELY(acc.token.fn == u6a_vf_d)) {
goto delay; goto delay;
} }
STACK_PUSH1(acc); STACK_PUSH1(vm_var_fn_addref(acc));
break; break;
case u6a_vo_xch: case u6a_vo_xch:
if (UNLIKELY(acc.token.fn == u6a_vf_d)) { if (UNLIKELY(acc.token.fn == u6a_vf_d)) {
STACK_POP(); STACK_POP();
func = top; vm_var_fn_addref(func = top);
STACK_POP(); STACK_POP();
arg = top; vm_var_fn_addref(arg = top);
ACC_FN_REF(u6a_vf_d1_s, POOL_ALLOC2(func, arg)); ACC_FN_REF(u6a_vf_d1_s, POOL_ALLOC2(func, arg));
} else { } else {
acc = STACK_XCH(acc); acc = STACK_XCH(acc);
@ -366,12 +352,12 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
break; break;
case u6a_vo_del: case u6a_vo_del:
delay: delay:
ACC_FN_INIT(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);
VM_JMP(text_subst_len + ins->operand.offset); VM_JMP(text_subst_len + ins->operand.offset);
case u6a_vo_lc: case u6a_vo_lc:
switch (ins->opcode_ex) { switch (ins->opcode_ex) {
case u6a_vo_ex_print: case u6a_vo_ex_print:
ACC_FN_INIT(U6A_VM_VAR_FN_REF(u6a_vf_p, ins->operand.offset)); acc = U6A_VM_VAR_FN_REF(u6a_vf_p, ins->operand.offset);
break; break;
default: default:
CHECK_FORCE(u6a_err_invalid_ex_opcode, ins->opcode_ex); CHECK_FORCE(u6a_err_invalid_ex_opcode, ins->opcode_ex);