зеркало из https://github.com/mozilla/gecko-dev.git
Bug 855136 - Don't use call/construct slots for direct proxies (r=luke)
This commit is contained in:
Родитель
8b5998ff20
Коммит
297984ced3
|
@ -485,12 +485,6 @@ JSCompartment::markCrossCompartmentWrappers(JSTracer *trc)
|
|||
Value referent = GetProxyPrivate(wrapper);
|
||||
MarkValueRoot(trc, &referent, "cross-compartment wrapper");
|
||||
JS_ASSERT(referent == GetProxyPrivate(wrapper));
|
||||
|
||||
if (IsFunctionProxy(wrapper)) {
|
||||
Value call = GetProxyCall(wrapper);
|
||||
MarkValueRoot(trc, &call, "cross-compartment wrapper");
|
||||
JS_ASSERT(call == GetProxyCall(wrapper));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3260,11 +3260,6 @@ JSCompartment::findOutgoingEdges(ComponentFinder<JS::Zone> &finder)
|
|||
if (w->isGCMarking())
|
||||
finder.addEdgeTo(w);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
JSObject *wrapper = &e.front().value.toObject();
|
||||
JS_ASSERT_IF(IsFunctionProxy(wrapper), &GetProxyCall(wrapper).toObject() == other);
|
||||
#endif
|
||||
}
|
||||
|
||||
Debugger::findCompartmentEdges(zone(), finder);
|
||||
|
|
|
@ -327,24 +327,16 @@ bool
|
|||
BaseProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned argc,
|
||||
Value *vp)
|
||||
{
|
||||
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;
|
||||
JS_NOT_REACHED("callable proxies should implement call trap");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
BaseProxyHandler::construct(JSContext *cx, HandleObject proxy, unsigned argc,
|
||||
Value *argv, MutableHandleValue rval)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedValue fval(cx, GetConstruct(proxy));
|
||||
if (fval.isUndefined())
|
||||
fval = GetCall(proxy);
|
||||
return InvokeConstructor(cx, fval, argc, argv, rval.address());
|
||||
JS_NOT_REACHED("callable proxies should implement construct trap");
|
||||
return false;
|
||||
}
|
||||
|
||||
JSString *
|
||||
|
@ -358,19 +350,8 @@ BaseProxyHandler::obj_toString(JSContext *cx, HandleObject proxy)
|
|||
JSString *
|
||||
BaseProxyHandler::fun_toString(JSContext *cx, HandleObject proxy, unsigned indent)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
Value fval = GetCall(proxy);
|
||||
if (IsFunctionProxy(proxy) &&
|
||||
(fval.isPrimitive() || !fval.toObject().isFunction())) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO,
|
||||
js_Function_str, js_toString_str,
|
||||
"object");
|
||||
return NULL;
|
||||
}
|
||||
RootedObject obj(cx, &fval.toObject());
|
||||
return fun_toStringHelper(cx, obj, indent);
|
||||
|
||||
JS_NOT_REACHED("callable proxies should implement fun_toString trap");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -511,6 +492,28 @@ DirectProxyHandler::enumerate(JSContext *cx, HandleObject proxy,
|
|||
return GetPropertyNames(cx, target, 0, &props);
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned argc,
|
||||
Value *vp)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::construct(JSContext *cx, HandleObject proxy, unsigned argc,
|
||||
Value *argv, MutableHandleValue rval)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedValue target(cx, GetProxyPrivate(proxy));
|
||||
return InvokeConstructor(cx, target, argc, argv, rval.address());
|
||||
}
|
||||
|
||||
bool
|
||||
DirectProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args)
|
||||
|
@ -812,8 +815,12 @@ class ScriptedIndirectProxyHandler : public BaseProxyHandler {
|
|||
MutableHandleValue vp) MOZ_OVERRIDE;
|
||||
|
||||
/* Spidermonkey extensions. */
|
||||
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 nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args) MOZ_OVERRIDE;
|
||||
virtual JSString *fun_toString(JSContext *cx, HandleObject proxy, unsigned indent) MOZ_OVERRIDE;
|
||||
virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint,
|
||||
MutableHandleValue vp) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -1011,6 +1018,30 @@ ScriptedIndirectProxyHandler::iterate(JSContext *cx, HandleObject proxy, unsigne
|
|||
ReturnedValueMustNotBePrimitive(cx, proxy, cx->names().iterate, vp);
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::call(JSContext *cx, HandleObject proxy, unsigned argc,
|
||||
Value *vp)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::construct(JSContext *cx, HandleObject proxy, unsigned argc,
|
||||
Value *argv, MutableHandleValue rval)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
RootedValue fval(cx, GetConstruct(proxy));
|
||||
if (fval.isUndefined())
|
||||
fval = GetCall(proxy);
|
||||
return InvokeConstructor(cx, fval, argc, argv, rval.address());
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args)
|
||||
|
@ -1018,6 +1049,23 @@ ScriptedIndirectProxyHandler::nativeCall(JSContext *cx, IsAcceptableThis test, N
|
|||
return BaseProxyHandler::nativeCall(cx, test, impl, args);
|
||||
}
|
||||
|
||||
JSString *
|
||||
ScriptedIndirectProxyHandler::fun_toString(JSContext *cx, HandleObject proxy, unsigned indent)
|
||||
{
|
||||
assertEnteredPolicy(cx, proxy, JSID_VOID);
|
||||
Value fval = GetCall(proxy);
|
||||
if (IsFunctionProxy(proxy) &&
|
||||
(fval.isPrimitive() || !fval.toObject().isFunction())) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL,
|
||||
JSMSG_INCOMPATIBLE_PROTO,
|
||||
js_Function_str, js_toString_str,
|
||||
"object");
|
||||
return NULL;
|
||||
}
|
||||
RootedObject obj(cx, &fval.toObject());
|
||||
return fun_toStringHelper(cx, obj, indent);
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptedIndirectProxyHandler::defaultValue(JSContext *cx, HandleObject proxy, JSType hint,
|
||||
MutableHandleValue vp)
|
||||
|
@ -3262,9 +3310,9 @@ js::NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv_,
|
|||
return NewProxyObject(cx, handler, priv_, TaggedProto(proto_), parent_, callable);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
js::NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv_, JSObject *proto_,
|
||||
JSObject *parent_, JSObject *call, JSObject *construct)
|
||||
static JSObject *
|
||||
NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv_, JSObject *proto_,
|
||||
JSObject *parent_, JSObject *call, JSObject *construct)
|
||||
{
|
||||
JS_ASSERT_IF(construct, cx->compartment == construct->compartment());
|
||||
JS_ASSERT_IF(call && cx->compartment != call->compartment(), priv_ == ObjectValue(*call));
|
||||
|
|
|
@ -191,6 +191,9 @@ public:
|
|||
|
||||
/* 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 nativeCall(JSContext *cx, IsAcceptableThis test, NativeImpl impl,
|
||||
CallArgs args) MOZ_OVERRIDE;
|
||||
virtual bool hasInstance(JSContext *cx, HandleObject proxy, MutableHandleValue v,
|
||||
|
@ -316,13 +319,6 @@ GetProxyTargetObject(RawObject obj)
|
|||
return GetProxyPrivate(obj).toObjectOrNull();
|
||||
}
|
||||
|
||||
inline const Value &
|
||||
GetProxyCall(RawObject obj)
|
||||
{
|
||||
JS_ASSERT(IsFunctionProxy(obj));
|
||||
return GetReservedSlot(obj, JSSLOT_PROXY_CALL);
|
||||
}
|
||||
|
||||
inline const Value &
|
||||
GetProxyExtra(RawObject obj, size_t n)
|
||||
{
|
||||
|
@ -354,10 +350,6 @@ JS_FRIEND_API(JSObject *)
|
|||
NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv,
|
||||
JSObject *proto, JSObject *parent, ProxyCallable callable = ProxyNotCallable);
|
||||
|
||||
JS_FRIEND_API(JSObject *)
|
||||
NewProxyObject(JSContext *cx, BaseProxyHandler *handler, const Value &priv,
|
||||
JSObject *proto, JSObject *parent, JSObject *call, JSObject *construct);
|
||||
|
||||
JSObject *
|
||||
RenewProxyObject(JSContext *cx, JSObject *obj, BaseProxyHandler *handler, Value priv);
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ Wrapper::New(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent,
|
|||
AutoMarkInDeadZone amd(cx->zone());
|
||||
|
||||
return NewProxyObject(cx, handler, ObjectValue(*obj), proto, parent,
|
||||
obj->isCallable() ? obj : NULL, NULL);
|
||||
obj->isCallable() ? ProxyIsCallable : ProxyNotCallable);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
|
|
@ -3057,8 +3057,7 @@ bool
|
|||
xpc::SandboxCallableProxyHandler::call(JSContext *cx, JS::Handle<JSObject*> proxy,
|
||||
unsigned argc, Value *vp)
|
||||
{
|
||||
// We forward the call to our underlying callable. The callable to forward
|
||||
// to can be gotten via GetProxyCall.
|
||||
// We forward the call to our underlying callable.
|
||||
|
||||
// The parent of our proxy is the SandboxProxyHandler proxy
|
||||
JSObject *sandboxProxy = JS_GetParent(proxy);
|
||||
|
@ -3106,7 +3105,7 @@ xpc::SandboxCallableProxyHandler::call(JSContext *cx, JS::Handle<JSObject*> prox
|
|||
thisVal = ObjectValue(*js::GetProxyTargetObject(sandboxProxy));
|
||||
}
|
||||
|
||||
return JS::Call(cx, thisVal, js::GetProxyCall(proxy), argc,
|
||||
return JS::Call(cx, thisVal, js::GetProxyPrivate(proxy), argc,
|
||||
JS_ARGV(cx, vp), vp);
|
||||
}
|
||||
|
||||
|
@ -3125,11 +3124,9 @@ WrapCallable(JSContext *cx, JSObject *callable, JSObject *sandboxProtoProxy)
|
|||
js::GetProxyHandler(sandboxProtoProxy) ==
|
||||
&xpc::sandboxProxyHandler);
|
||||
|
||||
// We need to pass the given callable in as the "call" and
|
||||
// "construct" so we get a function proxy.
|
||||
return js::NewProxyObject(cx, &xpc::sandboxCallableProxyHandler,
|
||||
ObjectValue(*callable), nullptr,
|
||||
sandboxProtoProxy, callable, callable);
|
||||
sandboxProtoProxy, js::ProxyIsCallable);
|
||||
}
|
||||
|
||||
template<typename Op>
|
||||
|
|
Загрузка…
Ссылка в новой задаче