Bug 852602 - Pass CallArgs to Proxy call() and construct() hooks; r=Waldo

This commit is contained in:
Ms2ger 2013-04-04 09:02:24 +02:00
parent 87b86f2def
commit e38aa0d743
10 changed files with 133 additions and 176 deletions

View File

@ -45,6 +45,18 @@ class JSObject;
typedef JSBool
(* JSNative)(JSContext *cx, unsigned argc, JS::Value *vp);
/*
* Compute |this| for the |vp| inside a JSNative, either boxing primitives or
* replacing with the global object as necessary.
*
* This method will go away at some point: instead use |args.thisv()|. If the
* value is an object, no further work is required. If that value is |null| or
* |undefined|, use |JS_GetGlobalForObject| to compute the global object. If
* the value is some other primitive, use |JS_ValueToObject| to box it.
*/
extern JS_PUBLIC_API(JS::Value)
JS_ComputeThis(JSContext *cx, JS::Value *vp);
namespace JS {
/*
@ -66,7 +78,7 @@ namespace JS {
*
* // It's always fine to access thisv().
* HandleValue thisv = rec.thisv();
* rec.thisv().set(thisv);
* rec.rval().set(thisv);
*
* // As the return value was last set to |this|, returns |this|.
* return true;
@ -130,6 +142,13 @@ class CallReceiver
return HandleValue::fromMarkedLocation(&argv_[-1]);
}
Value computeThis(JSContext *cx) const {
if (thisv().isObject())
return thisv();
return JS_ComputeThis(cx, base());
}
/*
* Returns the currently-set return value. The initial contents of this
* value are unspecified. Once this method has been called, callee() and
@ -242,17 +261,11 @@ class CallArgs : public CallReceiver
}
/* Returns a mutable handle for the i-th zero-indexed argument. */
MutableHandleValue handleAt(unsigned i) {
MutableHandleValue handleAt(unsigned i) const {
MOZ_ASSERT(i < argc_);
return MutableHandleValue::fromMarkedLocation(&argv_[i]);
}
/* Returns a Handle for the i-th zero-indexed argument. */
HandleValue handleAt(unsigned i) const {
MOZ_ASSERT(i < argc_);
return HandleValue::fromMarkedLocation(&argv_[i]);
}
/*
* Returns the i-th zero-indexed argument, or |undefined| if there's no
* such argument.
@ -295,18 +308,6 @@ CallArgsFromSp(unsigned argc, Value *sp)
} // namespace JS
/*
* Compute |this| for the |vp| inside a JSNative, either boxing primitives or
* replacing with the global object as necessary.
*
* This method will go away at some point: instead use |args.thisv()|. If the
* value is an object, no further work is required. If that value is |null| or
* |undefined|, use |JS_GetGlobalForObject| to compute the global object. If
* the value is some other primitive, use |JS_ValueToObject| to box it.
*/
extern JS_PUBLIC_API(JS::Value)
JS_ComputeThis(JSContext *cx, JS::Value *vp);
/*
* Macros to hide interpreter stack layout details from a JSNative using its
* JS::Value *vp parameter. DO NOT USE THESE! Instead use JS::CallArgs and

View File

@ -25,6 +25,7 @@
using namespace js;
using namespace js::gc;
using mozilla::ArrayLength;
static inline HeapSlot &
GetCall(RawObject proxy)
@ -307,16 +308,14 @@ BaseProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned flags, Mut
}
bool
BaseProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned argc,
Value *vp)
BaseProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
JS_NOT_REACHED("callable proxies should implement call trap");
return false;
}
bool
BaseProxyHandler::construct(JSContext *cx, HandleObject proxy, unsigned argc,
Value *argv, MutableHandleValue rval)
BaseProxyHandler::construct(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
JS_NOT_REACHED("callable proxies should implement construct trap");
return false;
@ -476,25 +475,19 @@ DirectProxyHandler::enumerate(JSContext *cx, HandleObject proxy,
}
bool
DirectProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned argc,
Value *vp)
DirectProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
assertEnteredPolicy(cx, proxy, JSID_VOID);
AutoValueRooter rval(cx);
RootedValue target(cx, GetProxyPrivate(proxy));
JSBool ok = Invoke(cx, vp[1], target, argc, JS_ARGV(cx, vp), rval.addr());
if (ok)
JS_SET_RVAL(cx, vp, rval.value());
return ok;
return Invoke(cx, args.thisv(), target, args.length(), args.array(), args.rval().address());
}
bool
DirectProxyHandler::construct(JSContext *cx, HandleObject proxy, unsigned argc,
Value *argv, MutableHandleValue rval)
DirectProxyHandler::construct(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
assertEnteredPolicy(cx, proxy, JSID_VOID);
RootedValue target(cx, GetProxyPrivate(proxy));
return InvokeConstructor(cx, target, argc, argv, rval.address());
return InvokeConstructor(cx, target, args.length(), args.array(), args.rval().address());
}
bool
@ -801,9 +794,8 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler
/* Spidermonkey extensions. */
virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, unsigned argc,
Value *argv, MutableHandleValue rval) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
CallArgs args) MOZ_OVERRIDE;
virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) MOZ_OVERRIDE;
@ -1020,27 +1012,21 @@ ScriptedIndirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigne
}
bool
ScriptedIndirectProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned argc,
Value *vp)
ScriptedIndirectProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
assertEnteredPolicy(cx, proxy, JSID_VOID);
AutoValueRooter rval(cx);
RootedValue call(cx, GetCall(proxy));
JSBool ok = Invoke(cx, vp[1], call, argc, JS_ARGV(cx, vp), rval.addr());
if (ok)
JS_SET_RVAL(cx, vp, rval.value());
return ok;
return Invoke(cx, args.thisv(), call, args.length(), args.array(), args.rval().address());
}
bool
ScriptedIndirectProxyHandler::construct(JSContext *cx, HandleObject proxy, unsigned argc,
Value *argv, MutableHandleValue rval)
ScriptedIndirectProxyHandler::construct(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
assertEnteredPolicy(cx, proxy, JSID_VOID);
RootedValue fval(cx, GetConstruct(proxy));
if (fval.isUndefined())
fval = GetCall(proxy);
return InvokeConstructor(cx, fval, argc, argv, rval.address());
return InvokeConstructor(cx, fval, args.length(), args.array(), args.rval().address());
}
bool
@ -1115,9 +1101,8 @@ class ScriptedDirectProxyHandler : public DirectProxyHandler {
virtual bool iterate(JSContext *cx, HandleObject proxy, unsigned flags,
MutableHandleValue vp) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, unsigned argc, Value *argv,
MutableHandleValue rval) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
static ScriptedDirectProxyHandler singleton;
};
@ -2210,7 +2195,7 @@ ScriptedDirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigned
}
bool
ScriptedDirectProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp)
ScriptedDirectProxyHandler::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
// step 1
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
@ -2224,8 +2209,8 @@ ScriptedDirectProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned arg
*/
// step 3
RootedObject args(cx, NewDenseCopiedArray(cx, argc, vp + 2));
if (!args)
RootedObject argsArray(cx, NewDenseCopiedArray(cx, args.length(), args.array()));
if (!argsArray)
return false;
// step 4
@ -2235,21 +2220,20 @@ ScriptedDirectProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned arg
// step 5
if (trap.isUndefined())
return DirectProxyHandler::call(cx, proxy, argc, vp);
return DirectProxyHandler::call(cx, proxy, args);
// step 6
Value argv[] = {
ObjectValue(*target),
vp[1],
ObjectValue(*args)
args.thisv(),
ObjectValue(*argsArray)
};
RootedValue thisValue(cx, ObjectValue(*handler));
return Invoke(cx, thisValue, trap, 3, argv, vp);
return Invoke(cx, thisValue, trap, ArrayLength(argv), argv, args.rval().address());
}
bool
ScriptedDirectProxyHandler::construct(JSContext *cx, HandleObject proxy, unsigned argc, Value *argv,
MutableHandleValue rval)
ScriptedDirectProxyHandler::construct(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
// step 1
RootedObject handler(cx, GetDirectProxyHandlerObject(proxy));
@ -2263,8 +2247,8 @@ ScriptedDirectProxyHandler::construct(JSContext *cx, HandleObject proxy, unsigne
*/
// step 3
RootedObject args(cx, NewDenseCopiedArray(cx, argc, argv));
if (!args)
RootedObject argsArray(cx, NewDenseCopiedArray(cx, args.length(), args.array()));
if (!argsArray)
return false;
// step 4
@ -2274,15 +2258,16 @@ ScriptedDirectProxyHandler::construct(JSContext *cx, HandleObject proxy, unsigne
// step 5
if (trap.isUndefined())
return DirectProxyHandler::construct(cx, proxy, argc, argv, rval);
return DirectProxyHandler::construct(cx, proxy, args);
// step 6
Value constructArgv[] = {
ObjectValue(*target),
ObjectValue(*args)
ObjectValue(*argsArray)
};
RootedValue thisValue(cx, ObjectValue(*handler));
return Invoke(cx, thisValue, trap, 2, constructArgv, rval.address());
return Invoke(cx, thisValue, trap, ArrayLength(constructArgv), constructArgv,
args.rval().address());
}
ScriptedDirectProxyHandler ScriptedDirectProxyHandler::singleton;
@ -2611,7 +2596,7 @@ Proxy::preventExtensions(JSContext *cx, HandleObject proxy)
}
bool
Proxy::call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp)
Proxy::call(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
JS_CHECK_RECURSION(cx, return false);
BaseProxyHandler *handler = GetProxyHandler(proxy);
@ -2622,16 +2607,15 @@ Proxy::call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp)
AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
BaseProxyHandler::CALL, true);
if (!policy.allowed()) {
vp->setUndefined();
args.rval().setUndefined();
return policy.returnValue();
}
return handler->call(cx, proxy, argc, vp);
return handler->call(cx, proxy, args);
}
bool
Proxy::construct(JSContext *cx, HandleObject proxy, unsigned argc, Value *argv,
MutableHandleValue rval)
Proxy::construct(JSContext *cx, HandleObject proxy, const CallArgs &args)
{
JS_CHECK_RECURSION(cx, return false);
BaseProxyHandler *handler = GetProxyHandler(proxy);
@ -2642,11 +2626,11 @@ Proxy::construct(JSContext *cx, HandleObject proxy, unsigned argc, Value *argv,
AutoEnterPolicy policy(cx, handler, proxy, JS::JSID_VOIDHANDLE,
BaseProxyHandler::CALL, true);
if (!policy.allowed()) {
rval.setUndefined();
args.rval().setUndefined();
return policy.returnValue();
}
return handler->construct(cx, proxy, argc, argv, rval);
return handler->construct(cx, proxy, args);
}
bool
@ -3192,21 +3176,19 @@ JS_FRIEND_DATA(Class) js::OuterWindowProxyClass = {
static JSBool
proxy_Call(JSContext *cx, unsigned argc, Value *vp)
{
RootedObject proxy(cx, &JS_CALLEE(cx, vp).toObject());
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject proxy(cx, &args.callee());
JS_ASSERT(proxy->isProxy());
return Proxy::call(cx, proxy, argc, vp);
return Proxy::call(cx, proxy, args);
}
static JSBool
proxy_Construct(JSContext *cx, unsigned argc, Value *vp)
{
RootedObject proxy(cx, &JS_CALLEE(cx, vp).toObject());
CallArgs args = CallArgsFromVp(argc, vp);
RootedObject proxy(cx, &args.callee());
JS_ASSERT(proxy->isProxy());
RootedValue rval(cx, *vp);
if (!Proxy::construct(cx, proxy, argc, JS_ARGV(cx, vp), &rval))
return false;
*vp = rval;
return true;
return Proxy::construct(cx, proxy, args);
}
JS_FRIEND_DATA(Class) js::FunctionProxyClass = {

View File

@ -131,9 +131,8 @@ class JS_FRIEND_API(BaseProxyHandler)
/* Spidermonkey extensions. */
virtual bool isExtensible(JSObject *proxy) = 0;
virtual bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp);
virtual bool construct(JSContext *cx, HandleObject proxy, unsigned argc,
Value *argv, MutableHandleValue rval);
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args);
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args);
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
virtual bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx);
@ -193,9 +192,8 @@ class JS_PUBLIC_API(DirectProxyHandler) : public BaseProxyHandler
/* Spidermonkey extensions. */
virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, unsigned argc,
Value *argv, MutableHandleValue rval) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
CallArgs args) MOZ_OVERRIDE;
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
@ -246,9 +244,8 @@ class Proxy
/* Spidermonkey extensions. */
static bool isExtensible(JSObject *proxy);
static bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp);
static bool construct(JSContext *cx, HandleObject proxy, unsigned argc, Value *argv,
MutableHandleValue rval);
static bool call(JSContext *cx, HandleObject proxy, const CallArgs &args);
static bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args);
static bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl, CallArgs args);
static bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);
static bool objectClassIs(HandleObject obj, ESClassValue classValue, JSContext *cx);

View File

@ -467,11 +467,10 @@ CrossCompartmentWrapper::iterate(JSContext *cx, HandleObject wrapper, unsigned f
}
bool
CrossCompartmentWrapper::call(JSContext *cx, HandleObject wrapper, unsigned argc, Value *vp)
CrossCompartmentWrapper::call(JSContext *cx, HandleObject wrapper, const CallArgs &args)
{
RootedObject wrapped(cx, wrappedObject(wrapper));
CallArgs args = CallArgsFromVp(argc, vp);
{
AutoCompartment call(cx, wrapped);
@ -484,7 +483,7 @@ CrossCompartmentWrapper::call(JSContext *cx, HandleObject wrapper, unsigned argc
return false;
}
if (!Wrapper::call(cx, wrapper, argc, vp))
if (!Wrapper::call(cx, wrapper, args))
return false;
}
@ -492,23 +491,20 @@ CrossCompartmentWrapper::call(JSContext *cx, HandleObject wrapper, unsigned argc
}
bool
CrossCompartmentWrapper::construct(JSContext *cx, HandleObject wrapper, unsigned argc, Value *argv,
MutableHandleValue rval)
CrossCompartmentWrapper::construct(JSContext *cx, HandleObject wrapper, const CallArgs &args)
{
RootedObject wrapped(cx, wrappedObject(wrapper));
{
AutoCompartment call(cx, wrapped);
for (size_t n = 0; n < argc; ++n) {
RootedValue arg(cx, argv[n]);
if (!cx->compartment->wrap(cx, &arg))
for (size_t n = 0; n < args.length(); ++n) {
if (!cx->compartment->wrap(cx, args.handleAt(n)))
return false;
argv[n] = arg;
}
if (!Wrapper::construct(cx, wrapper, argc, argv, rval))
if (!Wrapper::construct(cx, wrapper, args))
return false;
}
return cx->compartment->wrap(cx, rval);
return cx->compartment->wrap(cx, args.rval());
}
bool
@ -788,15 +784,14 @@ DeadObjectProxy::enumerate(JSContext *cx, HandleObject wrapper, AutoIdVector &pr
}
bool
DeadObjectProxy::call(JSContext *cx, HandleObject wrapper, unsigned argc, Value *vp)
DeadObjectProxy::call(JSContext *cx, HandleObject wrapper, const CallArgs &args)
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEAD_OBJECT);
return false;
}
bool
DeadObjectProxy::construct(JSContext *cx, HandleObject wrapper, unsigned argc,
Value *vp, MutableHandleValue rval)
DeadObjectProxy::construct(JSContext *cx, HandleObject wrapper, const CallArgs &args)
{
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_DEAD_OBJECT);
return false;

View File

@ -111,9 +111,8 @@ class JS_FRIEND_API(CrossCompartmentWrapper) : public Wrapper
/* Spidermonkey extensions. */
virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject wrapper, unsigned argc, Value *vp) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject wrapper, unsigned argc, Value *argv,
MutableHandleValue rval) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject wrapper, const CallArgs &args) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject wrapper, const CallArgs &args) MOZ_OVERRIDE;
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
CallArgs args) MOZ_OVERRIDE;
virtual bool hasInstance(JSContext *cx, HandleObject wrapper, MutableHandleValue v,
@ -190,9 +189,8 @@ class JS_FRIEND_API(DeadObjectProxy) : public BaseProxyHandler
/* Spidermonkey extensions. */
virtual bool isExtensible(JSObject *proxy) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, HandleObject proxy, unsigned argc, Value *vp);
virtual bool construct(JSContext *cx, HandleObject proxy, unsigned argc,
Value *argv, MutableHandleValue rval);
virtual bool call(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, HandleObject proxy, const CallArgs &args) MOZ_OVERRIDE;
virtual bool nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
CallArgs args) MOZ_OVERRIDE;
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v, bool *bp);

View File

@ -3055,7 +3055,7 @@ xpc::IsSandboxPrototypeProxy(JSObject *obj)
bool
xpc::SandboxCallableProxyHandler::call(JSContext *cx, JS::Handle<JSObject*> proxy,
unsigned argc, Value *vp)
const JS::CallArgs &args)
{
// We forward the call to our underlying callable.
@ -3099,14 +3099,13 @@ xpc::SandboxCallableProxyHandler::call(JSContext *cx, JS::Handle<JSObject*> prox
// if the sandboxPrototype is an Xray Wrapper, which lets us appropriately
// remap |this|.
JS::Value thisVal =
WrapperFactory::IsXrayWrapper(sandboxProxy) ? JS_THIS(cx, vp)
: JS_THIS_VALUE(cx, vp);
WrapperFactory::IsXrayWrapper(sandboxProxy) ? args.computeThis(cx) : args.thisv();
if (thisVal == ObjectValue(*sandboxGlobal)) {
thisVal = ObjectValue(*js::GetProxyTargetObject(sandboxProxy));
}
return JS::Call(cx, thisVal, js::GetProxyPrivate(proxy), argc,
JS_ARGV(cx, vp), vp);
return JS::Call(cx, thisVal, js::GetProxyPrivate(proxy), args.length(), args.array(),
args.rval().address());
}
xpc::SandboxCallableProxyHandler xpc::sandboxCallableProxyHandler;

View File

@ -70,19 +70,17 @@ WaiveXrayWrapper::get(JSContext *cx, JS::Handle<JSObject*> wrapper,
}
bool
WaiveXrayWrapper::call(JSContext *cx, JS::Handle<JSObject*> wrapper, unsigned argc,
js::Value *vp)
WaiveXrayWrapper::call(JSContext *cx, JS::Handle<JSObject*> wrapper, const JS::CallArgs &args)
{
return CrossCompartmentWrapper::call(cx, wrapper, argc, vp) &&
WrapperFactory::WaiveXrayAndWrap(cx, vp);
return CrossCompartmentWrapper::call(cx, wrapper, args) &&
WrapperFactory::WaiveXrayAndWrap(cx, args.rval().address());
}
bool
WaiveXrayWrapper::construct(JSContext *cx, JS::Handle<JSObject*> wrapper,
unsigned argc, js::Value *argv, JS::MutableHandle<JS::Value> rval)
WaiveXrayWrapper::construct(JSContext *cx, JS::Handle<JSObject*> wrapper, const JS::CallArgs &args)
{
return CrossCompartmentWrapper::construct(cx, wrapper, argc, argv, rval) &&
WrapperFactory::WaiveXrayAndWrap(cx, rval.address());
return CrossCompartmentWrapper::construct(cx, wrapper, args) &&
WrapperFactory::WaiveXrayAndWrap(cx, args.rval().address());
}
// NB: This is important as the other side of a handshake with FieldGetter. See

View File

@ -30,11 +30,10 @@ class WaiveXrayWrapper : public js::CrossCompartmentWrapper {
virtual bool get(JSContext *cx, JS::Handle<JSObject*> wrapper, JS::Handle<JSObject*> receiver,
JS::Handle<jsid> id, JS::MutableHandle<JS::Value> vp) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, JS::Handle<JSObject*> wrapper, unsigned argc,
js::Value *vp) MOZ_OVERRIDE;
virtual bool call(JSContext *cx, JS::Handle<JSObject*> wrapper,
const JS::CallArgs &args) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, JS::Handle<JSObject*> wrapper,
unsigned argc, js::Value *argv,
JS::MutableHandle<JS::Value> rval) MOZ_OVERRIDE;
const JS::CallArgs &args) MOZ_OVERRIDE;
virtual bool nativeCall(JSContext *cx, JS::IsAcceptableThis test,
JS::NativeImpl impl, JS::CallArgs args) MOZ_OVERRIDE;

View File

@ -138,12 +138,11 @@ public:
HandleObject wrapper, HandleObject holder,
HandleId id, JSPropertyDescriptor *desc, unsigned flags);
static bool call(JSContext *cx, HandleObject wrapper, unsigned argc, Value *vp)
static bool call(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args)
{
MOZ_NOT_REACHED("Call trap currently implemented only for XPCWNs");
}
static bool construct(JSContext *cx, HandleObject wrapper, unsigned argc,
Value *argv, MutableHandleValue rval)
static bool construct(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args)
{
MOZ_NOT_REACHED("Call trap currently implemented only for XPCWNs");
}
@ -191,9 +190,8 @@ public:
bool *defined);
static bool enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags,
AutoIdVector &props);
static bool call(JSContext *cx, HandleObject wrapper, unsigned argc, Value *vp);
static bool construct(JSContext *cx, HandleObject wrapper, unsigned argc,
Value *argv, MutableHandleValue rval);
static bool call(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args);
static bool construct(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args);
static bool isResolving(JSContext *cx, JSObject *holder, jsid id);
@ -236,9 +234,8 @@ public:
bool *defined);
static bool enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flags,
AutoIdVector &props);
static bool call(JSContext *cx, HandleObject wrapper, unsigned argc, Value *vp);
static bool construct(JSContext *cx, HandleObject wrapper, unsigned argc,
Value *argv, MutableHandleValue rval);
static bool call(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args);
static bool construct(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args);
static bool isResolving(JSContext *cx, JSObject *holder, jsid id)
{
@ -1117,18 +1114,18 @@ XPCWrappedNativeXrayTraits::createHolder(JSContext *cx, JSObject *wrapper)
bool
XPCWrappedNativeXrayTraits::call(JSContext *cx, HandleObject wrapper,
unsigned argc, Value *vp)
const JS::CallArgs &args)
{
// Run the resolve hook of the wrapped native.
XPCWrappedNative *wn = getWN(wrapper);
if (NATIVE_HAS_FLAG(wn, WantCall)) {
XPCCallContext ccx(JS_CALLER, cx, wrapper, nullptr, JSID_VOID, argc,
vp + 2, vp);
XPCCallContext ccx(JS_CALLER, cx, wrapper, nullptr, JSID_VOID, args.length(), args.array(),
args.rval().address());
if (!ccx.IsValid())
return false;
bool ok = true;
nsresult rv = wn->GetScriptableInfo()->GetCallback()->Call(wn, cx, wrapper,
argc, vp + 2, vp, &ok);
nsresult rv = wn->GetScriptableInfo()->GetCallback()->Call(
wn, cx, wrapper, args.length(), args.array(), args.rval().address(), &ok);
if (NS_FAILED(rv)) {
if (ok)
XPCThrower::Throw(rv, cx);
@ -1142,19 +1139,18 @@ XPCWrappedNativeXrayTraits::call(JSContext *cx, HandleObject wrapper,
bool
XPCWrappedNativeXrayTraits::construct(JSContext *cx, HandleObject wrapper,
unsigned argc, Value *argv,
MutableHandleValue rval)
const JS::CallArgs &args)
{
// Run the resolve hook of the wrapped native.
XPCWrappedNative *wn = getWN(wrapper);
if (NATIVE_HAS_FLAG(wn, WantConstruct)) {
XPCCallContext ccx(JS_CALLER, cx, wrapper, nullptr, JSID_VOID, argc, argv, rval.address());
XPCCallContext ccx(JS_CALLER, cx, wrapper, nullptr, JSID_VOID, args.length(), args.array(),
args.rval().address());
if (!ccx.IsValid())
return false;
bool ok = true;
nsresult rv = wn->GetScriptableInfo()->GetCallback()->Construct(wn, cx, wrapper,
argc, argv, rval.address(),
&ok);
nsresult rv = wn->GetScriptableInfo()->GetCallback()->Construct(
wn, cx, wrapper, args.length(), args.array(), args.rval().address(), &ok);
if (NS_FAILED(rv)) {
if (ok)
XPCThrower::Throw(rv, cx);
@ -1227,46 +1223,42 @@ DOMXrayTraits::enumerateNames(JSContext *cx, HandleObject wrapper, unsigned flag
}
bool
DOMXrayTraits::call(JSContext *cx, HandleObject wrapper, unsigned argc, Value *vp)
DOMXrayTraits::call(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args)
{
RootedObject obj(cx, getTargetObject(wrapper));
AutoValueRooter rval(cx);
bool ok;
{
JSAutoCompartment ac(cx, obj);
if (!JS_WrapValue(cx, &vp[1]))
Value thisv = args.thisv();
if (!JS_WrapValue(cx, &thisv))
return false;
Value* argv = JS_ARGV(cx, vp);
for (unsigned i = 0; i < argc; ++i) {
if (!JS_WrapValue(cx, &argv[i]))
args.setThis(thisv);
for (size_t i = 0; i < args.length(); ++i) {
if (!JS_WrapValue(cx, &args[i]))
return false;
}
ok = Call(cx, vp[1], obj, argc, argv, rval.addr());
if (!Call(cx, thisv, obj, args.length(), args.array(), args.rval().address()))
return false;
}
if (!ok || !JS_WrapValue(cx, rval.addr()))
return false;
JS_SET_RVAL(cx, vp, rval.value());
return true;
return JS_WrapValue(cx, args.rval().address());
}
bool
DOMXrayTraits::construct(JSContext *cx, HandleObject wrapper, unsigned argc,
Value *argv, MutableHandleValue rval)
DOMXrayTraits::construct(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args)
{
RootedObject obj(cx, getTargetObject(wrapper));
MOZ_ASSERT(mozilla::dom::HasConstructor(obj));
RootedObject newObj(cx);
{
JSAutoCompartment ac(cx, obj);
for (unsigned i = 0; i < argc; ++i) {
if (!JS_WrapValue(cx, &argv[i]))
for (size_t i = 0; i < args.length(); ++i) {
if (!JS_WrapValue(cx, &args[i]))
return false;
}
newObj = JS_New(cx, obj, argc, argv);
newObj = JS_New(cx, obj, args.length(), args.array());
}
if (!newObj || !JS_WrapObject(cx, newObj.address()))
return false;
rval.setObject(*newObj);
args.rval().setObject(*newObj);
return true;
}
@ -1801,21 +1793,18 @@ XrayWrapper<Base, Traits>::iterate(JSContext *cx, HandleObject wrapper,
template <typename Base, typename Traits>
bool
XrayWrapper<Base, Traits>::call(JSContext *cx, HandleObject wrapper,
unsigned argc, js::Value *vp)
XrayWrapper<Base, Traits>::call(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args)
{
assertEnteredPolicy(cx, wrapper, JSID_VOID);
return Traits::call(cx, wrapper, argc, vp);
return Traits::call(cx, wrapper, args);
}
template <typename Base, typename Traits>
bool
XrayWrapper<Base, Traits>::construct(JSContext *cx, HandleObject wrapper,
unsigned argc, Value *argv,
MutableHandleValue rval)
XrayWrapper<Base, Traits>::construct(JSContext *cx, HandleObject wrapper, const JS::CallArgs &args)
{
assertEnteredPolicy(cx, wrapper, JSID_VOID);
return Traits::construct(cx, wrapper, argc, argv, rval);
return Traits::construct(cx, wrapper, args);
}
/*

View File

@ -95,11 +95,10 @@ class XrayWrapper : public Base {
virtual bool iterate(JSContext *cx, JS::Handle<JSObject*> wrapper, unsigned flags,
JS::MutableHandle<JS::Value> vp);
virtual bool call(JSContext *cx, JS::Handle<JSObject*> wrapper, unsigned argc,
js::Value *vp);
virtual bool call(JSContext *cx, JS::Handle<JSObject*> wrapper,
const JS::CallArgs &args) MOZ_OVERRIDE;
virtual bool construct(JSContext *cx, JS::Handle<JSObject*> wrapper,
unsigned argc, js::Value *argv,
JS::MutableHandle<JS::Value> rval);
const JS::CallArgs &args) MOZ_OVERRIDE;
static XrayWrapper singleton;
@ -156,8 +155,8 @@ public:
{
}
virtual bool call(JSContext *cx, JS::Handle<JSObject*> proxy, unsigned argc,
JS::Value *vp);
virtual bool call(JSContext *cx, JS::Handle<JSObject*> proxy,
const JS::CallArgs &args) MOZ_OVERRIDE;
};
extern SandboxCallableProxyHandler sandboxCallableProxyHandler;