|
|
@ -22,22 +22,22 @@ |
|
|
|
static void duk__create_arguments_object(duk_hthread *thr, |
|
|
|
duk_hobject *func, |
|
|
|
duk_hobject *varenv, |
|
|
|
int idx_argbase, /* idx of first argument on stack */ |
|
|
|
int num_stack_args) { /* num args starting from idx_argbase */ |
|
|
|
duk_idx_t idx_argbase, /* idx of first argument on stack */ |
|
|
|
duk_idx_t num_stack_args) { /* num args starting from idx_argbase */ |
|
|
|
duk_context *ctx = (duk_context *) thr; |
|
|
|
duk_hobject *arg; /* 'arguments' */ |
|
|
|
duk_hobject *formals; /* formals for 'func' (may be NULL if func is a C function) */ |
|
|
|
int i_arg; |
|
|
|
int i_map; |
|
|
|
int i_mappednames; |
|
|
|
int i_formals; |
|
|
|
int i_argbase; |
|
|
|
int n_formals; |
|
|
|
int idx; |
|
|
|
int need_map; |
|
|
|
duk_idx_t i_arg; |
|
|
|
duk_idx_t i_map; |
|
|
|
duk_idx_t i_mappednames; |
|
|
|
duk_idx_t i_formals; |
|
|
|
duk_idx_t i_argbase; |
|
|
|
duk_idx_t n_formals; |
|
|
|
duk_idx_t idx; |
|
|
|
duk_bool_t need_map; |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("creating arguments object for func=%!iO, varenv=%!iO, idx_argbase=%d, num_stack_args=%d", |
|
|
|
(duk_heaphdr *) func, (duk_heaphdr *) varenv, idx_argbase, num_stack_args)); |
|
|
|
(duk_heaphdr *) func, (duk_heaphdr *) varenv, (int) idx_argbase, (int) num_stack_args)); |
|
|
|
|
|
|
|
DUK_ASSERT(thr != NULL); |
|
|
|
DUK_ASSERT(func != NULL); |
|
|
@ -57,7 +57,7 @@ static void duk__create_arguments_object(duk_hthread *thr, |
|
|
|
n_formals = 0; |
|
|
|
if (formals) { |
|
|
|
duk_get_prop_stridx(ctx, -1, DUK_STRIDX_LENGTH); |
|
|
|
n_formals = duk_require_int(ctx, -1); |
|
|
|
n_formals = (duk_idx_t) duk_require_int(ctx, -1); |
|
|
|
duk_pop(ctx); |
|
|
|
} |
|
|
|
duk_remove(ctx, -2); /* leave formals on stack for later use */ |
|
|
@ -66,7 +66,7 @@ static void duk__create_arguments_object(duk_hthread *thr, |
|
|
|
DUK_ASSERT(n_formals >= 0); |
|
|
|
DUK_ASSERT(formals != NULL || n_formals == 0); |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("func=%!O, formals=%!O, n_formals=%d", func, formals, n_formals)); |
|
|
|
DUK_DDD(DUK_DDDPRINT("func=%!O, formals=%!O, n_formals=%d", func, formals, (int) n_formals)); |
|
|
|
|
|
|
|
/* [ ... formals ] */ |
|
|
|
|
|
|
@ -104,9 +104,9 @@ static void duk__create_arguments_object(duk_hthread *thr, |
|
|
|
"arguments at index %d -> %!O " |
|
|
|
"map at index %d -> %!O " |
|
|
|
"mappednames at index %d -> %!O", |
|
|
|
i_arg, duk_get_hobject(ctx, i_arg), |
|
|
|
i_map, duk_get_hobject(ctx, i_map), |
|
|
|
i_mappednames, duk_get_hobject(ctx, i_mappednames))); |
|
|
|
(int) i_arg, duk_get_hobject(ctx, i_arg), |
|
|
|
(int) i_map, duk_get_hobject(ctx, i_map), |
|
|
|
(int) i_mappednames, duk_get_hobject(ctx, i_mappednames))); |
|
|
|
|
|
|
|
/*
|
|
|
|
* Init arguments properties, map, etc. |
|
|
@ -122,19 +122,21 @@ static void duk__create_arguments_object(duk_hthread *thr, |
|
|
|
/* step 11 */ |
|
|
|
idx = num_stack_args - 1; |
|
|
|
while (idx >= 0) { |
|
|
|
DUK_DDD(DUK_DDDPRINT("arg idx %d, argbase=%d, argidx=%d", idx, i_argbase, i_argbase + idx)); |
|
|
|
DUK_DDD(DUK_DDDPRINT("arg idx %d, argbase=%d, argidx=%d", |
|
|
|
(int) idx, (int) i_argbase, (int) (i_argbase + idx))); |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("define arguments[%d]=arg", idx)); |
|
|
|
DUK_DDD(DUK_DDDPRINT("define arguments[%d]=arg", (int) idx)); |
|
|
|
duk_push_int(ctx, idx); |
|
|
|
duk_dup(ctx, i_argbase + idx); |
|
|
|
duk_def_prop_wec(ctx, i_arg); |
|
|
|
DUK_DDD(DUK_DDDPRINT("defined arguments[%d]=arg", idx)); |
|
|
|
DUK_DDD(DUK_DDDPRINT("defined arguments[%d]=arg", (int) idx)); |
|
|
|
|
|
|
|
/* step 11.c is relevant only if non-strict (checked in 11.c.ii) */ |
|
|
|
if (!DUK_HOBJECT_HAS_STRICT(func) && idx < n_formals) { |
|
|
|
DUK_ASSERT(formals != NULL); |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("strict function, index within formals (%d < %d)", idx, n_formals)); |
|
|
|
DUK_DDD(DUK_DDDPRINT("strict function, index within formals (%d < %d)", |
|
|
|
(int) idx, (int) n_formals)); |
|
|
|
|
|
|
|
duk_get_prop_index(ctx, i_formals, idx); |
|
|
|
DUK_ASSERT(duk_is_string(ctx, -1)); |
|
|
@ -150,13 +152,15 @@ static void duk__create_arguments_object(duk_hthread *thr, |
|
|
|
|
|
|
|
need_map = 1; |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("set mappednames[%s]=%d", duk_get_string(ctx, -1), idx)); |
|
|
|
DUK_DDD(DUK_DDDPRINT("set mappednames[%s]=%d", |
|
|
|
duk_get_string(ctx, -1), (int) idx)); |
|
|
|
duk_dup(ctx, -1); /* name */ |
|
|
|
duk_push_int(ctx, idx); /* index */ |
|
|
|
duk_to_string(ctx, -1); |
|
|
|
duk_def_prop_wec(ctx, i_mappednames); /* out of spec, must be configurable */ |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("set map[%d]=%s", idx, duk_get_string(ctx, -1))); |
|
|
|
DUK_DDD(DUK_DDDPRINT("set map[%d]=%s", |
|
|
|
(int) idx, duk_get_string(ctx, -1))); |
|
|
|
duk_push_int(ctx, idx); /* index */ |
|
|
|
duk_to_string(ctx, -1); |
|
|
|
duk_dup(ctx, -2); /* name */ |
|
|
@ -250,9 +254,9 @@ static void duk__create_arguments_object(duk_hthread *thr, |
|
|
|
"arguments at index %d -> %!O " |
|
|
|
"map at index %d -> %!O " |
|
|
|
"mappednames at index %d -> %!O", |
|
|
|
i_arg, duk_get_hobject(ctx, i_arg), |
|
|
|
i_map, duk_get_hobject(ctx, i_map), |
|
|
|
i_mappednames, duk_get_hobject(ctx, i_mappednames))); |
|
|
|
(int) i_arg, duk_get_hobject(ctx, i_arg), |
|
|
|
(int) i_map, duk_get_hobject(ctx, i_map), |
|
|
|
(int) i_mappednames, duk_get_hobject(ctx, i_mappednames))); |
|
|
|
|
|
|
|
/* [args(n) [crud] formals arguments map mappednames] -> [args [crud] arguments] */ |
|
|
|
duk_pop_2(ctx); |
|
|
@ -266,7 +270,7 @@ static void duk__create_arguments_object(duk_hthread *thr, |
|
|
|
static void duk__handle_createargs_for_call(duk_hthread *thr, |
|
|
|
duk_hobject *func, |
|
|
|
duk_hobject *env, |
|
|
|
int num_stack_args) { |
|
|
|
duk_idx_t num_stack_args) { |
|
|
|
duk_context *ctx = (duk_context *) thr; |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("creating arguments object for function call")); |
|
|
@ -310,14 +314,14 @@ static void duk__handle_createargs_for_call(duk_hthread *thr, |
|
|
|
*/ |
|
|
|
|
|
|
|
static void duk__handle_bound_chain_for_call(duk_hthread *thr, |
|
|
|
int idx_func, |
|
|
|
int *p_num_stack_args, /* may be changed by call */ |
|
|
|
duk_idx_t idx_func, |
|
|
|
duk_idx_t *p_num_stack_args, /* may be changed by call */ |
|
|
|
duk_hobject **p_func, /* changed by call */ |
|
|
|
int is_constructor_call) { |
|
|
|
duk_bool_t is_constructor_call) { |
|
|
|
duk_context *ctx = (duk_context *) thr; |
|
|
|
int num_stack_args; |
|
|
|
duk_idx_t num_stack_args; |
|
|
|
duk_hobject *func; |
|
|
|
duk_uint32_t sanity; |
|
|
|
duk_uint_t sanity; |
|
|
|
|
|
|
|
DUK_ASSERT(thr != NULL); |
|
|
|
DUK_ASSERT(p_num_stack_args != NULL); |
|
|
@ -330,7 +334,7 @@ static void duk__handle_bound_chain_for_call(duk_hthread *thr, |
|
|
|
|
|
|
|
sanity = DUK_HOBJECT_BOUND_CHAIN_SANITY; |
|
|
|
do { |
|
|
|
int i, len; |
|
|
|
duk_idx_t i, len; |
|
|
|
|
|
|
|
if (!DUK_HOBJECT_HAS_BOUND(func)) { |
|
|
|
break; |
|
|
@ -344,7 +348,7 @@ static void duk__handle_bound_chain_for_call(duk_hthread *thr, |
|
|
|
*/ |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("bound function encountered, ptr=%p, num_stack_args=%d", |
|
|
|
(void *) func, num_stack_args)); |
|
|
|
(void *) func, (int) num_stack_args)); |
|
|
|
|
|
|
|
/* [ ... func this arg1 ... argN ] */ |
|
|
|
|
|
|
@ -361,7 +365,7 @@ static void duk__handle_bound_chain_for_call(duk_hthread *thr, |
|
|
|
/* XXX: duk_get_length? */ |
|
|
|
duk_get_prop_stridx(ctx, idx_func, DUK_STRIDX_INT_ARGS); /* -> [ ... func this arg1 ... argN _args ] */ |
|
|
|
duk_get_prop_stridx(ctx, -1, DUK_STRIDX_LENGTH); /* -> [ ... func this arg1 ... argN _args length ] */ |
|
|
|
len = duk_require_int(ctx, -1); |
|
|
|
len = (duk_idx_t) duk_require_int(ctx, -1); |
|
|
|
duk_pop(ctx); |
|
|
|
for (i = 0; i < len; i++) { |
|
|
|
/* XXX: very slow - better to bulk allocate a gap, and copy
|
|
|
@ -547,7 +551,7 @@ static void duk__update_func_caller_prop(duk_hthread *thr, duk_hobject *func) { |
|
|
|
|
|
|
|
static void duk__coerce_effective_this_binding(duk_hthread *thr, |
|
|
|
duk_hobject *func, |
|
|
|
int idx_this) { |
|
|
|
duk_idx_t idx_this) { |
|
|
|
duk_context *ctx = (duk_context *) thr; |
|
|
|
|
|
|
|
if (DUK_HOBJECT_HAS_STRICT(func)) { |
|
|
@ -621,30 +625,30 @@ static void duk__coerce_effective_this_binding(duk_hthread *thr, |
|
|
|
* call are not guaranteed to keep their value. |
|
|
|
*/ |
|
|
|
|
|
|
|
int duk_handle_call(duk_hthread *thr, |
|
|
|
int num_stack_args, |
|
|
|
int call_flags) { |
|
|
|
duk_int_t duk_handle_call(duk_hthread *thr, |
|
|
|
duk_idx_t num_stack_args, |
|
|
|
duk_small_uint_t call_flags) { |
|
|
|
duk_context *ctx = (duk_context *) thr; |
|
|
|
duk_size_t entry_valstack_bottom_index; |
|
|
|
duk_size_t entry_callstack_top; |
|
|
|
duk_size_t entry_catchstack_top; |
|
|
|
int entry_call_recursion_depth; |
|
|
|
duk_int_t entry_call_recursion_depth; |
|
|
|
duk_hthread *entry_curr_thread; |
|
|
|
duk_uint8_t entry_thread_state; |
|
|
|
volatile int need_setjmp; |
|
|
|
duk_uint_fast8_t entry_thread_state; |
|
|
|
volatile duk_bool_t need_setjmp; |
|
|
|
duk_jmpbuf * volatile old_jmpbuf_ptr = NULL; /* ptr is volatile (not the target) */ |
|
|
|
int idx_func; /* valstack index of 'func' and retval (relative to entry valstack_bottom) */ |
|
|
|
int idx_args; /* valstack index of start of args (arg1) (relative to entry valstack_bottom) */ |
|
|
|
int nargs; /* # argument registers target function wants (< 0 => "as is") */ |
|
|
|
int nregs; /* # total registers target function wants on entry (< 0 => "as is") */ |
|
|
|
unsigned int vs_min_size; /* FIXME: type */ |
|
|
|
duk_idx_t idx_func; /* valstack index of 'func' and retval (relative to entry valstack_bottom) */ |
|
|
|
duk_idx_t idx_args; /* valstack index of start of args (arg1) (relative to entry valstack_bottom) */ |
|
|
|
duk_idx_t nargs; /* # argument registers target function wants (< 0 => "as is") */ |
|
|
|
duk_idx_t nregs; /* # total registers target function wants on entry (< 0 => "as is") */ |
|
|
|
duk_size_t vs_min_size; |
|
|
|
duk_hobject *func; /* 'func' on stack (borrowed reference) */ |
|
|
|
duk_activation *act; |
|
|
|
duk_hobject *env; |
|
|
|
duk_jmpbuf our_jmpbuf; |
|
|
|
duk_tval tv_tmp; |
|
|
|
int retval = DUK_EXEC_ERROR; |
|
|
|
int rc; |
|
|
|
duk_int_t retval = DUK_EXEC_ERROR; |
|
|
|
duk_ret_t rc; |
|
|
|
|
|
|
|
DUK_ASSERT(thr != NULL); |
|
|
|
DUK_ASSERT(ctx != NULL); |
|
|
@ -684,23 +688,23 @@ int duk_handle_call(duk_hthread *thr, |
|
|
|
"entry_valstack_bottom_index=%d, entry_callstack_top=%d, entry_catchstack_top=%d, " |
|
|
|
"entry_call_recursion_depth=%d, entry_curr_thread=%p, entry_thread_state=%d", |
|
|
|
(void *) thr, |
|
|
|
num_stack_args, |
|
|
|
call_flags, |
|
|
|
((call_flags & DUK_CALL_FLAG_PROTECTED) != 0 ? 1 : 0), |
|
|
|
((call_flags & DUK_CALL_FLAG_IGNORE_RECLIMIT) != 0 ? 1 : 0), |
|
|
|
((call_flags & DUK_CALL_FLAG_CONSTRUCTOR_CALL) != 0 ? 1 : 0), |
|
|
|
need_setjmp, |
|
|
|
duk_get_top(ctx), |
|
|
|
idx_func, |
|
|
|
idx_args, |
|
|
|
thr->heap->call_recursion_depth, |
|
|
|
thr->heap->call_recursion_limit, |
|
|
|
entry_valstack_bottom_index, |
|
|
|
entry_callstack_top, |
|
|
|
entry_catchstack_top, |
|
|
|
entry_call_recursion_depth, |
|
|
|
(int) num_stack_args, |
|
|
|
(int) call_flags, |
|
|
|
(int) ((call_flags & DUK_CALL_FLAG_PROTECTED) != 0 ? 1 : 0), |
|
|
|
(int) ((call_flags & DUK_CALL_FLAG_IGNORE_RECLIMIT) != 0 ? 1 : 0), |
|
|
|
(int) ((call_flags & DUK_CALL_FLAG_CONSTRUCTOR_CALL) != 0 ? 1 : 0), |
|
|
|
(int) need_setjmp, |
|
|
|
(int) duk_get_top(ctx), |
|
|
|
(int) idx_func, |
|
|
|
(int) idx_args, |
|
|
|
(int) thr->heap->call_recursion_depth, |
|
|
|
(int) thr->heap->call_recursion_limit, |
|
|
|
(int) entry_valstack_bottom_index, |
|
|
|
(int) entry_callstack_top, |
|
|
|
(int) entry_catchstack_top, |
|
|
|
(int) entry_call_recursion_depth, |
|
|
|
(void *) entry_curr_thread, |
|
|
|
entry_thread_state)); |
|
|
|
(int) entry_thread_state)); |
|
|
|
|
|
|
|
#ifdef DUK_USE_DDDPRINT /*XXX:incorrect*/ |
|
|
|
DUK_D(DUK_DPRINT("callstack before call setup:")); |
|
|
@ -1205,7 +1209,7 @@ int duk_handle_call(duk_hthread *thr, |
|
|
|
} |
|
|
|
/* [... func this (crud) retval] */ |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("native call retval -> %!T (rc=%d)", duk_get_tval(ctx, -1), rc)); |
|
|
|
DUK_DDD(DUK_DDDPRINT("native call retval -> %!T (rc=%d)", duk_get_tval(ctx, -1), (int) rc)); |
|
|
|
|
|
|
|
duk_replace(ctx, idx_func); |
|
|
|
duk_set_top(ctx, idx_func + 1); |
|
|
@ -1342,7 +1346,7 @@ int duk_handle_call(duk_hthread *thr, |
|
|
|
} |
|
|
|
|
|
|
|
DUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread); /* may be NULL */ |
|
|
|
thr->state = entry_thread_state; |
|
|
|
thr->state = (duk_uint8_t) entry_thread_state; |
|
|
|
|
|
|
|
DUK_ASSERT((thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread == NULL) || /* first call */ |
|
|
|
(thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread != NULL) || /* other call */ |
|
|
@ -1353,7 +1357,7 @@ int duk_handle_call(duk_hthread *thr, |
|
|
|
return retval; |
|
|
|
|
|
|
|
thread_state_error: |
|
|
|
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "invalid thread state for call (%d)", thr->state); |
|
|
|
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "invalid thread state for call (%d)", (int) thr->state); |
|
|
|
DUK_UNREACHABLE(); |
|
|
|
return DUK_EXEC_ERROR; /* never executed */ |
|
|
|
} |
|
|
@ -1368,9 +1372,9 @@ int duk_handle_call(duk_hthread *thr, |
|
|
|
* empty (below idx_retbase). |
|
|
|
*/ |
|
|
|
|
|
|
|
static void duk__safe_call_adjust_valstack(duk_hthread *thr, int idx_retbase, int num_stack_rets, int num_actual_rets) { |
|
|
|
static void duk__safe_call_adjust_valstack(duk_hthread *thr, duk_idx_t idx_retbase, duk_idx_t num_stack_rets, duk_idx_t num_actual_rets) { |
|
|
|
duk_context *ctx = (duk_context *) thr; |
|
|
|
int idx_rcbase; |
|
|
|
duk_idx_t idx_rcbase; |
|
|
|
|
|
|
|
DUK_ASSERT(thr != NULL); |
|
|
|
DUK_ASSERT(idx_retbase >= 0); |
|
|
@ -1381,7 +1385,8 @@ static void duk__safe_call_adjust_valstack(duk_hthread *thr, int idx_retbase, in |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("adjust valstack after func call: " |
|
|
|
"num_stack_rets=%d, num_actual_rets=%d, stack_top=%d, idx_retbase=%d, idx_rcbase=%d", |
|
|
|
num_stack_rets, num_actual_rets, duk_get_top(ctx), idx_retbase, idx_rcbase)); |
|
|
|
(int) num_stack_rets, (int) num_actual_rets, (int) duk_get_top(ctx), |
|
|
|
(int) idx_retbase, (int) idx_rcbase)); |
|
|
|
|
|
|
|
DUK_ASSERT(idx_rcbase >= 0); /* caller must check */ |
|
|
|
|
|
|
@ -1396,11 +1401,11 @@ static void duk__safe_call_adjust_valstack(duk_hthread *thr, int idx_retbase, in |
|
|
|
duk_set_top(ctx, idx_rcbase + num_stack_rets); |
|
|
|
|
|
|
|
if (idx_rcbase >= idx_retbase) { |
|
|
|
int count = idx_rcbase - idx_retbase; |
|
|
|
int i; |
|
|
|
duk_idx_t count = idx_rcbase - idx_retbase; |
|
|
|
duk_idx_t i; |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("elements at/after idx_retbase have enough to cover func retvals " |
|
|
|
"(idx_retbase=%d, idx_rcbase=%d)", idx_retbase, idx_rcbase)); |
|
|
|
"(idx_retbase=%d, idx_rcbase=%d)", (int) idx_retbase, (int) idx_rcbase)); |
|
|
|
|
|
|
|
/* nuke values at idx_retbase to get the first retval (initially
|
|
|
|
* at idx_rcbase) to idx_retbase |
|
|
@ -1413,11 +1418,11 @@ static void duk__safe_call_adjust_valstack(duk_hthread *thr, int idx_retbase, in |
|
|
|
duk_remove(ctx, idx_retbase); |
|
|
|
} |
|
|
|
} else { |
|
|
|
int count = idx_retbase - idx_rcbase; |
|
|
|
int i; |
|
|
|
duk_idx_t count = idx_retbase - idx_rcbase; |
|
|
|
duk_idx_t i; |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("not enough elements at/after idx_retbase to cover func retvals " |
|
|
|
"(idx_retbase=%d, idx_rcbase=%d)", idx_retbase, idx_rcbase)); |
|
|
|
"(idx_retbase=%d, idx_rcbase=%d)", (int) idx_retbase, (int) idx_rcbase)); |
|
|
|
|
|
|
|
/* insert 'undefined' values at idx_rcbase to get the
|
|
|
|
* return values to idx_retbase |
|
|
@ -1456,29 +1461,29 @@ static void duk__safe_call_adjust_valstack(duk_hthread *thr, int idx_retbase, in |
|
|
|
|
|
|
|
/* FIXME: bump preventcount by one for the duration of this call? */ |
|
|
|
|
|
|
|
int duk_handle_safe_call(duk_hthread *thr, |
|
|
|
duk_safe_call_function func, |
|
|
|
int num_stack_args, |
|
|
|
int num_stack_rets) { |
|
|
|
duk_int_t duk_handle_safe_call(duk_hthread *thr, |
|
|
|
duk_safe_call_function func, |
|
|
|
duk_idx_t num_stack_args, |
|
|
|
duk_idx_t num_stack_rets) { |
|
|
|
duk_context *ctx = (duk_context *) thr; |
|
|
|
duk_size_t entry_valstack_bottom_index; |
|
|
|
duk_size_t entry_callstack_top; |
|
|
|
duk_size_t entry_catchstack_top; |
|
|
|
int entry_call_recursion_depth; |
|
|
|
duk_int_t entry_call_recursion_depth; |
|
|
|
duk_hthread *entry_curr_thread; |
|
|
|
duk_uint8_t entry_thread_state; |
|
|
|
duk_uint_fast8_t entry_thread_state; |
|
|
|
duk_jmpbuf *old_jmpbuf_ptr = NULL; |
|
|
|
duk_jmpbuf our_jmpbuf; |
|
|
|
duk_tval tv_tmp; |
|
|
|
int idx_retbase; |
|
|
|
int retval; |
|
|
|
int rc; |
|
|
|
duk_idx_t idx_retbase; |
|
|
|
duk_int_t retval; |
|
|
|
duk_ret_t rc; |
|
|
|
|
|
|
|
DUK_ASSERT(thr != NULL); |
|
|
|
DUK_ASSERT(ctx != NULL); |
|
|
|
|
|
|
|
/* Note: careful with indices like '-x'; if 'x' is zero, it refers to bottom */ |
|
|
|
entry_valstack_bottom_index = (int) (thr->valstack_bottom - thr->valstack); |
|
|
|
entry_valstack_bottom_index = (duk_size_t) (thr->valstack_bottom - thr->valstack); |
|
|
|
entry_callstack_top = thr->callstack_top; |
|
|
|
entry_catchstack_top = thr->catchstack_top; |
|
|
|
entry_call_recursion_depth = thr->heap->call_recursion_depth; |
|
|
@ -1491,11 +1496,19 @@ int duk_handle_safe_call(duk_hthread *thr, |
|
|
|
"valstack_top=%d, idx_retbase=%d, rec_depth=%d/%d, " |
|
|
|
"entry_valstack_bottom_index=%d, entry_callstack_top=%d, entry_catchstack_top=%d, " |
|
|
|
"entry_call_recursion_depth=%d, entry_curr_thread=%p, entry_thread_state=%d", |
|
|
|
(void *) thr, num_stack_args, num_stack_rets, |
|
|
|
duk_get_top(ctx), idx_retbase, thr->heap->call_recursion_depth, |
|
|
|
thr->heap->call_recursion_limit, entry_valstack_bottom_index, |
|
|
|
entry_callstack_top, entry_catchstack_top, entry_call_recursion_depth, |
|
|
|
entry_curr_thread, entry_thread_state)); |
|
|
|
(void *) thr, |
|
|
|
(int) num_stack_args, |
|
|
|
(int) num_stack_rets, |
|
|
|
(int) duk_get_top(ctx), |
|
|
|
(int) idx_retbase, |
|
|
|
(int) thr->heap->call_recursion_depth, |
|
|
|
(int) thr->heap->call_recursion_limit, |
|
|
|
(int) entry_valstack_bottom_index, |
|
|
|
(int) entry_callstack_top, |
|
|
|
(int) entry_catchstack_top, |
|
|
|
(int) entry_call_recursion_depth, |
|
|
|
(void *) entry_curr_thread, |
|
|
|
(int) entry_thread_state)); |
|
|
|
|
|
|
|
if (idx_retbase < 0) { |
|
|
|
/*
|
|
|
@ -1703,7 +1716,7 @@ int duk_handle_safe_call(duk_hthread *thr, |
|
|
|
* uncaught error. |
|
|
|
*/ |
|
|
|
DUK_HEAP_SWITCH_THREAD(thr->heap, entry_curr_thread); /* may be NULL */ |
|
|
|
thr->state = entry_thread_state; |
|
|
|
thr->state = (duk_uint8_t) entry_thread_state; |
|
|
|
|
|
|
|
DUK_ASSERT((thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread == NULL) || /* first call */ |
|
|
|
(thr->state == DUK_HTHREAD_STATE_INACTIVE && thr->heap->curr_thread != NULL) || /* other call */ |
|
|
@ -1717,7 +1730,7 @@ int duk_handle_safe_call(duk_hthread *thr, |
|
|
|
return retval; |
|
|
|
|
|
|
|
thread_state_error: |
|
|
|
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "invalid thread state for safe_call (%d)", thr->state); |
|
|
|
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "invalid thread state for safe_call (%d)", (int) thr->state); |
|
|
|
DUK_UNREACHABLE(); |
|
|
|
return DUK_EXEC_ERROR; /* never executed */ |
|
|
|
} |
|
|
@ -1744,18 +1757,18 @@ int duk_handle_safe_call(duk_hthread *thr, |
|
|
|
*/ |
|
|
|
|
|
|
|
void duk_handle_ecma_call_setup(duk_hthread *thr, |
|
|
|
int num_stack_args, |
|
|
|
int call_flags) { |
|
|
|
duk_idx_t num_stack_args, |
|
|
|
duk_small_uint_t call_flags) { |
|
|
|
duk_context *ctx = (duk_context *) thr; |
|
|
|
int entry_valstack_bottom_index; |
|
|
|
int idx_func; /* valstack index of 'func' and retval (relative to entry valstack_bottom) */ |
|
|
|
int idx_args; /* valstack index of start of args (arg1) (relative to entry valstack_bottom) */ |
|
|
|
int nargs; /* # argument registers target function wants (< 0 => never for ecma calls) */ |
|
|
|
int nregs; /* # total registers target function wants on entry (< 0 => never for ecma calls) */ |
|
|
|
duk_hobject *func; /* 'func' on stack (borrowed reference) */ |
|
|
|
duk_size_t entry_valstack_bottom_index; |
|
|
|
duk_idx_t idx_func; /* valstack index of 'func' and retval (relative to entry valstack_bottom) */ |
|
|
|
duk_idx_t idx_args; /* valstack index of start of args (arg1) (relative to entry valstack_bottom) */ |
|
|
|
duk_idx_t nargs; /* # argument registers target function wants (< 0 => never for ecma calls) */ |
|
|
|
duk_idx_t nregs; /* # total registers target function wants on entry (< 0 => never for ecma calls) */ |
|
|
|
duk_hobject *func; /* 'func' on stack (borrowed reference) */ |
|
|
|
duk_activation *act; |
|
|
|
duk_hobject *env; |
|
|
|
int use_tailcall; |
|
|
|
duk_bool_t use_tailcall; |
|
|
|
|
|
|
|
DUK_ASSERT(thr != NULL); |
|
|
|
DUK_ASSERT(ctx != NULL); |
|
|
@ -1800,7 +1813,7 @@ void duk_handle_ecma_call_setup(duk_hthread *thr, |
|
|
|
} |
|
|
|
#endif /* DUK_USE_ASSERTIONS */ |
|
|
|
|
|
|
|
entry_valstack_bottom_index = (int) (thr->valstack_bottom - thr->valstack); |
|
|
|
entry_valstack_bottom_index = (duk_size_t) (thr->valstack_bottom - thr->valstack); |
|
|
|
idx_func = duk_normalize_index(thr, -num_stack_args - 2); |
|
|
|
idx_args = idx_func + 2; |
|
|
|
|
|
|
@ -1808,13 +1821,13 @@ void duk_handle_ecma_call_setup(duk_hthread *thr, |
|
|
|
"num_stack_args=%d, call_flags=%d (resume=%d, tailcall=%d), " |
|
|
|
"idx_func=%d, idx_args=%d, entry_valstack_bottom_index=%d", |
|
|
|
(void *) thr, |
|
|
|
num_stack_args, |
|
|
|
call_flags, |
|
|
|
((call_flags & DUK_CALL_FLAG_IS_RESUME) != 0 ? 1 : 0), |
|
|
|
((call_flags & DUK_CALL_FLAG_IS_TAILCALL) != 0 ? 1 : 0), |
|
|
|
idx_func, |
|
|
|
idx_args, |
|
|
|
entry_valstack_bottom_index)); |
|
|
|
(int) num_stack_args, |
|
|
|
(int) call_flags, |
|
|
|
(int) ((call_flags & DUK_CALL_FLAG_IS_RESUME) != 0 ? 1 : 0), |
|
|
|
(int) ((call_flags & DUK_CALL_FLAG_IS_TAILCALL) != 0 ? 1 : 0), |
|
|
|
(int) idx_func, |
|
|
|
(int) idx_args, |
|
|
|
(int) entry_valstack_bottom_index)); |
|
|
|
|
|
|
|
#ifdef DUK_USE_DDDPRINT /*XXX:incorrect*/ |
|
|
|
DUK_D(DUK_DPRINT("callstack before call setup:")); |
|
|
@ -1899,7 +1912,7 @@ void duk_handle_ecma_call_setup(duk_hthread *thr, |
|
|
|
duk_tval *tv1, *tv2; |
|
|
|
duk_tval tv_tmp; |
|
|
|
duk_size_t cs_index; |
|
|
|
int i; |
|
|
|
duk_idx_t i; |
|
|
|
|
|
|
|
/*
|
|
|
|
* Tailcall handling |
|
|
@ -2172,4 +2185,3 @@ void duk_handle_ecma_call_setup(duk_hthread *thr, |
|
|
|
* the topmost activation. |
|
|
|
*/ |
|
|
|
} |
|
|
|
|
|
|
|