diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index 96f236299b0b..5427a73c9acd 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -4604,7 +4604,8 @@ GetExternalClassInfo(nsScriptNameSpaceManager *aNameSpaceManager, static nsresult ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx, - const PRUnichar *name, const nsDOMClassInfoData *ci_data, + JSObject *obj, const PRUnichar *name, + const nsDOMClassInfoData *ci_data, const nsGlobalNameStruct *name_struct, nsScriptNameSpaceManager *nameSpaceManager, JSObject *dot_prototype, PRBool install, PRBool *did_resolve); @@ -4703,8 +4704,9 @@ nsDOMClassInfo::PostCreatePrototype(JSContext * cx, JSObject * proto) NS_ENSURE_TRUE(nameSpaceManager, NS_OK); PRBool unused; - return ResolvePrototype(sXPConnect, win, cx, mData->mNameUTF16, mData, - nsnull, nameSpaceManager, proto, !found, &unused); + return ResolvePrototype(sXPConnect, win, cx, global, mData->mNameUTF16, + mData, nsnull, nameSpaceManager, proto, !found, + &unused); } // static @@ -6051,7 +6053,8 @@ GetXPCProto(nsIXPConnect *aXPConnect, JSContext *cx, nsGlobalWindow *aWin, // eTypeClassProto. static nsresult ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx, - const PRUnichar *name, const nsDOMClassInfoData *ci_data, + JSObject *obj, const PRUnichar *name, + const nsDOMClassInfoData *ci_data, const nsGlobalNameStruct *name_struct, nsScriptNameSpaceManager *nameSpaceManager, JSObject *dot_prototype, PRBool install, PRBool *did_resolve) @@ -6061,13 +6064,6 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx, name_struct->mType == nsGlobalNameStruct::eTypeClassProto), "Wrong type or missing ci_data!"); - JSObject *obj = aWin->FastGetGlobalJSObject(); - JSAutoEnterCompartment ac; - - if (!ac.enter(cx, obj)) { - return NS_ERROR_UNEXPECTED; - } - nsRefPtr constructor; nsresult rv = nsDOMConstructor::Create(name, ci_data, name_struct, aWin, getter_AddRefs(constructor)); @@ -6163,49 +6159,59 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx, } } - JSObject *proto = nsnull; + { + JSObject *winobj = aWin->FastGetGlobalJSObject(); - if (class_parent_name) { - jsval val; - - if (!::JS_LookupProperty(cx, obj, CutPrefix(class_parent_name), &val)) { + JSAutoEnterCompartment ac; + if (!ac.enter(cx, winobj)) { return NS_ERROR_UNEXPECTED; } - JSObject *tmp = JSVAL_IS_OBJECT(val) ? JSVAL_TO_OBJECT(val) : nsnull; + JSObject *proto = nsnull; - if (tmp) { - if (!::JS_LookupProperty(cx, tmp, "prototype", &val)) { + if (class_parent_name) { + jsval val; + + if (!::JS_LookupProperty(cx, winobj, CutPrefix(class_parent_name), &val)) { return NS_ERROR_UNEXPECTED; } - if (JSVAL_IS_OBJECT(val)) { - proto = JSVAL_TO_OBJECT(val); + JSObject *tmp = JSVAL_IS_OBJECT(val) ? JSVAL_TO_OBJECT(val) : nsnull; + + if (tmp) { + if (!::JS_LookupProperty(cx, tmp, "prototype", &val)) { + return NS_ERROR_UNEXPECTED; + } + + if (JSVAL_IS_OBJECT(val)) { + proto = JSVAL_TO_OBJECT(val); + } } } - } - if (dot_prototype) { - JSObject *xpc_proto_proto = ::JS_GetPrototype(cx, dot_prototype); + if (dot_prototype) { + JSObject *xpc_proto_proto = ::JS_GetPrototype(cx, dot_prototype); - if (proto && - (!xpc_proto_proto || - JS_GET_CLASS(cx, xpc_proto_proto) == sObjectClass)) { - if (!::JS_SetPrototype(cx, dot_prototype, proto)) { - return NS_ERROR_UNEXPECTED; + if (proto && + (!xpc_proto_proto || + JS_GET_CLASS(cx, xpc_proto_proto) == sObjectClass)) { + if (!::JS_SetPrototype(cx, dot_prototype, proto)) { + return NS_ERROR_UNEXPECTED; + } } + } else { + dot_prototype = ::JS_NewObject(cx, &sDOMConstructorProtoClass, proto, + winobj); + NS_ENSURE_TRUE(dot_prototype, NS_ERROR_OUT_OF_MEMORY); } - } else { - dot_prototype = ::JS_NewObject(cx, &sDOMConstructorProtoClass, proto, - obj); - NS_ENSURE_TRUE(dot_prototype, NS_ERROR_OUT_OF_MEMORY); } v = OBJECT_TO_JSVAL(dot_prototype); // Per ECMA, the prototype property is {DontEnum, DontDelete, ReadOnly} - if (!::JS_DefineProperty(cx, class_obj, "prototype", v, nsnull, nsnull, - JSPROP_PERMANENT | JSPROP_READONLY)) { + if (!JS_WrapValue(cx, &v) || + !JS_DefineProperty(cx, class_obj, "prototype", v, nsnull, nsnull, + JSPROP_PERMANENT | JSPROP_READONLY)) { return NS_ERROR_UNEXPECTED; } @@ -6310,7 +6316,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, ci_data = name_struct->mData; } - return ResolvePrototype(sXPConnect, aWin, cx, class_name, ci_data, + return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, ci_data, name_struct, nameSpaceManager, dot_prototype, PR_TRUE, did_resolve); } @@ -6323,7 +6329,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, if (name_struct->mType == nsGlobalNameStruct::eTypeClassProto) { // We don't have a XPConnect prototype object, let ResolvePrototype create // one. - return ResolvePrototype(sXPConnect, aWin, cx, class_name, nsnull, + return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, nsnull, name_struct, nameSpaceManager, nsnull, PR_TRUE, did_resolve); } @@ -6354,7 +6360,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, return NS_ERROR_UNEXPECTED; } - return ResolvePrototype(sXPConnect, aWin, cx, class_name, ci_data, + return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, ci_data, name_struct, nameSpaceManager, nsnull, PR_TRUE, did_resolve); }