refactor runtime

This commit is contained in:
CismonX 2020-05-29 00:54:26 +08:00
parent 15a7173de0
commit 05849e02a9
No known key found for this signature in database
GPG Key ID: 315D6652268C5007
1 changed files with 27 additions and 28 deletions

View File

@ -62,6 +62,11 @@ static const char* info_runtime = "runtime";
if (UNLIKELY(acc.ref == UINT32_MAX)) { \ if (UNLIKELY(acc.ref == UINT32_MAX)) { \
goto runtime_error; \ goto runtime_error; \
} }
#define VM_JMP(dest) \
ins = text + (dest); \
continue
#define VM_VAR_JMP \
U6A_VM_VAR_FN_REF(u6a_vf_j, ins - text)
#define CHECK_FORCE(log_func, err_val) \ #define CHECK_FORCE(log_func, err_val) \
if (!force_exec) { \ if (!force_exec) { \
log_func(err_runtime, err_val); \ log_func(err_runtime, err_val); \
@ -248,11 +253,10 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
if (ins - text == 0x03) { if (ins - text == 0x03) {
STACK_PUSH3(arg, tuple); STACK_PUSH3(arg, tuple);
} else { } else {
STACK_PUSH4(U6A_VM_VAR_FN_REF(u6a_vf_j, ins - text), arg, tuple); STACK_PUSH4(VM_VAR_JMP, arg, tuple);
} }
ACC_FN(arg); ACC_FN(arg);
ins = text; VM_JMP(0x00);
continue;
case u6a_vf_k: case u6a_vf_k:
vm_var_fn_addref(arg); vm_var_fn_addref(arg);
ACC_FN_REF(u6a_vf_k1, u6a_vm_pool_alloc1(arg)); ACC_FN_REF(u6a_vf_k1, u6a_vm_pool_alloc1(arg));
@ -272,21 +276,21 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
ins = text + func.ref; ins = text + func.ref;
break; break;
case u6a_vf_f: case u6a_vf_f:
// Safe to assign IP here before jumping, as func won't be `j` or `f`
ins = text + func.ref; ins = text + func.ref;
STACK_POP(); STACK_POP();
func = acc; STACK_PUSH2(U6A_VM_VAR_FN_REF(u6a_vf_j, func.ref), vm_var_fn_addref(arg));
arg = top; ACC_FN(top);
goto do_apply; VM_JMP(0x03);
case u6a_vf_c: case u6a_vf_c:
ptr = u6a_vm_stack_save(); ptr = u6a_vm_stack_save();
if (UNLIKELY(ptr == NULL)) { if (UNLIKELY(ptr == NULL)) {
goto runtime_error; goto runtime_error;
} }
func = arg; STACK_PUSH2(VM_VAR_JMP, vm_var_fn_addref(arg));
arg = U6A_VM_VAR_FN_REF(u6a_vf_c1, u6a_vm_pool_alloc2_ptr(ptr, ins)); ACC_FN_REF(u6a_vf_c1, u6a_vm_pool_alloc2_ptr(ptr, ins));
goto do_apply; VM_JMP(0x03);
case u6a_vf_d: case u6a_vf_d:
vm_var_fn_addref(arg);
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:
@ -302,12 +306,10 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
tuple = u6a_vm_pool_get2(func.ref); tuple = u6a_vm_pool_get2(func.ref);
STACK_PUSH1(tuple.v1.fn); STACK_PUSH1(tuple.v1.fn);
ACC_FN(tuple.v2.fn); ACC_FN(tuple.v2.fn);
ins = text + 0x03; VM_JMP(0x03);
continue;
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), U6A_VM_VAR_FN_REF(u6a_vf_f, ins - text));
ins = text + func.ref; VM_JMP(func.ref);
continue;
case u6a_vf_v: case u6a_vf_v:
vm_var_fn_free(acc); vm_var_fn_free(acc);
acc.token.fn = u6a_vf_v; acc.token.fn = u6a_vf_v;
@ -318,30 +320,28 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
break; break;
case u6a_vf_in: case u6a_vf_in:
current_char = fgetc(istream); current_char = fgetc(istream);
func = arg; STACK_PUSH2(VM_VAR_JMP, vm_var_fn_addref(arg));
if (UNLIKELY(current_char == EOF)) { if (UNLIKELY(current_char == EOF)) {
arg.token.fn = u6a_vf_v; arg.token.fn = u6a_vf_v;
} else { } else {
arg.token.fn = u6a_vf_i; arg.token.fn = u6a_vf_i;
} }
goto do_apply; ACC_FN(arg);
VM_JMP(0x03);
case u6a_vf_cmp: case u6a_vf_cmp:
if (func.token.ch == current_char) { STACK_PUSH2(VM_VAR_JMP, vm_var_fn_addref(arg));
func = arg; arg.token.fn = func.token.ch == current_char ? u6a_vf_i : u6a_vf_v;
arg.token.fn = u6a_vf_i; ACC_FN(arg);
} else { VM_JMP(0x03);
func = arg;
arg.token.fn = u6a_vf_v;
}
goto do_apply;
case u6a_vf_pipe: case u6a_vf_pipe:
func = arg; STACK_PUSH2(VM_VAR_JMP, vm_var_fn_addref(arg));
if (UNLIKELY(current_char == EOF)) { if (UNLIKELY(current_char == EOF)) {
arg.token.fn = u6a_vf_v; 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);
} }
goto do_apply; ACC_FN(arg);
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
return U6A_VM_VAR_FN(arg); return U6A_VM_VAR_FN(arg);
@ -369,8 +369,7 @@ u6a_runtime_execute(FILE* restrict istream, FILE* restrict ostream) {
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_FN_INIT(U6A_VM_VAR_FN_REF(u6a_vf_d1_d, ins + 1 - text));
ins = text + text_subst_len + ins->operand.offset; VM_JMP(text_subst_len + ins->operand.offset);
continue;
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: