author | Wes Kocher <wkocher@mozilla.com> |
Thu, 26 Feb 2015 23:17:34 -0800 | |
changeset 231115 | 7c3cc4f11d38fd6adfc585cf06afb3d092471bdc |
parent 231114 | 81589d78bc6fb391417a9b96f76e445d3335a2f2 |
child 231116 | 5dac945cae321bf7da54f6ca830d995fd4758906 |
push id | 28344 |
push user | ryanvm@gmail.com |
push date | Fri, 27 Feb 2015 18:20:08 +0000 |
treeherder | mozilla-central@9dd9d1e5b43c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1136925 |
milestone | 39.0a1 |
backs out | 331761aaae2288d5188db8801cf5894b92b23cd2 2faa0e91fe230efb7219e3b63b04641d12ee5264 a00f2530c9111f06c43c987e09306cd23ebfb911 d5e658bc07927efca7cf538ca8d6b8430099febd |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/WindowNamedPropertiesHandler.cpp +++ b/dom/base/WindowNamedPropertiesHandler.cpp @@ -275,13 +275,14 @@ WindowNamedPropertiesHandler::Create(JSC // chain, it needs a singleton type to avoid polluting type information // for properties on the window. JS::Rooted<JSObject*> gsp(aCx); js::ProxyOptions options; options.setSingleton(true); options.setClass(&WindowNamedPropertiesClass.mBase); return js::NewProxyObject(aCx, WindowNamedPropertiesHandler::getInstance(), JS::NullHandleValue, aProto, + js::GetGlobalForObjectCrossCompartment(aProto), options); } } // namespace dom } // namespace mozilla
--- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -1052,25 +1052,23 @@ nsChromeOuterWindowProxy::className(JSCo return "ChromeWindow"; } const nsChromeOuterWindowProxy nsChromeOuterWindowProxy::singleton; static JSObject* -NewOuterWindowProxy(JSContext *cx, JS::Handle<JSObject*> global, bool isChrome) -{ - JSAutoCompartment ac(cx, global); - MOZ_ASSERT(js::GetGlobalForObjectCrossCompartment(global) == global); - +NewOuterWindowProxy(JSContext *cx, JS::Handle<JSObject*> parent, bool isChrome) +{ + JSAutoCompartment ac(cx, parent); js::WrapperOptions options; options.setClass(&OuterWindowProxyClass); options.setSingleton(true); - JSObject *obj = js::Wrapper::New(cx, global, + JSObject *obj = js::Wrapper::New(cx, parent, parent, isChrome ? &nsChromeOuterWindowProxy::singleton : &nsOuterWindowProxy::singleton, options); NS_ASSERTION(js::GetObjectClass(obj)->ext.innerObject, "bad class"); return obj; }
--- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -1808,17 +1808,17 @@ ReparentWrapper(JSContext* aCx, JS::Hand // return early we must avoid ending up with two reflectors pointing to the // same native. Other than that, the objects we create will just go away. JS::Handle<JSObject*> proto = (domClass->mGetProto)(aCx, newParent); if (!proto) { return NS_ERROR_FAILURE; } - JS::Rooted<JSObject*> newobj(aCx, JS_CloneObject(aCx, aObj, proto)); + JS::Rooted<JSObject*> newobj(aCx, JS_CloneObject(aCx, aObj, proto, newParent)); if (!newobj) { return NS_ERROR_FAILURE; } js::SetReservedOrProxyPrivateSlot(newobj, DOM_OBJECT_SLOT, js::GetReservedOrProxyPrivateSlot(aObj, DOM_OBJECT_SLOT)); // At this point, both |aObj| and |newobj| point to the same native
--- a/dom/bindings/BindingUtils.h +++ b/dom/bindings/BindingUtils.h @@ -2797,17 +2797,17 @@ public: const DOMProxyHandler* aHandler, JS::Handle<JSObject*> aProto, T* aNative, JS::MutableHandle<JSObject*> aReflector) { js::ProxyOptions options; options.setClass(aClass); JS::Rooted<JS::Value> proxyPrivateVal(aCx, JS::PrivateValue(aNative)); aReflector.set(js::NewProxyObject(aCx, aHandler, proxyPrivateVal, aProto, - options)); + /* parent= */nullptr, options)); if (aReflector) { mNative = aNative; mReflector = aReflector; } } void CreateObject(JSContext* aCx, const JSClass* aClass,
--- a/js/ipc/WrapperOwner.cpp +++ b/js/ipc/WrapperOwner.cpp @@ -1015,16 +1015,17 @@ WrapperOwner::fromRemoteObjectVariant(JS RootedValue v(cx, UndefinedValue()); // We need to setLazyProto for the getPrototypeOf hook. ProxyOptions options; options.setLazyProto(true); obj = NewProxyObject(cx, &CPOWProxyHandler::singleton, v, nullptr, + junkScope, options); if (!obj) return nullptr; if (!cpows_.add(objId, obj)) return nullptr; // Incref once we know the decref will be called.
--- a/js/public/Proxy.h +++ b/js/public/Proxy.h @@ -576,17 +576,17 @@ class MOZ_STACK_CLASS ProxyOptions { private: bool singleton_; bool lazyProto_; const Class *clasp_; }; JS_FRIEND_API(JSObject *) NewProxyObject(JSContext *cx, const BaseProxyHandler *handler, HandleValue priv, - JSObject *proto, const ProxyOptions &options = ProxyOptions()); + JSObject *proto, JSObject *parent, const ProxyOptions &options = ProxyOptions()); JSObject * RenewProxyObject(JSContext *cx, JSObject *obj, BaseProxyHandler *handler, Value priv); class JS_FRIEND_API(AutoEnterPolicy) { public: typedef BaseProxyHandler::Action Action;
--- a/js/src/jsapi-tests/testBug604087.cpp +++ b/js/src/jsapi-tests/testBug604087.cpp @@ -39,32 +39,33 @@ static JSObject * PreWrap(JSContext *cx, JS::HandleObject scope, JS::HandleObject obj, JS::HandleObject objectPassedToWrap) { JS_GC(JS_GetRuntime(cx)); return obj; } static JSObject * -Wrap(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj) +Wrap(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj, + JS::HandleObject parent) { - return js::Wrapper::New(cx, obj, &js::CrossCompartmentWrapper::singleton); + return js::Wrapper::New(cx, obj, parent, &js::CrossCompartmentWrapper::singleton); } static const JSWrapObjectCallbacks WrapObjectCallbacks = { Wrap, PreWrap }; BEGIN_TEST(testBug604087) { js::WrapperOptions options; options.setClass(&OuterWrapperClass); options.setSingleton(true); - JS::RootedObject outerObj(cx, js::Wrapper::New(cx, global, &js::Wrapper::singleton, options)); + JS::RootedObject outerObj(cx, js::Wrapper::New(cx, global, global, &js::Wrapper::singleton, options)); JS::RootedObject compartment2(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook)); JS::RootedObject compartment3(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook)); JS::RootedObject compartment4(cx, JS_NewGlobalObject(cx, getGlobalClass(), nullptr, JS::FireOnNewGlobalHook)); JS::RootedObject c2wrapper(cx, wrap(cx, outerObj, compartment2)); CHECK(c2wrapper); c2wrapper->as<js::ProxyObject>().setExtra(0, js::Int32Value(2)); @@ -75,17 +76,17 @@ BEGIN_TEST(testBug604087) JS::RootedObject c4wrapper(cx, wrap(cx, outerObj, compartment4)); CHECK(c4wrapper); c4wrapper->as<js::ProxyObject>().setExtra(0, js::Int32Value(4)); compartment4 = c4wrapper = nullptr; JS::RootedObject next(cx); { JSAutoCompartment ac(cx, compartment2); - next = js::Wrapper::New(cx, compartment2, &js::Wrapper::singleton, options); + next = js::Wrapper::New(cx, compartment2, compartment2, &js::Wrapper::singleton, options); CHECK(next); } JS_SetWrapObjectCallbacks(JS_GetRuntime(cx), &WrapObjectCallbacks); CHECK(JS_TransplantObject(cx, outerObj, next)); return true; } END_TEST(testBug604087)
--- a/js/src/jsapi-tests/testSetPropertyIgnoringNamedGetter.cpp +++ b/js/src/jsapi-tests/testSetPropertyIgnoringNamedGetter.cpp @@ -67,17 +67,17 @@ BEGIN_TEST(testSetPropertyIgnoringNamedG { RootedValue protov(cx); EVAL("Object.prototype", &protov); RootedValue targetv(cx); EVAL("({})", &targetv); RootedObject proxyObj(cx, NewProxyObject(cx, &customProxyHandler, targetv, - &protov.toObject(), ProxyOptions())); + &protov.toObject(), global, ProxyOptions())); CHECK(proxyObj); CHECK(JS_DefineProperty(cx, global, "target", targetv, 0)); CHECK(JS_DefineProperty(cx, global, "proxy", proxyObj, 0)); RootedValue v(cx); EVAL("Object.getOwnPropertyDescriptor(proxy, 'phantom').value", &v); CHECK_SAME(v, Int32Value(42));
--- a/js/src/jsapi.h +++ b/js/src/jsapi.h @@ -733,17 +733,18 @@ typedef bool * that implements the desired prolicy for this kind of object in the * destination compartment. |obj| is the object to be wrapped. If |existing| is * non-nullptr, it will point to an existing wrapper object that should be * re-used if possible. |existing| is guaranteed to be a cross-compartment * wrapper with a lazily-defined prototype and the correct global. It is * guaranteed not to wrap a function. */ typedef JSObject * -(* JSWrapObjectCallback)(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj); +(* JSWrapObjectCallback)(JSContext *cx, JS::HandleObject existing, JS::HandleObject obj, + JS::HandleObject parent); /* * Callback used by the wrap hook to ask the embedding to prepare an object * for wrapping in a context. This might include unwrapping other wrappers * or even finding a more suitable object for the new compartment. */ typedef JSObject * (* JSPreWrapCallback)(JSContext *cx, JS::HandleObject scope, JS::HandleObject obj,
--- a/js/src/jscompartment.cpp +++ b/js/src/jscompartment.cpp @@ -438,17 +438,17 @@ JSCompartment::wrap(JSContext *cx, Mutab existing->isCallable() || existing->getParent() != global || obj->isCallable()) { existing = nullptr; } } - obj.set(cb->wrap(cx, existing, obj)); + obj.set(cb->wrap(cx, existing, obj, global)); if (!obj) return false; // We maintain the invariant that the key in the cross-compartment wrapper // map is always directly wrapped by the value. MOZ_ASSERT(Wrapper::wrappedObject(obj) == &key.get().toObject()); return putWrapper(cx, CrossCompartmentKey(key), ObjectValue(*obj));
--- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -617,20 +617,20 @@ js::StringToLinearStringSlow(JSContext * JS_FRIEND_API(void) JS_SetAccumulateTelemetryCallback(JSRuntime *rt, JSAccumulateTelemetryDataCallback callback) { rt->setTelemetryCallback(rt, callback); } JS_FRIEND_API(JSObject *) -JS_CloneObject(JSContext *cx, HandleObject obj, HandleObject protoArg) +JS_CloneObject(JSContext *cx, HandleObject obj, HandleObject protoArg, HandleObject parent) { Rooted<TaggedProto> proto(cx, TaggedProto(protoArg.get())); - return CloneObject(cx, obj, proto); + return CloneObject(cx, obj, proto, parent); } #ifdef DEBUG JS_FRIEND_API(void) js_DumpString(JSString *str) { str->dump(); }
--- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -143,17 +143,18 @@ JS_ScriptHasMutedErrors(JSScript *script extern JS_FRIEND_API(JSObject *) JS_ObjectToInnerObject(JSContext *cx, JS::HandleObject obj); /* Requires obj != nullptr. */ extern JS_FRIEND_API(JSObject *) JS_ObjectToOuterObject(JSContext *cx, JS::HandleObject obj); extern JS_FRIEND_API(JSObject *) -JS_CloneObject(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto); +JS_CloneObject(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto, + JS::HandleObject parent); /* * Copy the own properties of src to dst in a fast way. src and dst must both * be native and must be in the compartment of cx. They must have the same * class, the same parent, and the same prototype. Class reserved slots will * NOT be copied. * * dst must not have any properties on it before this function is called.
--- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -1772,43 +1772,43 @@ CopyProxyObject(JSContext *cx, Handle<Pr return false; SetProxyExtra(to, n, v); } return true; } JSObject * -js::CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto) +js::CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto, HandleObject parent) { if (!obj->isNative() && !obj->is<ProxyObject>()) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CLONE_OBJECT); return nullptr; } RootedObject clone(cx); if (obj->isNative()) { - clone = NewObjectWithGivenTaggedProto(cx, obj->getClass(), proto, NullPtr()); + clone = NewObjectWithGivenTaggedProto(cx, obj->getClass(), proto, parent); if (!clone) return nullptr; if (clone->is<JSFunction>() && (obj->compartment() != clone->compartment())) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_CANT_CLONE_OBJECT); return nullptr; } if (obj->as<NativeObject>().hasPrivate()) clone->as<NativeObject>().setPrivate(obj->as<NativeObject>().getPrivate()); } else { ProxyOptions options; options.setClass(obj->getClass()); - clone = ProxyObject::New(cx, GetProxyHandler(obj), JS::NullHandleValue, proto, options); + clone = ProxyObject::New(cx, GetProxyHandler(obj), JS::NullHandleValue, proto, parent, options); if (!clone) return nullptr; if (!CopyProxyObject(cx, obj.as<ProxyObject>(), clone.as<ProxyObject>())) return nullptr; } return clone;
--- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -1132,17 +1132,17 @@ CreateThisForFunctionWithProto(JSContext extern JSObject * CreateThisForFunction(JSContext *cx, js::HandleObject callee, NewObjectKind newKind); // Generic call for constructing |this|. extern JSObject * CreateThis(JSContext *cx, const js::Class *clasp, js::HandleObject callee); extern JSObject * -CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto); +CloneObject(JSContext *cx, HandleObject obj, Handle<js::TaggedProto> proto, HandleObject parent); extern NativeObject * DeepCloneObjectLiteral(JSContext *cx, HandleNativeObject obj, NewObjectKind newKind = GenericObject); extern bool DefineProperties(JSContext *cx, HandleObject obj, HandleObject props); /*
--- a/js/src/jswrapper.h +++ b/js/src/jswrapper.h @@ -64,17 +64,17 @@ class JS_FRIEND_API(Wrapper) : public Di enum Flags { CROSS_COMPARTMENT = 1 << 0, LAST_USED_FLAG = CROSS_COMPARTMENT }; virtual bool defaultValue(JSContext *cx, HandleObject obj, JSType hint, MutableHandleValue vp) const MOZ_OVERRIDE; - static JSObject *New(JSContext *cx, JSObject *obj, const Wrapper *handler, + static JSObject *New(JSContext *cx, JSObject *obj, JSObject *parent, const Wrapper *handler, const WrapperOptions &options = WrapperOptions()); static JSObject *Renew(JSContext *cx, JSObject *existing, JSObject *obj, const Wrapper *handler); static const Wrapper *wrapperHandler(JSObject *wrapper); static JSObject *wrappedObject(JSObject *wrapper); @@ -212,17 +212,18 @@ class JS_FRIEND_API(SecurityWrapper) : p typedef Base Permissive; typedef SecurityWrapper<Base> Restrictive; }; typedef SecurityWrapper<Wrapper> SameCompartmentSecurityWrapper; typedef SecurityWrapper<CrossCompartmentWrapper> CrossCompartmentSecurityWrapper; extern JSObject * -TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj); +TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj, + HandleObject parent); inline bool IsWrapper(JSObject *obj) { return IsProxy(obj) && GetProxyHandler(obj)->family() == &Wrapper::family; } // Given a JSObject, returns that object stripped of wrappers. If
--- a/js/src/proxy/Proxy.cpp +++ b/js/src/proxy/Proxy.cpp @@ -723,24 +723,25 @@ js::proxy_GetElements(JSContext *cx, Han const Class js::ProxyObject::class_ = PROXY_CLASS_DEF("Proxy", JSCLASS_HAS_CACHED_PROTO(JSProto_Proxy)); const Class* const js::ProxyClassPtr = &js::ProxyObject::class_; JS_FRIEND_API(JSObject *) js::NewProxyObject(JSContext *cx, const BaseProxyHandler *handler, HandleValue priv, JSObject *proto_, - const ProxyOptions &options) + JSObject *parent_, const ProxyOptions &options) { if (options.lazyProto()) { MOZ_ASSERT(!proto_); proto_ = TaggedProto::LazyProto; } - return ProxyObject::New(cx, handler, priv, TaggedProto(proto_), options); + return ProxyObject::New(cx, handler, priv, TaggedProto(proto_), parent_, + options); } void ProxyObject::renew(JSContext *cx, const BaseProxyHandler *handler, Value priv) { MOZ_ASSERT_IF(IsCrossCompartmentWrapper(this), IsDeadProxyObject(this)); MOZ_ASSERT(getParent() == cx->global()); MOZ_ASSERT(getClass() == &ProxyObject::class_);
--- a/js/src/proxy/ScriptedDirectProxyHandler.cpp +++ b/js/src/proxy/ScriptedDirectProxyHandler.cpp @@ -1201,17 +1201,17 @@ NewScriptedProxy(JSContext *cx, CallArgs if (!target) return false; RootedObject handler(cx, NonNullObject(cx, args[1])); if (!handler) return false; RootedValue priv(cx, ObjectValue(*target)); JSObject *proxy_ = NewProxyObject(cx, &ScriptedDirectProxyHandler::singleton, - priv, TaggedProto::LazyProto); + priv, TaggedProto::LazyProto, cx->global()); if (!proxy_) return false; Rooted<ProxyObject*> proxy(cx, &proxy_->as<ProxyObject>()); proxy->setExtra(ScriptedDirectProxyHandler::HANDLER_EXTRA, ObjectValue(*handler)); // Assign [[Call]] and [[Construct]] uint32_t callable = target->isCallable() ? ScriptedDirectProxyHandler::IS_CALLABLE : 0; uint32_t constructor = target->isConstructor() ? ScriptedDirectProxyHandler::IS_CONSTRUCTOR : 0;
--- a/js/src/proxy/ScriptedIndirectProxyHandler.cpp +++ b/js/src/proxy/ScriptedIndirectProxyHandler.cpp @@ -401,26 +401,29 @@ js::proxy_create(JSContext *cx, unsigned if (args.length() < 1) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED, "create", "0", "s"); return false; } JSObject *handler = NonNullObject(cx, args[0]); if (!handler) return false; - JSObject *proto; + JSObject *proto, *parent = nullptr; if (args.get(1).isObject()) { proto = &args[1].toObject(); + parent = proto->getParent(); } else { MOZ_ASSERT(IsFunctionObject(&args.callee())); proto = nullptr; } + if (!parent) + parent = args.callee().getParent(); RootedValue priv(cx, ObjectValue(*handler)); JSObject *proxy = NewProxyObject(cx, &ScriptedIndirectProxyHandler::singleton, - priv, proto); + priv, proto, parent); if (!proxy) return false; args.rval().setObject(*proxy); return true; } bool @@ -430,19 +433,22 @@ js::proxy_createFunction(JSContext *cx, if (args.length() < 2) { JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_MORE_ARGS_NEEDED, "createFunction", "1", ""); return false; } RootedObject handler(cx, NonNullObject(cx, args[0])); if (!handler) return false; - RootedObject proto(cx, args.callee().global().getOrCreateFunctionPrototype(cx)); + RootedObject proto(cx), parent(cx); + parent = args.callee().getParent(); + proto = parent->global().getOrCreateFunctionPrototype(cx); if (!proto) return false; + parent = proto->getParent(); RootedObject call(cx, ValueToCallable(cx, args[1], args.length() - 2)); if (!call) return false; RootedObject construct(cx, nullptr); if (args.length() > 2) { construct = ValueToCallable(cx, args[2], args.length() - 3); if (!construct) @@ -458,16 +464,16 @@ js::proxy_createFunction(JSContext *cx, if (!ccHolder) return false; ccHolder->as<NativeObject>().setReservedSlot(0, ObjectValue(*call)); ccHolder->as<NativeObject>().setReservedSlot(1, ObjectValue(*construct)); RootedValue priv(cx, ObjectValue(*handler)); JSObject *proxy = NewProxyObject(cx, &CallableScriptedIndirectProxyHandler::singleton, - priv, proto); + priv, proto, parent); if (!proxy) return false; proxy->as<ProxyObject>().setExtra(0, ObjectValue(*ccHolder)); args.rval().setObject(*proxy); return true; }
--- a/js/src/proxy/Wrapper.cpp +++ b/js/src/proxy/Wrapper.cpp @@ -28,21 +28,23 @@ Wrapper::defaultValue(JSContext *cx, Han { vp.set(ObjectValue(*proxy->as<ProxyObject>().target())); if (hint == JSTYPE_VOID) return ToPrimitive(cx, vp); return ToPrimitive(cx, hint, vp); } JSObject * -Wrapper::New(JSContext *cx, JSObject *obj, const Wrapper *handler, +Wrapper::New(JSContext *cx, JSObject *obj, JSObject *parent, const Wrapper *handler, const WrapperOptions &options) { + MOZ_ASSERT(parent); + RootedValue priv(cx, ObjectValue(*obj)); - return NewProxyObject(cx, handler, priv, options.proto(), options); + return NewProxyObject(cx, handler, priv, options.proto(), parent, options); } JSObject * Wrapper::Renew(JSContext *cx, JSObject *existing, JSObject *obj, const Wrapper *handler) { existing->as<ProxyObject>().renew(cx, handler, ObjectValue(*obj)); return existing; } @@ -120,21 +122,22 @@ js::UnwrapOneChecked(JSObject *obj, bool const char Wrapper::family = 0; const Wrapper Wrapper::singleton((unsigned)0); const Wrapper Wrapper::singletonWithPrototype((unsigned)0, true); JSObject *Wrapper::defaultProto = TaggedProto::LazyProto; /* Compartments. */ extern JSObject * -js::TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj) +js::TransparentObjectWrapper(JSContext *cx, HandleObject existing, HandleObject obj, + HandleObject parent) { // Allow wrapping outer window proxies. MOZ_ASSERT(!obj->is<WrapperObject>() || obj->getClass()->ext.innerObject); - return Wrapper::New(cx, obj, &CrossCompartmentWrapper::singleton); + return Wrapper::New(cx, obj, parent, &CrossCompartmentWrapper::singleton); } ErrorCopier::~ErrorCopier() { JSContext *cx = ac->context()->asJSContext(); if (ac->origin() != cx->compartment() && cx->isExceptionPending()) { RootedValue exc(cx); if (cx->getPendingException(&exc) && exc.isObject() && exc.toObject().is<ErrorObject>()) {
--- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -3963,17 +3963,17 @@ WrapWithProto(JSContext *cx, unsigned ar if (!obj.isObject() || !proto.isObjectOrNull()) { JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_INVALID_ARGS, "wrapWithProto"); return false; } WrapperOptions options(cx); options.setProto(proto.toObjectOrNull()); - JSObject *wrapped = Wrapper::New(cx, &obj.toObject(), + JSObject *wrapped = Wrapper::New(cx, &obj.toObject(), &obj.toObject().global(), &Wrapper::singletonWithPrototype, options); if (!wrapped) return false; args.rval().setObject(*wrapped); return true; }
--- a/js/src/vm/ProxyObject.cpp +++ b/js/src/vm/ProxyObject.cpp @@ -9,24 +9,26 @@ #include "jscompartment.h" #include "jsgcinlines.h" #include "jsobjinlines.h" using namespace js; /* static */ ProxyObject * ProxyObject::New(JSContext *cx, const BaseProxyHandler *handler, HandleValue priv, TaggedProto proto_, - const ProxyOptions &options) + JSObject *parent_, const ProxyOptions &options) { Rooted<TaggedProto> proto(cx, proto_); + RootedObject parent(cx, parent_); const Class *clasp = options.clasp(); MOZ_ASSERT(isValidProxyClass(clasp)); MOZ_ASSERT_IF(proto.isObject(), cx->compartment() == proto.toObject()->compartment()); + MOZ_ASSERT_IF(parent, cx->compartment() == parent->compartment()); /* * Eagerly mark properties unknown for proxies, so we don't try to track * their properties and so that we don't need to walk the compartment if * their prototype changes later. But don't do this for DOM proxies, * because we want to be able to keep track of them in typesets in useful * ways. */ @@ -43,17 +45,17 @@ ProxyObject::New(JSContext *cx, const Ba allocKind = GetBackgroundAllocKind(allocKind); ProxyValueArray *values = cx->zone()->new_<ProxyValueArray>(); if (!values) return nullptr; // Note: this will initialize the object's |data| to strange values, but we // will immediately overwrite those below. - RootedObject obj(cx, NewObjectWithGivenTaggedProto(cx, clasp, proto, NullPtr(), allocKind, + RootedObject obj(cx, NewObjectWithGivenTaggedProto(cx, clasp, proto, parent, allocKind, newKind)); if (!obj) { js_free(values); return nullptr; } Rooted<ProxyObject*> proxy(cx, &obj->as<ProxyObject>());
--- a/js/src/vm/ProxyObject.h +++ b/js/src/vm/ProxyObject.h @@ -23,17 +23,18 @@ class ProxyObject : public JSObject static_assert(sizeof(ProxyObject) == sizeof(JSObject_Slots0), "proxy object size must match GC thing size"); static_assert(offsetof(ProxyObject, data) == ProxyDataOffset, "proxy object layout must match shadow interface"); } public: static ProxyObject *New(JSContext *cx, const BaseProxyHandler *handler, HandleValue priv, - TaggedProto proto_, const ProxyOptions &options); + TaggedProto proto_, JSObject *parent_, + const ProxyOptions &options); const Value &private_() { return GetProxyPrivate(this); } void setCrossCompartmentPrivate(const Value &priv); void setSameCompartmentPrivate(const Value &priv);
--- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -1731,17 +1731,17 @@ const char DebugScopeProxy::family = 0; const DebugScopeProxy DebugScopeProxy::singleton; /* static */ DebugScopeObject * DebugScopeObject::create(JSContext *cx, ScopeObject &scope, HandleObject enclosing) { MOZ_ASSERT(scope.compartment() == cx->compartment()); RootedValue priv(cx, ObjectValue(scope)); JSObject *obj = NewProxyObject(cx, &DebugScopeProxy::singleton, priv, - nullptr /* proto */); + nullptr /* proto */, &scope.global()); if (!obj) return nullptr; MOZ_ASSERT(!enclosing->is<ScopeObject>()); DebugScopeObject *debugScope = &obj->as<DebugScopeObject>(); debugScope->setExtra(ENCLOSING_EXTRA, ObjectValue(*enclosing)); debugScope->setExtra(SNAPSHOT_EXTRA, NullValue());
--- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -642,17 +642,17 @@ WrapCallable(JSContext *cx, HandleObject // callable as the private. We put the given sandboxProtoProxy in // an extra slot, and our call() hook depends on that. MOZ_ASSERT(js::IsProxy(sandboxProtoProxy) && js::GetProxyHandler(sandboxProtoProxy) == &xpc::sandboxProxyHandler); RootedValue priv(cx, ObjectValue(*callable)); JSObject *obj = js::NewProxyObject(cx, &xpc::sandboxCallableProxyHandler, - priv, nullptr); + priv, nullptr, nullptr); if (obj) { js::SetProxyExtra(obj, SandboxCallableProxyHandler::SandboxProxySlot, ObjectValue(*sandboxProtoProxy)); } return obj; } @@ -967,17 +967,17 @@ xpc::CreateSandboxObject(JSContext *cx, JSObject *unwrappedProto = js::UncheckedUnwrap(options.proto, false); const js::Class *unwrappedClass = js::GetObjectClass(unwrappedProto); if (IS_WN_CLASS(unwrappedClass) || mozilla::dom::IsDOMClass(Jsvalify(unwrappedClass))) { // Wrap it up in a proxy that will do the right thing in terms // of this-binding for methods. RootedValue priv(cx, ObjectValue(*options.proto)); options.proto = js::NewProxyObject(cx, &xpc::sandboxProxyHandler, - priv, nullptr); + priv, nullptr, nullptr); if (!options.proto) return NS_ERROR_OUT_OF_MEMORY; } ok = JS_SetPrototype(cx, sandbox, options.proto); if (!ok) return NS_ERROR_XPC_UNEXPECTED; }
--- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -73,17 +73,19 @@ JSObject * WrapperFactory::CreateXrayWaiver(JSContext *cx, HandleObject obj) { // The caller is required to have already done a lookup. // NB: This implictly performs the assertions of GetXrayWaiver. MOZ_ASSERT(!GetXrayWaiver(obj)); XPCWrappedNativeScope *scope = ObjectScope(obj); JSAutoCompartment ac(cx, obj); - JSObject *waiver = Wrapper::New(cx, obj, &XrayWaiver); + JSObject *waiver = Wrapper::New(cx, obj, + JS_GetGlobalForObject(cx, obj), + &XrayWaiver); if (!waiver) return nullptr; // Add the new waiver to the map. It's important that we only ever have // one waiver for the lifetime of the target object. if (!scope->mWaiverWrapperMap) { scope->mWaiverWrapperMap = JSObject2JSObjectMap::newMap(XPC_WRAPPER_MAP_LENGTH); @@ -375,17 +377,18 @@ SelectAddonWrapper(JSContext *cx, Handle else if (wrapper == &PermissiveXrayDOM::singleton) return &AddonWrapper<PermissiveXrayDOM>::singleton; // |wrapper| is not supported for interposition, so we don't do it. return wrapper; } JSObject * -WrapperFactory::Rewrap(JSContext *cx, HandleObject existing, HandleObject obj) +WrapperFactory::Rewrap(JSContext *cx, HandleObject existing, HandleObject obj, + HandleObject parent) { MOZ_ASSERT(!IsWrapper(obj) || GetProxyHandler(obj) == &XrayWaiver || js::GetObjectClass(obj)->ext.innerObject, "wrapped object passed to rewrap"); MOZ_ASSERT(!XrayUtils::IsXPCWNHolderClass(JS_GetClass(obj)), "trying to wrap a holder"); MOZ_ASSERT(!js::IsInnerObject(obj)); // We sometimes end up here after nsContentUtils has been shut down but before @@ -496,17 +499,17 @@ WrapperFactory::Rewrap(JSContext *cx, Ha } } DEBUG_CheckUnwrapSafety(obj, wrapper, origin, target); if (existing) return Wrapper::Renew(cx, existing, obj, wrapper); - return Wrapper::New(cx, obj, wrapper); + return Wrapper::New(cx, obj, parent, wrapper); } // Call WaiveXrayAndWrap when you have a JS object that you don't want to be // wrapped in an Xray wrapper. cx->compartment is the compartment that will be // using the returned object. If the object to be wrapped is already in the // correct compartment, then this returns the unwrapped object. bool WrapperFactory::WaiveXrayAndWrap(JSContext *cx, MutableHandleValue vp)
--- a/js/xpconnect/wrappers/WrapperFactory.h +++ b/js/xpconnect/wrappers/WrapperFactory.h @@ -41,17 +41,18 @@ class WrapperFactory { static JSObject *PrepareForWrapping(JSContext *cx, JS::HandleObject scope, JS::HandleObject obj, JS::HandleObject objectPassedToWrap); // Rewrap an object that is about to cross compartment boundaries. static JSObject *Rewrap(JSContext *cx, JS::HandleObject existing, - JS::HandleObject obj); + JS::HandleObject obj, + JS::HandleObject parent); // Wrap wrapped object into a waiver wrapper and then re-wrap it. static bool WaiveXrayAndWrap(JSContext *cx, JS::MutableHandleValue vp); static bool WaiveXrayAndWrap(JSContext *cx, JS::MutableHandleObject object); }; extern const js::Wrapper XrayWaiver;