|
|
@ -11,7 +11,7 @@ |
|
|
|
*/ |
|
|
|
static void duk__call_prop_prep_stack(duk_context *ctx, duk_idx_t normalized_obj_index, duk_idx_t nargs) { |
|
|
|
DUK_DDD(DUK_DDDPRINT("duk__call_prop_prep_stack, normalized_obj_index=%d, nargs=%d, stacktop=%d", |
|
|
|
normalized_obj_index, (int) nargs, (int) duk_get_top(ctx))); |
|
|
|
(int) normalized_obj_index, (int) nargs, (int) duk_get_top(ctx))); |
|
|
|
|
|
|
|
/* [... key arg1 ... argN] */ |
|
|
|
|
|
|
@ -45,10 +45,12 @@ void duk_call(duk_context *ctx, duk_idx_t nargs) { |
|
|
|
idx_func = duk_get_top(ctx) - nargs - 1; /* must work for nargs <= 0 */ |
|
|
|
if (idx_func < 0 || nargs < 0) { |
|
|
|
/* note that we can't reliably pop anything here */ |
|
|
|
DUK_ERROR(thr, DUK_ERR_API_ERROR, "invalid call args"); |
|
|
|
DUK_ERROR(thr, DUK_ERR_API_ERROR, duk_str_invalid_call_args); |
|
|
|
} |
|
|
|
|
|
|
|
/* awkward; we assume there is space for this */ |
|
|
|
/* XXX: awkward; we assume there is space for this, overwrite
|
|
|
|
* directly instead? |
|
|
|
*/ |
|
|
|
duk_push_undefined(ctx); |
|
|
|
duk_insert(ctx, idx_func + 1); |
|
|
|
|
|
|
@ -72,7 +74,7 @@ void duk_call_method(duk_context *ctx, duk_idx_t nargs) { |
|
|
|
idx_func = duk_get_top(ctx) - nargs - 2; /* must work for nargs <= 0 */ |
|
|
|
if (idx_func < 0 || nargs < 0) { |
|
|
|
/* note that we can't reliably pop anything here */ |
|
|
|
DUK_ERROR(thr, DUK_ERR_API_ERROR, "invalid call args"); |
|
|
|
DUK_ERROR(thr, DUK_ERR_API_ERROR, duk_str_invalid_call_args); |
|
|
|
} |
|
|
|
|
|
|
|
call_flags = 0; /* not protected, respect reclimit, not constructor */ |
|
|
@ -119,7 +121,7 @@ duk_int_t duk_pcall(duk_context *ctx, duk_idx_t nargs) { |
|
|
|
* might STILL throw an out-of-memory error or some other internal |
|
|
|
* fatal error. |
|
|
|
*/ |
|
|
|
DUK_ERROR(thr, DUK_ERR_API_ERROR, "invalid call args"); |
|
|
|
DUK_ERROR(thr, DUK_ERR_API_ERROR, duk_str_invalid_call_args); |
|
|
|
return DUK_EXEC_ERROR; /* unreachable */ |
|
|
|
} |
|
|
|
|
|
|
@ -148,7 +150,7 @@ duk_int_t duk_pcall_method(duk_context *ctx, duk_idx_t nargs) { |
|
|
|
idx_func = duk_get_top(ctx) - nargs - 2; /* must work for nargs <= 0 */ |
|
|
|
if (idx_func < 0 || nargs < 0) { |
|
|
|
/* See comments in duk_pcall(). */ |
|
|
|
DUK_ERROR(thr, DUK_ERR_API_ERROR, "invalid call args"); |
|
|
|
DUK_ERROR(thr, DUK_ERR_API_ERROR, duk_str_invalid_call_args); |
|
|
|
return DUK_EXEC_ERROR; /* unreachable */ |
|
|
|
} |
|
|
|
|
|
|
@ -185,8 +187,8 @@ duk_int_t duk_pcall_prop(duk_context *ctx, duk_idx_t obj_index, duk_idx_t nargs) |
|
|
|
* and property lookup, not just the call itself. |
|
|
|
*/ |
|
|
|
|
|
|
|
duk_push_int(ctx, obj_index); /* FIXME: typing */ |
|
|
|
duk_push_int(ctx, nargs); |
|
|
|
duk_push_idx(ctx, obj_index); |
|
|
|
duk_push_idx(ctx, nargs); |
|
|
|
|
|
|
|
/* Inputs: explicit arguments (nargs), +1 for key, +2 for obj_index/nargs passing.
|
|
|
|
* If the value stack does not contain enough args, an error is thrown; this matches |
|
|
@ -204,7 +206,7 @@ duk_int_t duk_safe_call(duk_context *ctx, duk_safe_call_function func, duk_idx_t |
|
|
|
|
|
|
|
if (duk_get_top(ctx) < nargs || nrets < 0) { |
|
|
|
/* See comments in duk_pcall(). */ |
|
|
|
DUK_ERROR(thr, DUK_ERR_API_ERROR, "invalid call args"); |
|
|
|
DUK_ERROR(thr, DUK_ERR_API_ERROR, duk_str_invalid_call_args); |
|
|
|
return DUK_EXEC_ERROR; /* unreachable */ |
|
|
|
} |
|
|
|
|
|
|
@ -244,14 +246,14 @@ void duk_new(duk_context *ctx, duk_idx_t nargs) { |
|
|
|
* |
|
|
|
* This would be easy to fix, e.g. by knowing that the Array constructor |
|
|
|
* will always create a replacement object and skip creating the fallback |
|
|
|
* object in that case. FIXME. |
|
|
|
* object in that case. |
|
|
|
* |
|
|
|
* Note: functions called via "new" need to know they are called as a |
|
|
|
* constructor. For instance, built-in constructors behave differently |
|
|
|
* depending on how they are called. |
|
|
|
*/ |
|
|
|
|
|
|
|
/* FIXME: should this go to duk_js_call.c? it implements core semantics. */ |
|
|
|
/* XXX: should this go to duk_js_call.c? it implements core semantics. */ |
|
|
|
|
|
|
|
duk_hthread *thr = (duk_hthread *) ctx; |
|
|
|
duk_hobject *proto; |
|
|
@ -265,9 +267,10 @@ void duk_new(duk_context *ctx, duk_idx_t nargs) { |
|
|
|
|
|
|
|
idx_cons = duk_require_normalize_index(ctx, -nargs - 1); |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("top=%d, nargs=%d, idx_cons=%d", duk_get_top(ctx), nargs, idx_cons)); |
|
|
|
DUK_DDD(DUK_DDDPRINT("top=%d, nargs=%d, idx_cons=%d", |
|
|
|
(int) duk_get_top(ctx), (int) nargs, (int) idx_cons)); |
|
|
|
|
|
|
|
/* FIXME: code duplication */ |
|
|
|
/* XXX: code duplication */ |
|
|
|
|
|
|
|
/*
|
|
|
|
* Figure out the final, non-bound constructor, to get "prototype" |
|
|
@ -340,7 +343,7 @@ void duk_new(duk_context *ctx, duk_idx_t nargs) { |
|
|
|
DUK_DDD(DUK_DDDPRINT("before call, idx_cons+1 (constructor) -> %!T, idx_cons+2 (fallback/this) -> %!T, " |
|
|
|
"nargs=%d, top=%d", |
|
|
|
duk_get_tval(ctx, idx_cons + 1), duk_get_tval(ctx, idx_cons + 2), |
|
|
|
nargs, duk_get_top(ctx))); |
|
|
|
(int) nargs, (int) duk_get_top(ctx))); |
|
|
|
|
|
|
|
/*
|
|
|
|
* Call the constructor function (called in "constructor mode"). |
|
|
@ -356,7 +359,7 @@ void duk_new(duk_context *ctx, duk_idx_t nargs) { |
|
|
|
/* [... fallback retval] */ |
|
|
|
|
|
|
|
DUK_DDD(DUK_DDDPRINT("constructor call finished, rc=%d, fallback=%!iT, retval=%!iT", |
|
|
|
rc, duk_get_tval(ctx, -2), duk_get_tval(ctx, -1))); |
|
|
|
(int) rc, duk_get_tval(ctx, -2), duk_get_tval(ctx, -1))); |
|
|
|
|
|
|
|
/*
|
|
|
|
* Determine whether to use the constructor return value as the created |
|
|
@ -384,7 +387,7 @@ void duk_new(duk_context *ctx, duk_idx_t nargs) { |
|
|
|
return; |
|
|
|
|
|
|
|
not_constructable: |
|
|
|
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, "not constructable"); |
|
|
|
DUK_ERROR(thr, DUK_ERR_TYPE_ERROR, duk_str_not_constructable); |
|
|
|
} |
|
|
|
|
|
|
|
duk_bool_t duk_is_constructor_call(duk_context *ctx) { |
|
|
@ -442,9 +445,8 @@ duk_int_t duk_get_magic(duk_context *ctx) { |
|
|
|
|
|
|
|
if (DUK_HOBJECT_IS_NATIVEFUNCTION(func)) { |
|
|
|
duk_hnativefunction *nf = (duk_hnativefunction *) func; |
|
|
|
return (int) nf->magic; |
|
|
|
return (duk_int_t) nf->magic; |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|