|
|
@ -1970,6 +1970,14 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
volatile duk_int_t entry_call_recursion_depth; |
|
|
|
duk_jmpbuf * volatile entry_jmpbuf_ptr; |
|
|
|
|
|
|
|
/* current PC, volatile because it is accessed by other functions
|
|
|
|
* through thr->ptr_to_curr_pc. Critical for performance. |
|
|
|
* |
|
|
|
* cdecl> explain int * volatile curr_pc |
|
|
|
* declare curr_pc as volatile pointer to int |
|
|
|
*/ |
|
|
|
duk_instr_t * volatile curr_pc; /* stable */ |
|
|
|
|
|
|
|
/* "hot" variables for interpretation -- not volatile, value not guaranteed in setjmp error handling */ |
|
|
|
duk_hthread *thr; /* stable */ |
|
|
|
duk_hcompiledfunction *fun; /* stable */ |
|
|
@ -2112,8 +2120,8 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
* memory anyway. |
|
|
|
* |
|
|
|
* Any 'goto restart_execution;' code path in opcode dispatch must |
|
|
|
* ensure thr->curr_pc is synced back to act->curr_pc before the |
|
|
|
* goto takes place. |
|
|
|
* ensure 'curr_pc' is synced back to act->curr_pc before the goto |
|
|
|
* takes place. |
|
|
|
*/ |
|
|
|
|
|
|
|
restart_execution: |
|
|
@ -2128,6 +2136,8 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
DUK_ASSERT(DUK_ACT_GET_FUNC(thr->callstack + thr->callstack_top - 1) != NULL); |
|
|
|
DUK_ASSERT(DUK_HOBJECT_IS_COMPILEDFUNCTION(DUK_ACT_GET_FUNC(thr->callstack + thr->callstack_top - 1))); |
|
|
|
|
|
|
|
thr->ptr_curr_pc = (duk_instr_t * volatile * volatile) &curr_pc; |
|
|
|
|
|
|
|
/* Assume interrupt init/counter are properly initialized here. */ |
|
|
|
|
|
|
|
/* assume that thr->valstack_bottom has been set-up before getting here */ |
|
|
@ -2204,11 +2214,11 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
valstack_top_base = (duk_size_t) (thr->valstack_top - thr->valstack); |
|
|
|
#endif |
|
|
|
|
|
|
|
/* Set up thr->curr_pc for opcode dispatch. */ |
|
|
|
/* Set up curr_pc for opcode dispatch. */ |
|
|
|
{ |
|
|
|
duk_activation *act; |
|
|
|
act = thr->callstack + thr->callstack_top - 1; |
|
|
|
thr->curr_pc = act->curr_pc; |
|
|
|
curr_pc = act->curr_pc; |
|
|
|
} |
|
|
|
|
|
|
|
for (;;) { |
|
|
@ -2235,12 +2245,12 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
{ |
|
|
|
duk_activation *act; |
|
|
|
act = thr->callstack + thr->callstack_top - 1; |
|
|
|
act->curr_pc = thr->curr_pc; |
|
|
|
act->curr_pc = (duk_instr_t *) curr_pc; |
|
|
|
} |
|
|
|
|
|
|
|
exec_int_ret = duk__executor_interrupt(thr); |
|
|
|
if (exec_int_ret == DUK__INT_RESTART) { |
|
|
|
/* thr->curr_pc synced back above */ |
|
|
|
/* curr_pc synced back above */ |
|
|
|
goto restart_execution; |
|
|
|
} |
|
|
|
} |
|
|
@ -2253,18 +2263,18 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
{ |
|
|
|
duk_activation *act; |
|
|
|
act = thr->callstack + thr->callstack_top - 1; |
|
|
|
DUK_ASSERT(thr->curr_pc >= DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, fun)); |
|
|
|
DUK_ASSERT(thr->curr_pc < DUK_HCOMPILEDFUNCTION_GET_CODE_END(thr->heap, fun)); |
|
|
|
DUK_ASSERT(curr_pc >= DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, fun)); |
|
|
|
DUK_ASSERT(curr_pc < DUK_HCOMPILEDFUNCTION_GET_CODE_END(thr->heap, fun)); |
|
|
|
DUK_UNREF(act); /* if debugging disabled */ |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("executing bytecode: pc=%ld, ins=0x%08lx, op=%ld, valstack_top=%ld/%ld, nregs=%ld --> %!I", |
|
|
|
(long) (thr->curr_pc - DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, fun)), |
|
|
|
(unsigned long) *thr->curr_pc, |
|
|
|
(long) DUK_DEC_OP(*thr->curr_pc), |
|
|
|
(long) (curr_pc - DUK_HCOMPILEDFUNCTION_GET_CODE_BASE(thr->heap, fun)), |
|
|
|
(unsigned long) *curr_pc, |
|
|
|
(long) DUK_DEC_OP(*curr_pc), |
|
|
|
(long) (thr->valstack_top - thr->valstack), |
|
|
|
(long) (thr->valstack_end - thr->valstack), |
|
|
|
(long) (fun ? fun->nregs : -1), |
|
|
|
(duk_instr_t) *thr->curr_pc)); |
|
|
|
(duk_instr_t) *curr_pc)); |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
@ -2284,7 +2294,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
} |
|
|
|
#endif |
|
|
|
|
|
|
|
ins = *thr->curr_pc++; |
|
|
|
ins = *curr_pc++; |
|
|
|
|
|
|
|
/* Typing: use duk_small_(u)int_fast_t when decoding small
|
|
|
|
* opcode fields (op, A, B, C) and duk_(u)int_fast_t when |
|
|
@ -2548,7 +2558,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
* even if the constructor is an Ecmascript function. |
|
|
|
*/ |
|
|
|
|
|
|
|
/* Don't need to sync thr->curr_pc here; duk_new() will do that
|
|
|
|
/* Don't need to sync curr_pc here; duk_new() will do that
|
|
|
|
* when it augments the created error. |
|
|
|
*/ |
|
|
|
|
|
|
@ -3166,7 +3176,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
tmp = duk_js_toboolean(DUK__REGCONSTP(b)); |
|
|
|
if (tmp == (duk_bool_t) a) { |
|
|
|
/* if boolean matches A, skip next inst */ |
|
|
|
thr->curr_pc++; |
|
|
|
curr_pc++; |
|
|
|
} else { |
|
|
|
; |
|
|
|
} |
|
|
@ -3176,7 +3186,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
case DUK_OP_JUMP: { |
|
|
|
duk_int_fast_t abc = DUK_DEC_ABC(ins); |
|
|
|
|
|
|
|
thr->curr_pc += abc - DUK_BC_JUMP_BIAS; |
|
|
|
curr_pc += abc - DUK_BC_JUMP_BIAS; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
@ -3327,7 +3337,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
* Avoid C recursion by being clever. |
|
|
|
*/ |
|
|
|
DUK_DDD(DUK_DDDPRINT("ecma-to-ecma call setup possible, restart execution")); |
|
|
|
/* thr->curr_pc synced by duk_handle_ecma_call_setup() */ |
|
|
|
/* curr_pc synced by duk_handle_ecma_call_setup() */ |
|
|
|
goto restart_execution; |
|
|
|
} |
|
|
|
|
|
|
@ -3407,7 +3417,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
/* When debugger is enabled, we need to recheck the activation
|
|
|
|
* status after returning. |
|
|
|
*/ |
|
|
|
/* call handling has synced thr->curr_pc */ |
|
|
|
/* call handling has synced curr_pc */ |
|
|
|
goto restart_execution; |
|
|
|
#endif |
|
|
|
break; |
|
|
@ -3556,7 +3566,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
|
|
|
|
cat = thr->catchstack + thr->catchstack_top - 1; /* relookup (side effects) */ |
|
|
|
cat->callstack_index = thr->callstack_top - 1; |
|
|
|
cat->pc_base = thr->curr_pc; /* pre-incremented, points to first jump slot */ |
|
|
|
cat->pc_base = (duk_instr_t *) curr_pc; /* pre-incremented, points to first jump slot */ |
|
|
|
cat->idx_base = (duk_size_t) (thr->valstack_bottom - thr->valstack) + bc; |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("TRYCATCH catcher: flags=0x%08lx, callstack_index=%ld, pc_base=%ld, " |
|
|
@ -3564,7 +3574,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
(unsigned long) cat->flags, (long) cat->callstack_index, |
|
|
|
(long) cat->pc_base, (long) cat->idx_base, (duk_heaphdr *) cat->h_varname)); |
|
|
|
|
|
|
|
thr->curr_pc += 2; /* skip jump slots */ |
|
|
|
curr_pc += 2; /* skip jump slots */ |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
@ -3964,7 +3974,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
/* [ ... enum ] -> [ ... next_key ] */ |
|
|
|
DUK_DDD(DUK_DDDPRINT("enum active, next key is %!T, skip jump slot ", |
|
|
|
(duk_tval *) duk_get_tval(ctx, -1))); |
|
|
|
thr->curr_pc++; |
|
|
|
curr_pc++; |
|
|
|
} else { |
|
|
|
/* [ ... enum ] -> [ ... ] */ |
|
|
|
DUK_DDD(DUK_DDDPRINT("enum finished, execute jump slot")); |
|
|
@ -4084,7 +4094,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
/* no need to unwind callstack */ |
|
|
|
} |
|
|
|
|
|
|
|
thr->curr_pc = cat->pc_base + 1; |
|
|
|
curr_pc = cat->pc_base + 1; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
@ -4143,7 +4153,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
/* no need to unwind callstack */ |
|
|
|
} |
|
|
|
|
|
|
|
thr->curr_pc = cat->pc_base + 1; |
|
|
|
curr_pc = cat->pc_base + 1; |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
@ -4356,7 +4366,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
|
|
|
|
cat->flags = DUK_CAT_TYPE_LABEL | (bc << DUK_CAT_LABEL_SHIFT); |
|
|
|
cat->callstack_index = thr->callstack_top - 1; |
|
|
|
cat->pc_base = thr->curr_pc; /* pre-incremented, points to first jump slot */ |
|
|
|
cat->pc_base = (duk_instr_t *) curr_pc; /* pre-incremented, points to first jump slot */ |
|
|
|
cat->idx_base = 0; /* unused for label */ |
|
|
|
cat->h_varname = NULL; |
|
|
|
|
|
|
@ -4365,7 +4375,7 @@ DUK_INTERNAL void duk_js_execute_bytecode(duk_hthread *exec_thr) { |
|
|
|
(long) cat->flags, (long) cat->callstack_index, (long) cat->pc_base, |
|
|
|
(long) cat->idx_base, (duk_heaphdr *) cat->h_varname, (long) DUK_CAT_GET_LABEL(cat))); |
|
|
|
|
|
|
|
thr->curr_pc += 2; /* skip jump slots */ |
|
|
|
curr_pc += 2; /* skip jump slots */ |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|