author | Bill McCloskey <wmccloskey@mozilla.com> |
Mon, 03 Sep 2012 16:42:10 -0700 | |
changeset 108154 | c372439f0aad42d3dd73306c59035f2450d2e1b7 |
parent 108153 | a0853ae2ee0fc5e79847bdaf08be31451088eab8 |
child 108155 | fd398d69d052954dc376c64f1e17dbbc05579037 |
push id | 23539 |
push user | ryanvm@gmail.com |
push date | Wed, 26 Sep 2012 22:55:55 +0000 |
treeherder | autoland@ec079fd92224 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bhackett |
bugs | 787856 |
milestone | 18.0a1 |
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/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -1900,24 +1900,24 @@ jsid nsDOMClassInfo::sOnload_id jsid nsDOMClassInfo::sOnerror_id = JSID_VOID; static const JSClass *sObjectClass = nullptr; /** * Set our JSClass pointer for the Object class */ static void -FindObjectClass(JSObject* aGlobalObject) +FindObjectClass(JSContext* cx, JSObject* aGlobalObject) { NS_ASSERTION(!sObjectClass, "Double set of sObjectClass"); JSObject *obj, *proto = aGlobalObject; do { obj = proto; - proto = js::GetObjectProto(obj); + js::GetObjectProto(cx, obj, &proto); } while (proto); sObjectClass = js::GetObjectJSClass(obj); } static void PrintWarningOnConsole(JSContext *cx, const char *stringBundleProperty) { @@ -5121,17 +5121,17 @@ nsDOMClassInfo::PostCreatePrototype(JSCo if (!xpc::DOM_DefineQuickStubs(cx, proto, flags, count, mData->mInterfaces)) { JS_ClearPendingException(cx); } // This is called before any other location that requires // sObjectClass, so compute it here. We assume that nobody has had a // chance to monkey around with proto's prototype chain before this. if (!sObjectClass) { - FindObjectClass(proto); + FindObjectClass(cx, proto); NS_ASSERTION(sObjectClass && !strcmp(sObjectClass->name, "Object"), "Incorrect object class!"); } NS_ASSERTION(::JS_GetPrototype(proto) && JS_GetClass(::JS_GetPrototype(proto)) == sObjectClass, "Hmm, somebody did something evil?"); @@ -7495,17 +7495,21 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp // binding a name) a new undefined property that's not already // defined on our prototype chain. This way we can access this // expando w/o ever getting back into XPConnect. if (flags & JSRESOLVE_ASSIGNING) { JSObject *realObj; wrapper->GetJSObject(&realObj); if (obj == realObj) { - JSObject *proto = js::GetObjectProto(obj); + JSObject *proto; + if (!js::GetObjectProto(cx, obj, &proto)) { + *_retval = JS_FALSE; + return NS_OK; + } if (proto) { JSObject *pobj = NULL; jsval val; if (!::JS_LookupPropertyWithFlagsById(cx, proto, id, flags, &pobj, &val)) { *_retval = JS_FALSE; @@ -8934,17 +8938,19 @@ nsHTMLDocumentSH::DocumentAllGetProperty // newResolve hook, so nothing to do for those properties here. And // we need to return early to prevent <div id="item"> from shadowing // document.all.item(), etc. if (sItem_id == id || sNamedItem_id == id) { return JS_TRUE; } while (js::GetObjectJSClass(obj) != &sHTMLDocumentAllClass) { - obj = js::GetObjectProto(obj); + if (!js::GetObjectProto(cx, obj, &obj)) { + return JS_FALSE; + } if (!obj) { NS_ERROR("The JS engine lies!"); return JS_TRUE; } }
--- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -620,17 +620,21 @@ nsOuterWindowProxy::finalize(JSFreeOp *f nsOuterWindowProxy nsOuterWindowProxy::singleton; static JSObject* NewOuterWindowProxy(JSContext *cx, JSObject *parent) { JSAutoCompartment ac(cx, parent); - JSObject *obj = js::Wrapper::New(cx, parent, js::GetObjectProto(parent), parent, + JSObject *proto; + if (!js::GetObjectProto(cx, parent, &proto)) + return nullptr; + + JSObject *obj = js::Wrapper::New(cx, parent, proto, parent, &nsOuterWindowProxy::singleton); NS_ASSERTION(js::GetObjectClass(obj)->ext.innerObject, "bad class"); return obj; } //***************************************************************************** //*** nsGlobalWindow: Object Management //*****************************************************************************
--- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -586,17 +586,20 @@ XrayEnumerateProperties(JS::AutoIdVector return true; } bool GetPropertyOnPrototype(JSContext* cx, JSObject* proxy, jsid id, bool* found, JS::Value* vp) { - JSObject* proto = js::GetObjectProto(proxy); + JSObject* proto; + if (!js::GetObjectProto(cx, proxy, &proto)) { + return false; + } if (!proto) { *found = false; return true; } JSBool hasProp; if (!JS_HasPropertyById(cx, proto, id, &hasProp)) { return false;
--- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -5012,17 +5012,20 @@ if (expando) { """ return """MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(proxy), "Should not have a XrayWrapper here"); """ + get + """ // No need to worry about name getters here, so just check the proto. -JSObject *proto = js::GetObjectProto(proxy); +JSObject *proto; +if (!js::GetObjectProto(cx, proxy, &proto)) { + return false; +} if (proto) { JSBool isPresent; if (!JS_GetElementIfPresent(cx, proto, index, proxy, vp, &isPresent)) { return false; } *present = isPresent; return true; }
--- a/dom/bindings/DOMJSProxyHandler.cpp +++ b/dom/bindings/DOMJSProxyHandler.cpp @@ -92,17 +92,20 @@ DOMProxyHandler::getPropertyDescriptor(J { if (!getOwnPropertyDescriptor(cx, proxy, id, set, desc)) { return false; } if (desc->obj) { return true; } - JSObject* proto = js::GetObjectProto(proxy); + JSObject* proto; + if (!js::GetObjectProto(cx, proxy, &proto)) { + return false; + } if (!proto) { desc->obj = NULL; return true; } return JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, desc); } @@ -146,17 +149,20 @@ DOMProxyHandler::delete_(JSContext* cx, *bp = !!b; return true; } bool DOMProxyHandler::enumerate(JSContext* cx, JSObject* proxy, AutoIdVector& props) { - JSObject* proto = JS_GetPrototype(proxy); + JSObject* proto; + if (!JS_GetPrototype(cx, proxy, &proto)) { + return false; + } return getOwnPropertyNames(cx, proxy, props) && (!proto || js::GetPropertyNames(cx, proto, 0, &props)); } bool DOMProxyHandler::fix(JSContext* cx, JSObject* proxy, Value* vp) { vp->setUndefined(); @@ -172,17 +178,20 @@ DOMProxyHandler::has(JSContext* cx, JSOb if (*bp) { // We have the property ourselves; no need to worry about our prototype // chain. return true; } // OK, now we have to look at the proto - JSObject *proto = js::GetObjectProto(proxy); + JSObject *proto; + if (!js::GetObjectProto(cx, proxy, &proto)) { + return false; + } if (!proto) { return true; } JSBool protoHasProp; bool ok = JS_HasPropertyById(cx, proto, id, &protoHasProp); if (ok) { *bp = protoHasProp; }
--- a/js/ipc/ObjectWrapperParent.cpp +++ b/js/ipc/ObjectWrapperParent.cpp @@ -179,22 +179,23 @@ ObjectWrapperParent::GetJSObject(JSConte JS_SetPrivate(mObj, (void*)this); JS_SetReservedSlot(mObj, sFlagsSlot, JSVAL_ZERO); } } return mObj; } static ObjectWrapperParent* -Unwrap(JSObject* obj) +Unwrap(JSContext* cx, JSObject* obj) { - while (js::GetObjectClass(obj) != &ObjectWrapperParent::sCPOW_JSClass) - if (!(obj = js::GetObjectProto(obj))) + while (js::GetObjectClass(obj) != &ObjectWrapperParent::sCPOW_JSClass) { + if (!js::GetObjectProto(cx, obj, &obj) || !obj) return NULL; - + } + ObjectWrapperParent* self = static_cast<ObjectWrapperParent*>(JS_GetPrivate(obj)); NS_ASSERTION(!self || self->GetJSObjectOrNull() == obj, "Wrapper and wrapped object disagree?"); return self; } @@ -213,17 +214,17 @@ ObjectWrapperParent::jsval_to_JSVariant( // fall through case JSTYPE_FUNCTION: // CPOWs can fool JS_TypeOfValue into returning JSTYPE_FUNCTION // because they have a call hook, but CPOWs are really objects, so // fall through to the JSTYPE_OBJECT case: case JSTYPE_OBJECT: { PObjectWrapperParent* powp; - if (!JSObject_to_PObjectWrapperParent(JSVAL_TO_OBJECT(from), &powp)) + if (!JSObject_to_PObjectWrapperParent(cx, JSVAL_TO_OBJECT(from), &powp)) return with_error(cx, false, "Cannot pass parent-created object to child"); *to = powp; } return true; case JSTYPE_STRING: { nsDependentJSString depStr; if (!depStr.init(cx, from)) @@ -277,23 +278,23 @@ ObjectWrapperParent::jsval_from_JSVarian return true; default: return false; } } /*static*/ bool ObjectWrapperParent:: -JSObject_to_PObjectWrapperParent(JSObject* from, PObjectWrapperParent** to) +JSObject_to_PObjectWrapperParent(JSContext* cx, JSObject* from, PObjectWrapperParent** to) { if (!from) { *to = NULL; return true; } - ObjectWrapperParent* owp = Unwrap(from); + ObjectWrapperParent* owp = Unwrap(cx, from); if (!owp) return false; *to = owp; return true; } /*static*/ bool ObjectWrapperParent:: @@ -355,17 +356,17 @@ jsval_to_nsString(JSContext* cx, jsid fr /*static*/ JSBool ObjectWrapperParent::CPOW_AddProperty(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp) { CPOW_LOG(("Calling CPOW_AddProperty (%s)...", JSVAL_TO_CSTR(cx, id))); - ObjectWrapperParent* self = Unwrap(obj); + ObjectWrapperParent* self = Unwrap(cx, obj); if (!self) return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_AddProperty"); if (AutoResolveFlag::IsSet(obj)) return JS_TRUE; AutoCheckOperation aco(cx, self); @@ -382,17 +383,17 @@ ObjectWrapperParent::CPOW_AddProperty(JS /*static*/ JSBool ObjectWrapperParent::CPOW_GetProperty(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp) { CPOW_LOG(("Calling CPOW_GetProperty (%s)...", JSVAL_TO_CSTR(cx, id))); - ObjectWrapperParent* self = Unwrap(obj); + ObjectWrapperParent* self = Unwrap(cx, obj); if (!self) return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_GetProperty"); AutoCheckOperation aco(cx, self); nsString in_id; if (!jsval_to_nsString(cx, id, &in_id)) @@ -409,17 +410,17 @@ ObjectWrapperParent::CPOW_GetProperty(JS /*static*/ JSBool ObjectWrapperParent::CPOW_SetProperty(JSContext *cx, JSHandleObject obj, JSHandleId id, JSBool strict, JSMutableHandleValue vp) { CPOW_LOG(("Calling CPOW_SetProperty (%s)...", JSVAL_TO_CSTR(cx, id))); - ObjectWrapperParent* self = Unwrap(obj); + ObjectWrapperParent* self = Unwrap(cx, obj); if (!self) return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_SetProperty"); AutoCheckOperation aco(cx, self); nsString in_id; JSVariant in_v; @@ -438,17 +439,17 @@ ObjectWrapperParent::CPOW_SetProperty(JS /*static*/ JSBool ObjectWrapperParent::CPOW_DelProperty(JSContext *cx, JSHandleObject obj, JSHandleId id, JSMutableHandleValue vp) { CPOW_LOG(("Calling CPOW_DelProperty (%s)...", JSVAL_TO_CSTR(cx, id))); - ObjectWrapperParent* self = Unwrap(obj); + ObjectWrapperParent* self = Unwrap(cx, obj); if (!self) return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_DelProperty"); AutoCheckOperation aco(cx, self); nsString in_id; if (!jsval_to_nsString(cx, id, &in_id)) @@ -519,17 +520,17 @@ ObjectWrapperParent::NewEnumerateDestroy /*static*/ JSBool ObjectWrapperParent::CPOW_NewEnumerate(JSContext *cx, JSHandleObject obj, JSIterateOp enum_op, jsval *statep, jsid *idp) { CPOW_LOG(("Calling CPOW_NewEnumerate...")); - ObjectWrapperParent* self = Unwrap(obj); + ObjectWrapperParent* self = Unwrap(cx, obj); if (!self) return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewEnumerate"); switch (enum_op) { case JSENUMERATE_INIT: case JSENUMERATE_INIT_ALL: self->Manager()->RequestRunToCompletion(); return self->NewEnumerateInit(cx, statep, idp); @@ -545,17 +546,17 @@ ObjectWrapperParent::CPOW_NewEnumerate(J /*static*/ JSBool ObjectWrapperParent::CPOW_NewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags, JSMutableHandleObject objp) { CPOW_LOG(("Calling CPOW_NewResolve (%s)...", JSVAL_TO_CSTR(cx, id))); - ObjectWrapperParent* self = Unwrap(obj); + ObjectWrapperParent* self = Unwrap(cx, obj); if (!self) return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_NewResolve"); AutoCheckOperation aco(cx, self); nsString in_id; if (!jsval_to_nsString(cx, id, &in_id)) @@ -581,54 +582,56 @@ ObjectWrapperParent::CPOW_NewResolve(JSC /*static*/ JSBool ObjectWrapperParent::CPOW_Convert(JSContext *cx, JSHandleObject obj, JSType type, JSMutableHandleValue vp) { CPOW_LOG(("Calling CPOW_Convert (to %s)...", JS_GetTypeName(cx, type))); - ObjectWrapperParent* self = Unwrap(obj); + ObjectWrapperParent* self = Unwrap(cx, obj); if (!self) return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_Convert"); vp.set(OBJECT_TO_JSVAL(obj)); return JS_TRUE; } /*static*/ void ObjectWrapperParent::CPOW_Finalize(js::FreeOp* fop, JSObject* obj) { CPOW_LOG(("Calling CPOW_Finalize...")); - - ObjectWrapperParent* self = Unwrap(obj); + + MOZ_ASSERT(js::GetObjectClass(obj) == &ObjectWrapperParent::sCPOW_JSClass); + ObjectWrapperParent* self = + static_cast<ObjectWrapperParent*>(JS_GetPrivate(obj)); if (self) { self->mObj = NULL; unused << ObjectWrapperParent::Send__delete__(self); } } /*static*/ JSBool ObjectWrapperParent::CPOW_Call(JSContext* cx, unsigned argc, jsval* vp) { CPOW_LOG(("Calling CPOW_Call...")); JSObject* thisobj = JS_THIS_OBJECT(cx, vp); if (!thisobj) return JS_FALSE; ObjectWrapperParent* function = - Unwrap(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp))); + Unwrap(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp))); if (!function) return with_error(cx, JS_FALSE, "Could not unwrap CPOW function"); AutoCheckOperation aco(cx, function); - ObjectWrapperParent* receiver = Unwrap(thisobj); + ObjectWrapperParent* receiver = Unwrap(cx, thisobj); if (!receiver) { // Substitute child global for parent global object. // TODO First make sure we're really replacing the global object? ContextWrapperParent* manager = static_cast<ContextWrapperParent*>(function->Manager()); receiver = manager->GetGlobalObjectWrapper(); } @@ -647,17 +650,17 @@ ObjectWrapperParent::CPOW_Call(JSContext jsval_from_JSVariant(cx, out_rval, vp)); } /*static*/ JSBool ObjectWrapperParent::CPOW_Construct(JSContext* cx, unsigned argc, jsval* vp) { CPOW_LOG(("Calling CPOW_Construct...")); - ObjectWrapperParent* constructor = Unwrap(JSVAL_TO_OBJECT(JS_CALLEE(cx, vp))); + ObjectWrapperParent* constructor = Unwrap(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp))); if (!constructor) return with_error(cx, JS_FALSE, "Could not unwrap CPOW constructor function"); AutoCheckOperation aco(cx, constructor); InfallibleTArray<JSVariant> in_argv(argc); jsval* argv = JS_ARGV(cx, vp); for (unsigned i = 0; i < argc; i++) @@ -675,17 +678,17 @@ ObjectWrapperParent::CPOW_Construct(JSCo /*static*/ JSBool ObjectWrapperParent::CPOW_HasInstance(JSContext *cx, JSHandleObject obj, JSMutableHandleValue v, JSBool *bp) { CPOW_LOG(("Calling CPOW_HasInstance...")); *bp = JS_FALSE; - ObjectWrapperParent* self = Unwrap(obj); + ObjectWrapperParent* self = Unwrap(cx, obj); if (!self) return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_HasInstance"); AutoCheckOperation aco(cx, self); JSVariant in_v; if (!jsval_to_JSVariant(cx, v, &in_v)) @@ -700,23 +703,23 @@ ObjectWrapperParent::CPOW_HasInstance(JS /*static*/ JSBool ObjectWrapperParent::CPOW_Equality(JSContext *cx, JSHandleObject obj, JSHandleValue v, JSBool *bp) { CPOW_LOG(("Calling CPOW_Equality...")); *bp = JS_FALSE; - ObjectWrapperParent* self = Unwrap(obj); + ObjectWrapperParent* self = Unwrap(cx, obj); if (!self) return with_error(cx, JS_FALSE, "Unwrapping failed in CPOW_Equality"); if (JSVAL_IS_PRIMITIVE(v)) return JS_TRUE; - ObjectWrapperParent* other = Unwrap(JSVAL_TO_OBJECT(v)); + ObjectWrapperParent* other = Unwrap(cx, JSVAL_TO_OBJECT(v)); if (!other) return JS_TRUE; *bp = (self == other); return JS_TRUE; }
--- a/js/ipc/ObjectWrapperParent.h +++ b/js/ipc/ObjectWrapperParent.h @@ -99,17 +99,17 @@ private: static JSBool CPOW_Equality(JSContext *cx, JSHandleObject obj, JSHandleValue v, JSBool *bp); static bool jsval_to_JSVariant(JSContext* cx, jsval from, JSVariant* to); static bool jsval_from_JSVariant(JSContext* cx, const JSVariant& from, jsval* to); static bool - JSObject_to_PObjectWrapperParent(JSObject* from, PObjectWrapperParent** to); + JSObject_to_PObjectWrapperParent(JSContext* cx, JSObject* from, PObjectWrapperParent** to); static bool JSObject_from_PObjectWrapperParent(JSContext* cx, const PObjectWrapperParent* from, JSMutableHandleObject to); static bool jsval_from_PObjectWrapperParent(JSContext* cx, const PObjectWrapperParent* from, jsval* to);
--- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -392,21 +392,30 @@ InitClassWithReserved(JSContext *cx, JSO JSPropertySpec *static_ps, JSFunctionSpec *static_fs); JS_FRIEND_API(const Value &) GetFunctionNativeReserved(RawObject fun, size_t which); JS_FRIEND_API(void) SetFunctionNativeReserved(RawObject fun, size_t which, const Value &val); -inline JSObject * -GetObjectProto(RawObject obj) +inline bool +GetObjectProto(JSContext *cx, JSObject *obj, JSObject **proto) { - /* FIXME */ - return reinterpret_cast<const shadow::Object*>(obj)->type->proto; + js::Class *clasp = GetObjectClass(obj); + if (clasp == &js::ObjectProxyClass || + clasp == &js::OuterWindowProxyClass || + clasp == &js::FunctionProxyClass) + { + /* FIXME */ + *proto = reinterpret_cast<const shadow::Object*>(obj)->type->proto; + } else { + *proto = reinterpret_cast<const shadow::Object*>(obj)->type->proto; + } + return true; } inline void * GetObjectPrivate(RawObject obj) { const shadow::Object *nobj = reinterpret_cast<const shadow::Object*>(obj); void **addr = reinterpret_cast<void**>(&nobj->fixedSlots()[nobj->numFixedSlots()]); return *addr;
--- a/js/xpconnect/src/XPCDebug.cpp +++ b/js/xpconnect/src/XPCDebug.cpp @@ -163,78 +163,16 @@ private: JSObject* array[max_count]; int member_count; }; static const int tab_width = 2; #define INDENT(_d) (_d)*tab_width, " " -static void PrintObjectBasics(JSObject* obj) -{ - if (JS_IsNative(obj)) - DebugDump("%p 'native' <%s>", - (void *)obj, js::GetObjectClass(obj)->name); - else - DebugDump("%p 'host'", (void *)obj); -} - -static void PrintObject(JSObject* obj, int depth, ObjectPile* pile) -{ - PrintObjectBasics(obj); - - switch (pile->Visit(obj)) { - case ObjectPile::primary: - DebugDump("%s", "\n"); - break; - case ObjectPile::seen: - DebugDump("%s", " (SEE ABOVE)\n"); - return; - case ObjectPile::overflow: - DebugDump("%s", " (TOO MANY OBJECTS)\n"); - return; - } - - if (!JS_IsNative(obj)) - return; - - JSObject* parent = js::GetObjectParent(obj); - JSObject* proto = js::GetObjectProto(obj); - - DebugDump("%*sparent: ", INDENT(depth+1)); - if (parent) - PrintObject(parent, depth+1, pile); - else - DebugDump("%s", "null\n"); - DebugDump("%*sproto: ", INDENT(depth+1)); - if (proto) - PrintObject(proto, depth+1, pile); - else - DebugDump("%s", "null\n"); -} - -JSBool -xpc_DumpJSObject(JSObject* obj) -{ - ObjectPile pile; - - DebugDump("%s", "Debugging reminders...\n"); - DebugDump("%s", " class: (JSClass*)(obj->fslots[2]-1)\n"); - DebugDump("%s", " parent: (JSObject*)(obj->fslots[1])\n"); - DebugDump("%s", " proto: (JSObject*)(obj->fslots[0])\n"); - DebugDump("%s", "\n"); - - if (obj) - PrintObject(obj, 0, &pile); - else - DebugDump("%s", "xpc_DumpJSObject passed null!\n"); - - return true; -} - #ifdef DEBUG void xpc_PrintAllReferencesTo(void *p) { /* p must be a JS object */ XPCJSRuntime* rt = nsXPConnect::GetRuntimeInstance(); JS_DumpHeap(rt->GetJSRuntime(), stdout, nullptr, JSTRACE_OBJECT, p, 0x7fffffff, nullptr); }
--- a/js/xpconnect/src/XPCWrappedNative.cpp +++ b/js/xpconnect/src/XPCWrappedNative.cpp @@ -1830,66 +1830,71 @@ XPCWrappedNative::GetWrappedNativeOfJSOb goto return_tearoff; } else { NS_ERROR("function object has parent of unknown class!"); return nullptr; } } restart: - for (cur = obj; cur; cur = js::GetObjectProto(cur)) { + for (cur = obj; cur; ) { // this is on two lines to make the compiler happy given the goto. js::Class* clazz; clazz = js::GetObjectClass(cur); if (IS_WRAPPER_CLASS(clazz)) { return_wrapper: JSBool isWN = IS_WN_WRAPPER_OBJECT(cur); XPCWrappedNative* wrapper = isWN ? (XPCWrappedNative*) js::GetObjectPrivate(cur) : nullptr; if (proto) { XPCWrappedNativeProto* wrapper_proto = isWN ? wrapper->GetProto() : GetSlimWrapperProto(cur); if (proto != wrapper_proto && (!protoClassInfo || !wrapper_proto || protoClassInfo != wrapper_proto->GetClassInfo())) - continue; + goto next; } if (pobj2) *pobj2 = isWN ? nullptr : cur; return wrapper; } if (IS_TEAROFF_CLASS(clazz)) { return_tearoff: XPCWrappedNative* wrapper = (XPCWrappedNative*) js::GetObjectPrivate(js::GetObjectParent(cur)); if (proto && proto != wrapper->GetProto() && (proto->GetScope() != wrapper->GetScope() || !protoClassInfo || !wrapper->GetProto() || protoClassInfo != wrapper->GetProto()->GetClassInfo())) - continue; + goto next; if (pobj2) *pobj2 = nullptr; XPCWrappedNativeTearOff* to = (XPCWrappedNativeTearOff*) js::GetObjectPrivate(cur); if (!to) return nullptr; if (pTearOff) *pTearOff = to; return wrapper; } // Unwrap any wrapper wrappers. - JSObject *unsafeObj = cx - ? XPCWrapper::Unwrap(cx, cur, /* stopAtOuter = */ false) - : js::UnwrapObject(cur, /* stopAtOuter = */ false); + JSObject *unsafeObj; + unsafeObj = cx + ? XPCWrapper::Unwrap(cx, cur, /* stopAtOuter = */ false) + : js::UnwrapObject(cur, /* stopAtOuter = */ false); if (unsafeObj) { obj = unsafeObj; goto restart; } + + next: + if (!js::GetObjectProto(cx, cur, &cur)) + return nullptr; } if (pobj2) *pobj2 = nullptr; return nullptr; } JSBool
--- a/js/xpconnect/src/dombindings.cpp +++ b/js/xpconnect/src/dombindings.cpp @@ -557,17 +557,19 @@ ListBase<LC>::getPropertyDescriptor(JSCo JSPropertyDescriptor *desc) { if (!getOwnPropertyDescriptor(cx, proxy, id, set, desc)) return false; if (desc->obj) return true; if (xpc::WrapperFactory::IsXrayWrapper(proxy)) return resolveNativeName(cx, proxy, id, desc); - JSObject *proto = js::GetObjectProto(proxy); + JSObject *proto; + if (!js::GetObjectProto(cx, proxy, &proto)) + return false; if (!proto) { desc->obj = NULL; return true; } return JS_GetPropertyDescriptorById(cx, proto, id, JSRESOLVE_QUALIFIED, desc); } JSClass ExpandoClass = { @@ -739,17 +741,19 @@ ListBase<LC>::has(JSContext *cx, JSObjec if (!hasOwn(cx, proxy, id, bp)) return false; // We have the property ourselves; no need to worry about our // prototype chain. if (*bp) return true; // OK, now we have to look at the proto - JSObject *proto = js::GetObjectProto(proxy); + JSObject *proto; + if (!js::GetObjectProto(cx, proxy, &proto)) + return false; if (!proto) return true; JSBool protoHasProp; bool ok = JS_HasPropertyById(cx, proto, id, &protoHasProp); if (ok) *bp = protoHasProp; return ok; @@ -792,17 +796,19 @@ ListBase<LC>::resolveNativeName(JSContex return Base::resolveNativeName(cx, proxy, id, desc); } template<class LC> bool ListBase<LC>::getPropertyOnPrototype(JSContext *cx, JSObject *proxy, jsid id, bool *found, JS::Value *vp) { - JSObject *proto = js::GetObjectProto(proxy); + JSObject *proto; + if (!js::GetObjectProto(cx, proxy, &proto)) + return false; if (!proto) return true; JSBool hasProp; if (!JS_HasPropertyById(cx, proto, id, &hasProp)) return false; *found = hasProp; @@ -913,17 +919,19 @@ ListBase<LC>::getElementIfPresent(JSCont *present = true; return true; } } } // No need to worry about name getters here, so just check the proto. - JSObject *proto = js::GetObjectProto(proxy); + JSObject *proto; + if (!js::GetObjectProto(cx, proxy, &proto)) + return false; if (proto) { JSBool isPresent; if (!JS_GetElementIfPresent(cx, proto, index, proxy, vp, &isPresent)) return false; *present = isPresent; return true; }
--- a/js/xpconnect/src/nsXPConnect.cpp +++ b/js/xpconnect/src/nsXPConnect.cpp @@ -2924,50 +2924,16 @@ JS_EXPORT_API(void) DumpJSEval(uint32_t nsresult rv; nsCOMPtr<nsIXPConnect> xpc(do_GetService(nsIXPConnect::GetCID(), &rv)); if (NS_SUCCEEDED(rv) && xpc) xpc->DebugDumpEvalInJSStackFrame(frameno, text); else printf("failed to get XPConnect service!\n"); } -JS_EXPORT_API(void) DumpJSObject(JSObject* obj) -{ - xpc_DumpJSObject(obj); -} - -JS_EXPORT_API(void) DumpJSValue(JS::Value val) -{ - printf("Dumping 0x%llu.\n", (long long) val.asRawBits()); - if (val.isNull()) { - printf("Value is null\n"); - } else if (val.isObject()) { - printf("Value is an object\n"); - DumpJSObject(&val.toObject()); - } else if (val.isNumber()) { - printf("Value is a number: "); - if (val.isInt32()) - printf("Integer %i\n", val.toInt32()); - else if (val.isDouble()) - printf("Floating-point value %f\n", val.toDouble()); - } else if (val.isString()) { - printf("Value is a string: "); - putc('<', stdout); - JS_FileEscapedString(stdout, val.toString(), 0); - fputs(">\n", stdout); - } else if (val.isBoolean()) { - printf("Value is boolean: "); - printf(val.isTrue() ? "true" : "false"); - } else if (val.isUndefined()) { - printf("Value is undefined\n"); - } else { - printf("No idea what this value is.\n"); - } -} - JS_EXPORT_API(void) DumpCompleteHeap() { nsCOMPtr<nsICycleCollectorListener> listener = do_CreateInstance("@mozilla.org/cycle-collector-logger;1"); if (!listener) { NS_WARNING("Failed to create CC logger"); return; }
--- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -72,17 +72,19 @@ JSObject * WrapperFactory::CreateXrayWaiver(JSContext *cx, JSObject *obj) { // The caller is required to have already done a lookup. // NB: This implictly performs the assertions of GetXrayWaiver. MOZ_ASSERT(!GetXrayWaiver(obj)); CompartmentPrivate *priv = GetCompartmentPrivate(obj); // Get a waiver for the proto. - JSObject *proto = js::GetObjectProto(obj); + JSObject *proto; + if (!js::GetObjectProto(cx, obj, &proto)) + return nullptr; if (proto && !(proto = WaiveXray(cx, proto))) return nullptr; // Create the waiver. JSAutoCompartment ac(cx, obj); if (!JS_WrapObject(cx, &proto)) return nullptr; JSObject *waiver = Wrapper::New(cx, obj, proto, @@ -523,17 +525,20 @@ WrapperFactory::IsLocationObject(JSObjec } JSObject * WrapperFactory::WrapLocationObject(JSContext *cx, JSObject *obj) { JSObject *xrayHolder = XrayUtils::createHolder(cx, obj, js::GetObjectParent(obj)); if (!xrayHolder) return nullptr; - JSObject *wrapperObj = Wrapper::New(cx, obj, js::GetObjectProto(obj), js::GetObjectParent(obj), + JSObject *proto; + if (!js::GetObjectProto(cx, obj, &proto)) + return nullptr; + JSObject *wrapperObj = Wrapper::New(cx, obj, proto, js::GetObjectParent(obj), &LW::singleton); if (!wrapperObj) return nullptr; js::SetProxyExtra(wrapperObj, 0, js::ObjectValue(*xrayHolder)); return wrapperObj; } // Call WaiveXrayAndWrap when you have a JS object that you don't want to be
--- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -485,26 +485,27 @@ GetWrappedNativeFromHolder(JSObject *hol static JSObject * GetWrappedNativeObjectFromHolder(JSObject *holder) { return GetWrappedNativeFromHolder(holder)->GetFlatJSObject(); } static inline JSObject * -FindWrapper(JSObject *wrapper) +FindWrapper(JSContext *cx, JSObject *wrapper) { while (!js::IsWrapper(wrapper) || !(Wrapper::wrapperHandler(wrapper)->flags() & WrapperFactory::IS_XRAY_WRAPPER_FLAG)) { if (js::IsWrapper(wrapper) && js::GetProxyHandler(wrapper) == &sandboxProxyHandler) { wrapper = SandboxProxyHandler::wrappedObject(wrapper); } else { - wrapper = js::GetObjectProto(wrapper); + if (!js::GetObjectProto(cx, wrapper, &wrapper)) + return nullptr; } // NB: we must eventually hit our wrapper. } return wrapper; } JSObject* @@ -521,17 +522,19 @@ XPCWrappedNativeXrayTraits::isResolving( } // Some DOM objects have shared properties that don't have an explicit // getter/setter and rely on the class getter/setter. We install a // class getter/setter on the holder object to trigger them. JSBool holder_get(JSContext *cx, JSHandleObject wrapper_, JSHandleId id, JSMutableHandleValue vp) { - JSObject *wrapper = FindWrapper(wrapper_); + JSObject *wrapper = FindWrapper(cx, wrapper_); + if (!wrapper) + return false; JSObject *holder = GetHolder(wrapper); XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder); if (NATIVE_HAS_FLAG(wn, WantGetProperty)) { JSAutoCompartment ac(cx, holder); bool retval = true; nsresult rv = wn->GetScriptableCallback()->GetProperty(wn, cx, wrapper, @@ -543,17 +546,19 @@ holder_get(JSContext *cx, JSHandleObject } } return true; } JSBool holder_set(JSContext *cx, JSHandleObject wrapper_, JSHandleId id, JSBool strict, JSMutableHandleValue vp) { - JSObject *wrapper = FindWrapper(wrapper_); + JSObject *wrapper = FindWrapper(cx, wrapper_); + if (!wrapper) + return false; JSObject *holder = GetHolder(wrapper); if (XPCWrappedNativeXrayTraits::isResolving(cx, holder, id)) { return true; } XPCWrappedNative *wn = GetWrappedNativeFromHolder(holder); if (NATIVE_HAS_FLAG(wn, WantSetProperty)) {