зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1259877 - Add CallFromStack for certain internal users, js::Call for general use, and mark js::Invoke as deprecated. r=efaust
--HG-- extra : rebase_source : 4e2d82e18da373cc7ab7ba30e86af2f777665794
This commit is contained in:
Родитель
525e0715b0
Коммит
20b04cbd46
|
@ -501,24 +501,17 @@ js::InternalCallOrConstruct(JSContext* cx, const CallArgs& args, MaybeConstruct
|
|||
return ok;
|
||||
}
|
||||
|
||||
bool
|
||||
js::Invoke(JSContext* cx, const Value& thisv, const Value& fval, unsigned argc, const Value* argv,
|
||||
MutableHandleValue rval)
|
||||
static bool
|
||||
InternalCall(JSContext* cx, const AnyInvokeArgs& args)
|
||||
{
|
||||
InvokeArgs args(cx);
|
||||
if (!args.init(argc))
|
||||
return false;
|
||||
|
||||
args.setCallee(fval);
|
||||
args.setThis(thisv);
|
||||
PodCopy(args.array(), argv, argc);
|
||||
MOZ_ASSERT(args.array() + args.length() == args.end(),
|
||||
"must pass calling arguments to a calling attempt");
|
||||
|
||||
if (args.thisv().isObject()) {
|
||||
/*
|
||||
* We must call the thisValue hook in case we are not called from the
|
||||
* interpreter, where a prior bytecode has computed an appropriate
|
||||
* |this| already. But don't do that if fval is a DOM function.
|
||||
*/
|
||||
// We must call the thisValue hook in case we are not called from the
|
||||
// interpreter, where a prior bytecode has computed an appropriate
|
||||
// |this| already. But don't do that if fval is a DOM function.
|
||||
HandleValue fval = args.calleev();
|
||||
if (!fval.isObject() || !fval.toObject().is<JSFunction>() ||
|
||||
!fval.toObject().as<JSFunction>().isNative() ||
|
||||
!fval.toObject().as<JSFunction>().jitInfo() ||
|
||||
|
@ -529,13 +522,50 @@ js::Invoke(JSContext* cx, const Value& thisv, const Value& fval, unsigned argc,
|
|||
}
|
||||
}
|
||||
|
||||
if (!InternalCallOrConstruct(cx, args, NO_CONSTRUCT))
|
||||
return InternalCallOrConstruct(cx, args, NO_CONSTRUCT);
|
||||
}
|
||||
|
||||
static bool
|
||||
CallFromStack(JSContext* cx, const CallArgs& args)
|
||||
{
|
||||
return InternalCall(cx, static_cast<const AnyInvokeArgs&>(args));
|
||||
}
|
||||
|
||||
// ES7 rev 0c1bd3004329336774cbc90de727cd0cf5f11e93 7.3.12 Call.
|
||||
bool
|
||||
js::Call(JSContext* cx, HandleValue fval, HandleValue thisv, const AnyInvokeArgs& args,
|
||||
MutableHandleValue rval)
|
||||
{
|
||||
// Explicitly qualify these methods to bypass AnyInvokeArgs's deliberate
|
||||
// shadowing.
|
||||
args.CallArgs::setCallee(fval);
|
||||
args.CallArgs::setThis(thisv);
|
||||
|
||||
if (!InternalCall(cx, args))
|
||||
return false;
|
||||
|
||||
rval.set(args.rval());
|
||||
return true;
|
||||
}
|
||||
|
||||
// DEPRECATED. TO BE REMOVED. DO NOT ADD NEW USES.
|
||||
bool
|
||||
js::Invoke(JSContext* cx, const Value& thisv, const Value& fval, unsigned argc, const Value* argv,
|
||||
MutableHandleValue rval)
|
||||
{
|
||||
RootedValue fv(cx, fval);
|
||||
RootedValue tv(cx, thisv);
|
||||
|
||||
InvokeArgs args(cx);
|
||||
if (!args.init(argc))
|
||||
return false;
|
||||
|
||||
for (unsigned i = 0; i < argc; i++)
|
||||
args[i].set(argv[i]);
|
||||
|
||||
return Call(cx, fv, tv, args, rval);
|
||||
}
|
||||
|
||||
static bool
|
||||
InternalConstruct(JSContext* cx, const AnyConstructArgs& args)
|
||||
{
|
||||
|
@ -639,7 +669,9 @@ js::CallGetter(JSContext* cx, HandleValue thisv, HandleValue getter, MutableHand
|
|||
// bug 355497.
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
return Invoke(cx, thisv, getter, 0, nullptr, rval);
|
||||
FixedInvokeArgs<0> args(cx);
|
||||
|
||||
return Call(cx, getter, thisv, args, rval);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -647,8 +679,12 @@ js::CallSetter(JSContext* cx, HandleValue thisv, HandleValue setter, HandleValue
|
|||
{
|
||||
JS_CHECK_RECURSION(cx, return false);
|
||||
|
||||
FixedInvokeArgs<1> args(cx);
|
||||
|
||||
args[0].set(v);
|
||||
|
||||
RootedValue ignored(cx);
|
||||
return Invoke(cx, thisv, setter, 1, v.address(), &ignored);
|
||||
return Call(cx, setter, thisv, args, &ignored);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2728,7 +2764,7 @@ CASE(JSOP_STRICTEVAL)
|
|||
if (!DirectEval(cx, args.get(0), args.rval()))
|
||||
goto error;
|
||||
} else {
|
||||
if (!InternalInvoke(cx, args))
|
||||
if (!CallFromStack(cx, args))
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
@ -2810,7 +2846,7 @@ CASE(JSOP_FUNCALL)
|
|||
ReportValueError(cx, JSMSG_NOT_ITERABLE, -1, args.thisv(), nullptr);
|
||||
goto error;
|
||||
}
|
||||
if (!InternalInvoke(cx, args))
|
||||
if (!CallFromStack(cx, args))
|
||||
goto error;
|
||||
}
|
||||
Value* newsp = args.spAfterCall();
|
||||
|
@ -4616,35 +4652,25 @@ js::SpreadCallOperation(JSContext* cx, HandleScript script, jsbytecode* pc, Hand
|
|||
res.setObject(*obj);
|
||||
} else {
|
||||
InvokeArgs args(cx);
|
||||
|
||||
if (!args.init(length))
|
||||
return false;
|
||||
|
||||
args.setCallee(callee);
|
||||
args.setThis(thisv);
|
||||
|
||||
if (!GetElements(cx, aobj, length, args.array()))
|
||||
return false;
|
||||
|
||||
switch (op) {
|
||||
case JSOP_SPREADCALL:
|
||||
if (!Invoke(cx, args))
|
||||
if ((op == JSOP_SPREADEVAL || op == JSOP_STRICTSPREADEVAL) &&
|
||||
cx->global()->valueIsEval(callee))
|
||||
{
|
||||
if (!DirectEval(cx, args.get(0), res))
|
||||
return false;
|
||||
} else {
|
||||
MOZ_ASSERT(op == JSOP_SPREADCALL ||
|
||||
op == JSOP_SPREADEVAL ||
|
||||
op == JSOP_STRICTSPREADEVAL,
|
||||
"bad spread opcode");
|
||||
|
||||
if (!Call(cx, callee, thisv, args, res))
|
||||
return false;
|
||||
res.set(args.rval());
|
||||
break;
|
||||
case JSOP_SPREADEVAL:
|
||||
case JSOP_STRICTSPREADEVAL:
|
||||
if (cx->global()->valueIsEval(callee)) {
|
||||
if (!DirectEval(cx, args.get(0), res))
|
||||
return false;
|
||||
} else {
|
||||
if (!Invoke(cx, args))
|
||||
return false;
|
||||
res.set(args.rval());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("bad spread opcode");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,11 +83,7 @@ InternalInvoke(JSContext* cx, const CallArgs& args)
|
|||
return InternalCallOrConstruct(cx, args, NO_CONSTRUCT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to call a value with the provided |this| and arguments. This
|
||||
* function places no requirements on the caller: it may be called at any time,
|
||||
* and it takes care of copying |fval|, |thisv|, and arguments onto the stack.
|
||||
*/
|
||||
// DEPRECATED. TO BE REMOVED. DO NOT ADD NEW USES.
|
||||
extern bool
|
||||
Invoke(JSContext* cx, const Value& thisv, const Value& fval, unsigned argc, const Value* argv,
|
||||
MutableHandleValue rval);
|
||||
|
@ -102,9 +98,24 @@ CallGetter(JSContext* cx, HandleValue thisv, HandleValue getter, MutableHandleVa
|
|||
extern bool
|
||||
CallSetter(JSContext* cx, HandleValue thisv, HandleValue setter, HandleValue rval);
|
||||
|
||||
// ES7 rev 0c1bd3004329336774cbc90de727cd0cf5f11e93 7.3.12 Call(F, V, argumentsList).
|
||||
// All parameters are required, hopefully forcing callers to be careful not to
|
||||
// (say) blindly pass callee as |newTarget| when a different value should have
|
||||
// been passed. Behavior is unspecified if any element of |args| isn't initialized.
|
||||
//
|
||||
// |rval| is written to *only* after |fval| and |thisv| have been consumed, so
|
||||
// |rval| *may* alias either argument.
|
||||
extern bool
|
||||
Call(JSContext* cx, HandleValue fval, HandleValue thisv, const AnyInvokeArgs& args,
|
||||
MutableHandleValue rval);
|
||||
|
||||
// ES6 7.3.13 Construct(F, argumentsList, newTarget). All parameters are
|
||||
// required, hopefully forcing callers to be careful not to (say) blindly pass
|
||||
// callee as |newTarget| when a different value should have been passed.
|
||||
// Behavior is unspecified if any element of |args| isn't initialized.
|
||||
//
|
||||
// |rval| is written to *only* after |fval| and |newTarget| have been consumed,
|
||||
// so |rval| *may* alias either argument.
|
||||
//
|
||||
// NOTE: As with the ES6 spec operation, it's the caller's responsibility to
|
||||
// ensure |fval| and |newTarget| are both |IsConstructor|.
|
||||
|
@ -127,6 +138,9 @@ ConstructFromStack(JSContext* cx, const CallArgs& args);
|
|||
// Call Construct(fval, args, newTarget), but use the given |thisv| as |this|
|
||||
// during construction of |fval|.
|
||||
//
|
||||
// |rval| is written to *only* after |fval|, |thisv|, and |newTarget| have been
|
||||
// consumed, so |rval| *may* alias any of these arguments.
|
||||
//
|
||||
// This method exists only for very rare cases where a |this| was created
|
||||
// caller-side for construction of |fval|: basically only for JITs using
|
||||
// |CreateThis|. If that's not you, use Construct()!
|
||||
|
|
Загрузка…
Ссылка в новой задаче