Index: caps/src/nsScriptSecurityManager.cpp =================================================================== RCS file: /cvsroot/mozilla/caps/src/nsScriptSecurityManager.cpp,v retrieving revision 1.282 diff -up -r1.282 caps/src/nsScriptSecurityManager.cpp --- caps/src/nsScriptSecurityManager.cpp +++ caps/src/nsScriptSecurityManager.cpp @@ -96,7 +97,9 @@ JSRuntime *nsScriptSecurityManager static inline const PRUnichar * JSValIDToString(JSContext *cx, const jsval idval) { + ::JS_BeginRequest(cx); JSString *str = JS_ValueToString(cx, idval); + ::JS_EndRequest(cx); if(!str) return nsnull; return NS_REINTERPRET_CAST(PRUnichar*, JS_GetStringChars(str)); @@ -110,17 +113,21 @@ GetScriptContext(JSContext *cx) inline void SetPendingException(JSContext *cx, const char *aMsg) { + ::JS_BeginRequest(cx); JSString *str = JS_NewStringCopyZ(cx, aMsg); if (str) JS_SetPendingException(cx, STRING_TO_JSVAL(str)); + ::JS_EndRequest(cx); } inline void SetPendingException(JSContext *cx, const PRUnichar *aMsg) { + ::JS_BeginRequest(cx); JSString *str = JS_NewUCStringCopyZ(cx, NS_REINTERPRET_CAST(const jschar*, aMsg)); if (str) JS_SetPendingException(cx, STRING_TO_JSVAL(str)); + ::JS_EndRequest(cx); } // DomainPolicy members @@ -506,7 +520,9 @@ nsScriptSecurityManager::CheckConnect(JS nsresult rv = CheckLoadURIFromScript(cx, aTargetURI); if (NS_FAILED(rv)) return rv; + ::JS_BeginRequest(cx); JSString* propertyName = ::JS_InternString(cx, aPropertyName); + ::JS_EndRequest(cx); if (!propertyName) return NS_ERROR_OUT_OF_MEMORY; @@ -2743,7 +2804,9 @@ nsScriptSecurityManager::CheckComponentP // Look up the policy for this class. // while this isn't a property we'll treat it as such, using ACCESS_CALL_METHOD + ::JS_BeginRequest(cx); jsval cidVal = STRING_TO_JSVAL(::JS_InternString(cx, cid.get())); + ::JS_EndRequest(cx); ClassInfoData nameData(nsnull, "ClassID"); SecurityLevel securityLevel; @@ -3378,7 +3449,9 @@ nsScriptSecurityManager::InitDomainPolic if (end) *end = '\0'; + ::JS_BeginRequest(cx); JSString* propertyKey = ::JS_InternString(cx, start); + ::JS_EndRequest(cx); if (!propertyKey) return NS_ERROR_OUT_OF_MEMORY; Index: caps/src/nsSecurityManagerFactory.cpp =================================================================== RCS file: /cvsroot/mozilla/caps/src/nsSecurityManagerFactory.cpp,v retrieving revision 1.42 diff -up -r1.42 caps/src/nsSecurityManagerFactory.cpp --- caps/src/nsSecurityManagerFactory.cpp +++ caps/src/nsSecurityManagerFactory.cpp @@ -295,13 +295,17 @@ nsSecurityNameSet::InitializeNameSet(nsI */ JSObject *obj = global; JSObject *proto; + JS_BeginRequest(cx); while ((proto = JS_GetPrototype(cx, obj)) != nsnull) obj = proto; JSClass *objectClass = JS_GetClass(cx, obj); jsval v; - if (!JS_GetProperty(cx, global, "netscape", &v)) + if (!JS_GetProperty(cx, global, "netscape", &v)) { + JS_EndRequest(cx); return NS_ERROR_FAILURE; + } + JSObject *securityObj; if (JSVAL_IS_OBJECT(v)) { /* @@ -309,27 +313,37 @@ nsSecurityNameSet::InitializeNameSet(nsI * package. Get the "security" property. */ obj = JSVAL_TO_OBJECT(v); - if (!JS_GetProperty(cx, obj, "security", &v) || !JSVAL_IS_OBJECT(v)) + if (!JS_GetProperty(cx, obj, "security", &v) || !JSVAL_IS_OBJECT(v)) { + JS_EndRequest(cx); return NS_ERROR_FAILURE; + } securityObj = JSVAL_TO_OBJECT(v); } else { /* define netscape.security object */ obj = JS_DefineObject(cx, global, "netscape", objectClass, nsnull, 0); - if (obj == nsnull) + if (obj == nsnull) { + JS_EndRequest(cx); return NS_ERROR_FAILURE; + } securityObj = JS_DefineObject(cx, obj, "security", objectClass, nsnull, 0); - if (securityObj == nsnull) + if (securityObj == nsnull) { + JS_EndRequest(cx); return NS_ERROR_FAILURE; + } } /* Define PrivilegeManager object with the necessary "static" methods. */ obj = JS_DefineObject(cx, securityObj, "PrivilegeManager", objectClass, nsnull, 0); - if (obj == nsnull) + if (obj == nsnull) { + JS_EndRequest(cx); return NS_ERROR_FAILURE; + } - return JS_DefineFunctions(cx, obj, PrivilegeManager_static_methods) + JSBool ok = JS_DefineFunctions(cx, obj, PrivilegeManager_static_methods); + JS_EndRequest(cx); + return ok ? NS_OK : NS_ERROR_FAILURE; } Index: content/base/src/nsScriptLoader.cpp =================================================================== RCS file: /cvsroot/mozilla/content/base/src/nsScriptLoader.cpp,v retrieving revision 1.85 diff -up -r1.85 content/base/src/nsScriptLoader.cpp --- content/base/src/nsScriptLoader.cpp +++ content/base/src/nsScriptLoader.cpp @@ -754,7 +754,9 @@ nsScriptLoader::EvaluateScript(nsScriptL // Put the old script back in case it wants to do anything else. mCurrentScript = oldCurrent; + ::JS_BeginRequest(cx); ::JS_ReportPendingException(cx); + ::JS_EndRequest(cx); if (changed) { ::JS_SetOptions(cx, options); } Index: content/events/src/nsEventListenerManager.cpp =================================================================== RCS file: /cvsroot/mozilla/content/events/src/nsEventListenerManager.cpp,v retrieving revision 1.225 diff -up -r1.225 content/events/src/nsEventListenerManager.cpp --- content/events/src/nsEventListenerManager.cpp +++ content/events/src/nsEventListenerManager.cpp @@ -1426,10 +1439,12 @@ nsEventListenerManager::RegisterScriptEv rv = holder->GetJSObject(&jsobj); NS_ENSURE_SUCCESS(rv, rv); if (cx) { if (sAddListenerID == JSVAL_VOID) { + JS_BeginRequest(cx); sAddListenerID = STRING_TO_JSVAL(::JS_InternString(cx, "addEventListener")); + JS_EndRequest(cx); } rv = nsContentUtils::GetSecurityManager()-> Index: content/html/document/src/nsHTMLDocument.cpp =================================================================== RCS file: /cvsroot/mozilla/content/html/document/src/nsHTMLDocument.cpp,v retrieving revision 3.658 diff -up -r3.658 content/html/document/src/nsHTMLDocument.cpp --- content/html/document/src/nsHTMLDocument.cpp +++ content/html/document/src/nsHTMLDocument.cpp @@ -2335,7 +2334,9 @@ nsHTMLDocument::ScriptWriteCommon(PRBool NS_ENSURE_TRUE(argv, NS_ERROR_UNEXPECTED); if (argc == 1) { + JS_BeginRequest(cx); JSString *jsstr = JS_ValueToString(cx, argv[0]); + JS_EndRequest(cx); NS_ENSURE_TRUE(jsstr, NS_ERROR_OUT_OF_MEMORY); nsDependentString str(NS_REINTERPRET_CAST(const PRUnichar *, @@ -2349,7 +2350,9 @@ nsHTMLDocument::ScriptWriteCommon(PRBool nsAutoString string_buffer; for (i = 0; i < argc; ++i) { + JS_BeginRequest(cx); JSString *str = JS_ValueToString(cx, argv[i]); + JS_EndRequest(cx); NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY); string_buffer.Append(NS_REINTERPRET_CAST(const PRUnichar *, Index: content/xbl/src/nsXBLBinding.cpp =================================================================== RCS file: /cvsroot/mozilla/content/xbl/src/nsXBLBinding.cpp,v retrieving revision 1.208 diff -up -r1.208 content/xbl/src/nsXBLBinding.cpp --- content/xbl/src/nsXBLBinding.cpp +++ content/xbl/src/nsXBLBinding.cpp @@ -997,6 +997,7 @@ nsXBLBinding::DoInitJSClass(JSContext *c nsCAutoString className(aClassName); JSObject* parent_proto = nsnull; // If we have an "obj" we can set this + ::JS_BeginRequest(cx); if (obj) { // Retrieve the current prototype of obj. parent_proto = ::JS_GetPrototype(cx, obj); @@ -1008,6 +1009,7 @@ nsXBLBinding::DoInitJSClass(JSContext *c jsid parent_proto_id; if (!::JS_GetObjectId(cx, parent_proto, &parent_proto_id)) { // Probably OOM + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } @@ -1046,8 +1048,10 @@ nsXBLBinding::DoInitJSClass(JSContext *c // We need to create a struct for this class. c = new nsXBLJSClass(className); - if (!c) + if (!c) { + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; + } } else { // Pull the least recently used class struct off the list. JSCList* lru = (nsXBLService::gClassLRUList).next; @@ -1090,6 +1094,7 @@ nsXBLBinding::DoInitJSClass(JSContext *c c->Drop(); + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } @@ -1102,10 +1107,12 @@ nsXBLBinding::DoInitJSClass(JSContext *c if (obj) { // Set the prototype of our object to be the new class. if (!::JS_SetPrototype(cx, obj, proto)) { + ::JS_EndRequest(cx); return NS_ERROR_FAILURE; } } + ::JS_EndRequest(cx); return NS_OK; } Index: content/xbl/src/nsXBLDocumentInfo.cpp =================================================================== RCS file: /cvsroot/mozilla/content/xbl/src/nsXBLDocumentInfo.cpp,v retrieving revision 1.42 diff -up -r1.42 content/xbl/src/nsXBLDocumentInfo.cpp --- content/xbl/src/nsXBLDocumentInfo.cpp +++ content/xbl/src/nsXBLDocumentInfo.cpp @@ -254,8 +254,10 @@ nsXBLDocGlobalObject::GetContext() JSContext *cx = (JSContext *)mScriptContext->GetNativeContext(); + ::JS_BeginRequest(cx); JS_SetErrorReporter(cx, XBL_ProtoErrorReporter); mJSObject = ::JS_NewObject(cx, &gSharedGlobalClass, nsnull, nsnull); + ::JS_EndRequest(cx); if (!mJSObject) return nsnull; Index: content/xbl/src/nsXBLProtoImplField.cpp =================================================================== RCS file: /cvsroot/mozilla/content/xbl/src/nsXBLProtoImplField.cpp,v retrieving revision 1.15 diff -up -r1.15 content/xbl/src/nsXBLProtoImplField.cpp --- content/xbl/src/nsXBLProtoImplField.cpp +++ content/xbl/src/nsXBLProtoImplField.cpp @@ -138,8 +138,11 @@ nsXBLProtoImplField::InstallMember(nsISc if (!undefined) { // Define the evaluated result as a JS property nsDependentString name(mName); - if (!::JS_DefineUCProperty(cx, scriptObject, NS_REINTERPRET_CAST(const jschar*, mName), - name.Length(), result, nsnull, nsnull, mJSAttributes)) + ::JS_BeginRequest(cx); + JSBool ok = ::JS_DefineUCProperty(cx, scriptObject, NS_REINTERPRET_CAST(const jschar*, mName), + name.Length(), result, nsnull, nsnull, mJSAttributes); + ::JS_EndRequest(cx); + if (!ok) return NS_ERROR_OUT_OF_MEMORY; } Index: content/xbl/src/nsXBLProtoImplMethod.cpp =================================================================== RCS file: /cvsroot/mozilla/content/xbl/src/nsXBLProtoImplMethod.cpp,v retrieving revision 1.26 diff -up -r1.26 content/xbl/src/nsXBLProtoImplMethod.cpp --- content/xbl/src/nsXBLProtoImplMethod.cpp +++ content/xbl/src/nsXBLProtoImplMethod.cpp @@ -154,16 +154,19 @@ nsXBLProtoImplMethod::InstallMember(nsIS JSObject * globalObject = sgo->GetGlobalJSObject(); // now we want to reevaluate our property using aContext and the script object for this window... + nsresult rv = NS_OK; if (mJSMethodObject && targetClassObject) { nsDependentString name(mName); + ::JS_BeginRequest(cx); JSObject * method = ::JS_CloneFunctionObject(cx, mJSMethodObject, globalObject); if (!method || !::JS_DefineUCProperty(cx, targetClassObject, NS_REINTERPRET_CAST(const jschar*, mName), name.Length(), OBJECT_TO_JSVAL(method), NULL, NULL, JSPROP_ENUMERATE)) - return NS_ERROR_OUT_OF_MEMORY; + rv = NS_ERROR_OUT_OF_MEMORY; + ::JS_EndRequest(cx); } - return NS_OK; + return rv; } nsresult @@ -318,8 +321,10 @@ nsXBLProtoImplAnonymousMethod::Execute(n // Clone the function object, using thisObject as the parent so "this" is in // the scope chain of the resulting function (for backwards compat to the // days when this was an event handler). + ::JS_BeginRequest(cx); JSObject* method = ::JS_CloneFunctionObject(cx, mJSMethodObject, thisObject); + ::JS_EndRequest(cx); if (!method) { return NS_ERROR_OUT_OF_MEMORY; } @@ -336,8 +341,10 @@ nsXBLProtoImplAnonymousMethod::Execute(n JSBool ok = JS_TRUE; if (NS_SUCCEEDED(rv)) { jsval retval; + ::JS_BeginRequest(cx); ok = ::JS_CallFunctionValue(cx, thisObject, OBJECT_TO_JSVAL(method), 0 /* argc */, nsnull /* argv */, &retval); + ::JS_EndRequest(cx); } if (!ok) { Index: content/xbl/src/nsXBLProtoImplProperty.cpp =================================================================== RCS file: /cvsroot/mozilla/content/xbl/src/nsXBLProtoImplProperty.cpp,v retrieving revision 1.22 diff -up -r1.22 content/xbl/src/nsXBLProtoImplProperty.cpp --- content/xbl/src/nsXBLProtoImplProperty.cpp +++ content/xbl/src/nsXBLProtoImplProperty.cpp @@ -192,29 +192,36 @@ nsXBLProtoImplProperty::InstallMember(ns JSObject * globalObject = sgo->GetGlobalJSObject(); // now we want to reevaluate our property using aContext and the script object for this window... - if ((mJSGetterObject || mJSSetterObject) && targetClassObject) { - JSObject * getter = nsnull; - if (mJSGetterObject) - if (!(getter = ::JS_CloneFunctionObject(cx, mJSGetterObject, globalObject))) - return NS_ERROR_OUT_OF_MEMORY; + if (!targetClassObject || !(mJSGetterObject && mJSSetterObject)) + return NS_OK; - nsresult rv; - nsAutoGCRoot(&getter, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - JSObject * setter = nsnull; - if (mJSSetterObject) - if (!(setter = ::JS_CloneFunctionObject(cx, mJSSetterObject, globalObject))) - return NS_ERROR_OUT_OF_MEMORY; - - nsDependentString name(mName); - if (!::JS_DefineUCProperty(cx, targetClassObject, - NS_REINTERPRET_CAST(const jschar*, mName), - name.Length(), JSVAL_VOID, (JSPropertyOp) getter, - (JSPropertyOp) setter, mJSAttributes)) + JSObject * getter = nsnull; + ::JS_BeginRequest(cx); + if (mJSGetterObject) + if (!(getter = ::JS_CloneFunctionObject(cx, mJSGetterObject, globalObject))) { + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; - } - return NS_OK; + } + + nsresult rv; + nsAutoGCRoot(&getter, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + JSObject * setter = nsnull; + if (NS_SUCCEEDED(rv) && mJSSetterObject) + if (!(setter = ::JS_CloneFunctionObject(cx, mJSSetterObject, globalObject))) + rv = NS_ERROR_OUT_OF_MEMORY; + + nsDependentString name(mName); + if (NS_SUCCEEDED(rv) && + !::JS_DefineUCProperty(cx, targetClassObject, + NS_REINTERPRET_CAST(const jschar*, mName), + name.Length(), JSVAL_VOID, (JSPropertyOp) getter, + (JSPropertyOp) setter, mJSAttributes)) + rv = NS_ERROR_OUT_OF_MEMORY; + ::JS_EndRequest(cx); + + return rv; } nsresult Index: content/xul/content/src/nsXULElement.cpp =================================================================== RCS file: /cvsroot/mozilla/content/xul/content/src/nsXULElement.cpp,v retrieving revision 1.610 diff -up -r1.610 content/xul/content/src/nsXULElement.cpp --- content/xul/content/src/nsXULElement.cpp +++ content/xul/content/src/nsXULElement.cpp @@ -2994,6 +2994,7 @@ nsXULPrototypeScript::Serialize(nsIObjec JSScript *script = NS_REINTERPRET_CAST(JSScript*, ::JS_GetPrivate(cx, mJSObject)); + ::JS_BeginRequest(cx); if (! ::JS_XDRScript(xdr, &script)) { rv = NS_ERROR_FAILURE; // likely to be a principals serialization error } else { @@ -3022,6 +3023,7 @@ nsXULPrototypeScript::Serialize(nsIObjec } ::JS_XDRDestroy(xdr); + ::JS_EndRequest(cx); if (NS_FAILED(rv)) return rv; PRUint32 version = PRUint32(mLangVersion @@ -3129,6 +3131,7 @@ nsXULPrototypeScript::Deserialize(nsIObj rv = NS_ERROR_OUT_OF_MEMORY; } else { xdr->userdata = (void*) aStream; + ::JS_BeginRequest(cx); ::JS_XDRMemSetData(xdr, data, size); JSScript *script = nsnull; @@ -3167,6 +3170,7 @@ nsXULPrototypeScript::Deserialize(nsIObj if (data) ::JS_XDRMemSetData(xdr, NULL, 0); ::JS_XDRDestroy(xdr); + ::JS_EndRequest(cx); } // If data is null now, it must have been freed while deserializing an Index: content/xul/document/src/nsXULPrototypeDocument.cpp =================================================================== RCS file: /cvsroot/mozilla/content/xul/document/src/nsXULPrototypeDocument.cpp,v retrieving revision 1.75 diff -up -r1.75 content/xul/document/src/nsXULPrototypeDocument.cpp --- content/xul/document/src/nsXULPrototypeDocument.cpp +++ content/xul/document/src/nsXULPrototypeDocument.cpp @@ -817,15 +817,18 @@ nsXULPDGlobalObject::GetContext() JSContext *cx = (JSContext *)mScriptContext->GetNativeContext(); + ::JS_BeginRequest(cx); mJSObject = ::JS_NewObject(cx, &gSharedGlobalClass, nsnull, nsnull); + if (mJSObject) { + ::JS_SetGlobalObject(cx, mJSObject); + + // Add an owning reference from JS back to us. This'll be + // released when the JSObject is finalized. + ::JS_SetPrivate(cx, mJSObject, this); + } + ::JS_EndRequest(cx); if (!mJSObject) return nsnull; - - ::JS_SetGlobalObject(cx, mJSObject); - - // Add an owning reference from JS back to us. This'll be - // released when the JSObject is finalized. - ::JS_SetPrivate(cx, mJSObject, this); NS_ADDREF(this); } Index: dom/src/base/nsDOMClassInfo.cpp =================================================================== RCS file: /cvsroot/mozilla/dom/src/base/nsDOMClassInfo.cpp,v retrieving revision 1.349 diff -up -r1.349 dom/src/base/nsDOMClassInfo.cpp --- dom/src/base/nsDOMClassInfo.cpp +++ dom/src/base/nsDOMClassInfo.cpp @@ -1322,80 +1322,86 @@ nsDOMClassInfo::DefineStaticJSVals(JSCon #define SET_JSVAL_TO_STRING(_val, _cx, _str) \ _val = GetInternedJSVal(_cx, _str); \ if (!JSVAL_IS_STRING(_val)) { \ - return NS_ERROR_OUT_OF_MEMORY; \ + break; \ } - SET_JSVAL_TO_STRING(sTop_id, cx, "top"); - SET_JSVAL_TO_STRING(sParent_id, cx, "parent"); - SET_JSVAL_TO_STRING(sScrollbars_id, cx, "scrollbars"); - SET_JSVAL_TO_STRING(sLocation_id, cx, "location"); - SET_JSVAL_TO_STRING(sConstructor_id, cx, "constructor"); - SET_JSVAL_TO_STRING(s_content_id, cx, "_content"); - SET_JSVAL_TO_STRING(sContent_id, cx, "content"); - SET_JSVAL_TO_STRING(sMenubar_id, cx, "menubar"); - SET_JSVAL_TO_STRING(sToolbar_id, cx, "toolbar"); - SET_JSVAL_TO_STRING(sLocationbar_id, cx, "locationbar"); - SET_JSVAL_TO_STRING(sPersonalbar_id, cx, "personalbar"); - SET_JSVAL_TO_STRING(sStatusbar_id, cx, "statusbar"); - SET_JSVAL_TO_STRING(sDirectories_id, cx, "directories"); - SET_JSVAL_TO_STRING(sControllers_id, cx, "controllers"); - SET_JSVAL_TO_STRING(sLength_id, cx, "length"); - SET_JSVAL_TO_STRING(sInnerHeight_id, cx, "innerHeight"); - SET_JSVAL_TO_STRING(sInnerWidth_id, cx, "innerWidth"); - SET_JSVAL_TO_STRING(sOuterHeight_id, cx, "outerHeight"); - SET_JSVAL_TO_STRING(sOuterWidth_id, cx, "outerWidth"); - SET_JSVAL_TO_STRING(sScreenX_id, cx, "screenX"); - SET_JSVAL_TO_STRING(sScreenY_id, cx, "screenY"); - SET_JSVAL_TO_STRING(sStatus_id, cx, "status"); - SET_JSVAL_TO_STRING(sName_id, cx, "name"); - SET_JSVAL_TO_STRING(sOnmousedown_id, cx, "onmousedown"); - SET_JSVAL_TO_STRING(sOnmouseup_id, cx, "onmouseup"); - SET_JSVAL_TO_STRING(sOnclick_id, cx, "onclick"); - SET_JSVAL_TO_STRING(sOndblclick_id, cx, "ondblclick"); - SET_JSVAL_TO_STRING(sOncontextmenu_id, cx, "oncontextmenu"); - SET_JSVAL_TO_STRING(sOnmouseover_id, cx, "onmouseover"); - SET_JSVAL_TO_STRING(sOnmouseout_id, cx, "onmouseout"); - SET_JSVAL_TO_STRING(sOnkeydown_id, cx, "onkeydown"); - SET_JSVAL_TO_STRING(sOnkeyup_id, cx, "onkeyup"); - SET_JSVAL_TO_STRING(sOnkeypress_id, cx, "onkeypress"); - SET_JSVAL_TO_STRING(sOnmousemove_id, cx, "onmousemove"); - SET_JSVAL_TO_STRING(sOnfocus_id, cx, "onfocus"); - SET_JSVAL_TO_STRING(sOnblur_id, cx, "onblur"); - SET_JSVAL_TO_STRING(sOnsubmit_id, cx, "onsubmit"); - SET_JSVAL_TO_STRING(sOnreset_id, cx, "onreset"); - SET_JSVAL_TO_STRING(sOnchange_id, cx, "onchange"); - SET_JSVAL_TO_STRING(sOnselect_id, cx, "onselect"); - SET_JSVAL_TO_STRING(sOnload_id, cx, "onload"); - SET_JSVAL_TO_STRING(sOnbeforeunload_id, cx, "onbeforeunload"); - SET_JSVAL_TO_STRING(sOnunload_id, cx, "onunload"); - SET_JSVAL_TO_STRING(sOnpageshow_id, cx, "onpageshow"); - SET_JSVAL_TO_STRING(sOnpagehide_id, cx, "onpagehide"); - SET_JSVAL_TO_STRING(sOnabort_id, cx, "onabort"); - SET_JSVAL_TO_STRING(sOnerror_id, cx, "onerror"); - SET_JSVAL_TO_STRING(sOnpaint_id, cx, "onpaint"); - SET_JSVAL_TO_STRING(sOnresize_id, cx, "onresize"); - SET_JSVAL_TO_STRING(sOnscroll_id, cx, "onscroll"); - SET_JSVAL_TO_STRING(sScrollIntoView_id, cx, "scrollIntoView"); - SET_JSVAL_TO_STRING(sScrollX_id, cx, "scrollX"); - SET_JSVAL_TO_STRING(sScrollY_id, cx, "scrollY"); - SET_JSVAL_TO_STRING(sScrollMaxX_id, cx, "scrollMaxX"); - SET_JSVAL_TO_STRING(sScrollMaxY_id, cx, "scrollMaxY"); - SET_JSVAL_TO_STRING(sOpen_id, cx, "open"); - SET_JSVAL_TO_STRING(sItem_id, cx, "item"); - SET_JSVAL_TO_STRING(sNamedItem_id, cx, "namedItem"); - SET_JSVAL_TO_STRING(sEnumerate_id, cx, "enumerateProperties"); - SET_JSVAL_TO_STRING(sNavigator_id, cx, "navigator"); - SET_JSVAL_TO_STRING(sDocument_id, cx, "document"); - SET_JSVAL_TO_STRING(sWindow_id, cx, "window"); - SET_JSVAL_TO_STRING(sFrames_id, cx, "frames"); - SET_JSVAL_TO_STRING(sSelf_id, cx, "self"); - SET_JSVAL_TO_STRING(sOpener_id, cx, "opener"); - SET_JSVAL_TO_STRING(sAdd_id, cx, "add"); - SET_JSVAL_TO_STRING(sAll_id, cx, "all"); - SET_JSVAL_TO_STRING(sTags_id, cx, "tags"); - SET_JSVAL_TO_STRING(sAddEventListener_id,cx, "addEventListener"); + ::JS_BeginRequest(cx); + nsresult rv = NS_ERROR_OUT_OF_MEMORY; + do { + SET_JSVAL_TO_STRING(sTop_id, cx, "top"); + SET_JSVAL_TO_STRING(sParent_id, cx, "parent"); + SET_JSVAL_TO_STRING(sScrollbars_id, cx, "scrollbars"); + SET_JSVAL_TO_STRING(sLocation_id, cx, "location"); + SET_JSVAL_TO_STRING(sConstructor_id, cx, "constructor"); + SET_JSVAL_TO_STRING(s_content_id, cx, "_content"); + SET_JSVAL_TO_STRING(sContent_id, cx, "content"); + SET_JSVAL_TO_STRING(sMenubar_id, cx, "menubar"); + SET_JSVAL_TO_STRING(sToolbar_id, cx, "toolbar"); + SET_JSVAL_TO_STRING(sLocationbar_id, cx, "locationbar"); + SET_JSVAL_TO_STRING(sPersonalbar_id, cx, "personalbar"); + SET_JSVAL_TO_STRING(sStatusbar_id, cx, "statusbar"); + SET_JSVAL_TO_STRING(sDirectories_id, cx, "directories"); + SET_JSVAL_TO_STRING(sControllers_id, cx, "controllers"); + SET_JSVAL_TO_STRING(sLength_id, cx, "length"); + SET_JSVAL_TO_STRING(sInnerHeight_id, cx, "innerHeight"); + SET_JSVAL_TO_STRING(sInnerWidth_id, cx, "innerWidth"); + SET_JSVAL_TO_STRING(sOuterHeight_id, cx, "outerHeight"); + SET_JSVAL_TO_STRING(sOuterWidth_id, cx, "outerWidth"); + SET_JSVAL_TO_STRING(sScreenX_id, cx, "screenX"); + SET_JSVAL_TO_STRING(sScreenY_id, cx, "screenY"); + SET_JSVAL_TO_STRING(sStatus_id, cx, "status"); + SET_JSVAL_TO_STRING(sName_id, cx, "name"); + SET_JSVAL_TO_STRING(sOnmousedown_id, cx, "onmousedown"); + SET_JSVAL_TO_STRING(sOnmouseup_id, cx, "onmouseup"); + SET_JSVAL_TO_STRING(sOnclick_id, cx, "onclick"); + SET_JSVAL_TO_STRING(sOndblclick_id, cx, "ondblclick"); + SET_JSVAL_TO_STRING(sOncontextmenu_id, cx, "oncontextmenu"); + SET_JSVAL_TO_STRING(sOnmouseover_id, cx, "onmouseover"); + SET_JSVAL_TO_STRING(sOnmouseout_id, cx, "onmouseout"); + SET_JSVAL_TO_STRING(sOnkeydown_id, cx, "onkeydown"); + SET_JSVAL_TO_STRING(sOnkeyup_id, cx, "onkeyup"); + SET_JSVAL_TO_STRING(sOnkeypress_id, cx, "onkeypress"); + SET_JSVAL_TO_STRING(sOnmousemove_id, cx, "onmousemove"); + SET_JSVAL_TO_STRING(sOnfocus_id, cx, "onfocus"); + SET_JSVAL_TO_STRING(sOnblur_id, cx, "onblur"); + SET_JSVAL_TO_STRING(sOnsubmit_id, cx, "onsubmit"); + SET_JSVAL_TO_STRING(sOnreset_id, cx, "onreset"); + SET_JSVAL_TO_STRING(sOnchange_id, cx, "onchange"); + SET_JSVAL_TO_STRING(sOnselect_id, cx, "onselect"); + SET_JSVAL_TO_STRING(sOnload_id, cx, "onload"); + SET_JSVAL_TO_STRING(sOnbeforeunload_id, cx, "onbeforeunload"); + SET_JSVAL_TO_STRING(sOnunload_id, cx, "onunload"); + SET_JSVAL_TO_STRING(sOnpageshow_id, cx, "onpageshow"); + SET_JSVAL_TO_STRING(sOnpagehide_id, cx, "onpagehide"); + SET_JSVAL_TO_STRING(sOnabort_id, cx, "onabort"); + SET_JSVAL_TO_STRING(sOnerror_id, cx, "onerror"); + SET_JSVAL_TO_STRING(sOnpaint_id, cx, "onpaint"); + SET_JSVAL_TO_STRING(sOnresize_id, cx, "onresize"); + SET_JSVAL_TO_STRING(sOnscroll_id, cx, "onscroll"); + SET_JSVAL_TO_STRING(sScrollIntoView_id, cx, "scrollIntoView"); + SET_JSVAL_TO_STRING(sScrollX_id, cx, "scrollX"); + SET_JSVAL_TO_STRING(sScrollY_id, cx, "scrollY"); + SET_JSVAL_TO_STRING(sScrollMaxX_id, cx, "scrollMaxX"); + SET_JSVAL_TO_STRING(sScrollMaxY_id, cx, "scrollMaxY"); + SET_JSVAL_TO_STRING(sOpen_id, cx, "open"); + SET_JSVAL_TO_STRING(sItem_id, cx, "item"); + SET_JSVAL_TO_STRING(sNamedItem_id, cx, "namedItem"); + SET_JSVAL_TO_STRING(sEnumerate_id, cx, "enumerateProperties"); + SET_JSVAL_TO_STRING(sNavigator_id, cx, "navigator"); + SET_JSVAL_TO_STRING(sDocument_id, cx, "document"); + SET_JSVAL_TO_STRING(sWindow_id, cx, "window"); + SET_JSVAL_TO_STRING(sFrames_id, cx, "frames"); + SET_JSVAL_TO_STRING(sSelf_id, cx, "self"); + SET_JSVAL_TO_STRING(sOpener_id, cx, "opener"); + SET_JSVAL_TO_STRING(sAdd_id, cx, "add"); + SET_JSVAL_TO_STRING(sAll_id, cx, "all"); + SET_JSVAL_TO_STRING(sTags_id, cx, "tags"); + SET_JSVAL_TO_STRING(sAddEventListener_id,cx, "addEventListener"); + rv = NS_OK; + } while (0); + ::JS_EndRequest(cx); - return NS_OK; + return rv; } // static @@ -1450,7 +1456,9 @@ nsDOMClassInfo::ThrowJSException(JSConte rv = WrapNative(cx, ::JS_GetGlobalObject(cx), exception, NS_GET_IID(nsIException), &jv, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); + ::JS_BeginRequest(cx); JS_SetPendingException(cx, jv); + ::JS_EndRequest(cx); return NS_OK; } @@ -3071,7 +3076,10 @@ nsDOMClassInfo::GetArrayIndexFromId(JSCo *aIsNumber = PR_FALSE; } - if (!::JS_ValueToNumber(cx, id, &array_index)) { + ::JS_BeginRequest(cx); + JSBool ok = ::JS_ValueToNumber(cx, id, &array_index); + ::JS_EndRequest(cx); + if (!ok) { return -1; } @@ -3262,11 +3270,14 @@ nsDOMClassInfo::PostCreate(nsIXPConnectW wrapper->GetJSObjectPrototype(&proto); + ::JS_BeginRequest(cx); JSObject *proto_proto = ::JS_GetPrototype(cx, proto); JSClass *proto_proto_class = JS_GET_CLASS(cx, proto_proto); if (proto_proto_class != sObjectClass) { + ::JS_EndRequest(cx); + // We've just wrapped an object of a type that has been wrapped on // this scope already so the prototype of the xpcwrapped native's // prototype is already set up. @@ -3298,7 +3309,9 @@ nsDOMClassInfo::PostCreate(nsIXPConnectW JSObject *global = GetGlobalJSObject(cx, obj); jsval val; - if (!::JS_GetProperty(cx, global, mData->mName, &val)) { + JSBool ok = ::JS_GetProperty(cx, global, mData->mName, &val); + ::JS_EndRequest(cx); + if (!ok) { return NS_ERROR_UNEXPECTED; } @@ -3381,27 +3394,34 @@ nsDOMClassInfo::ResolveConstructor(JSCon { JSObject *global = GetGlobalJSObject(cx, obj); - jsval val; - if (!::JS_GetProperty(cx, global, mData->mName, &val)) { - return NS_ERROR_UNEXPECTED; - } - - if (!JSVAL_IS_PRIMITIVE(val)) { - // If val is not an (non-null) object there either is no - // constructor for this class, or someone messed with - // window.classname, just fall through and let the JS engine - // return the Object constructor. - - JSString *str = JSVAL_TO_STRING(sConstructor_id); - if (!::JS_SetUCProperty(cx, obj, ::JS_GetStringChars(str), - ::JS_GetStringLength(str), &val)) { - return NS_ERROR_UNEXPECTED; + nsresult rv = NS_ERROR_UNEXPECTED; + do { + jsval val; + ::JS_BeginRequest(cx); + JSBool ok = ::JS_GetProperty(cx, global, mData->mName, &val); + if (!ok) { + break; } - *objp = obj; - } + if (!JSVAL_IS_PRIMITIVE(val)) { + // If val is not an (non-null) object there either is no + // constructor for this class, or someone messed with + // window.classname, just fall through and let the JS engine + // return the Object constructor. + + JSString *str = JSVAL_TO_STRING(sConstructor_id); + if (!::JS_SetUCProperty(cx, obj, ::JS_GetStringChars(str), + ::JS_GetStringLength(str), &val)) { + break; + } - return NS_OK; + *objp = obj; + } + + rv = NS_OK; + } while (0); + ::JS_EndRequest(cx); + return rv; } NS_IMETHODIMP @@ -3816,11 +3836,12 @@ nsWindowSH::PreCreate(nsISupports *nativ if (!sObjectClass) { JSObject *obj, *proto = globalObj; - + ::JS_BeginRequest(cx); do { obj = proto; proto = ::JS_GetPrototype(cx, obj); } while (proto); + ::JS_EndRequest(cx); sObjectClass = JS_GET_CLASS(cx, obj); } @@ -3995,6 +4016,7 @@ nsWindowSH::InvalidateGlobalScopePollute { JSObject *proto; + ::JS_BeginRequest(cx); while ((proto = ::JS_GetPrototype(cx, obj))) { if (JS_GET_CLASS(cx, proto) == &sGlobalScopePolluterClass) { nsIHTMLDocument *doc = (nsIHTMLDocument *)::JS_GetPrivate(cx, proto); @@ -4012,6 +4034,7 @@ nsWindowSH::InvalidateGlobalScopePollute obj = proto; } + ::JS_EndRequest(cx); } // static @@ -4025,8 +4048,10 @@ nsWindowSH::InstallGlobalScopePolluter(J return NS_OK; } + ::JS_BeginRequest(cx); JSObject *gsp = ::JS_NewObject(cx, &sGlobalScopePolluterClass, nsnull, obj); if (!gsp) { + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } @@ -4039,6 +4064,7 @@ nsWindowSH::InstallGlobalScopePolluter(J if (JS_GET_CLASS(cx, proto) == sObjectClass) { // Set the global scope polluters prototype to Object.prototype if (!::JS_SetPrototype(cx, gsp, proto)) { + ::JS_EndRequest(cx); return NS_ERROR_UNEXPECTED; } @@ -4050,13 +4076,12 @@ nsWindowSH::InstallGlobalScopePolluter(J // And then set the prototype of the object whose prototype was // Object.prototype to be the global scope polluter. - if (!::JS_SetPrototype(cx, o, gsp)) { - return NS_ERROR_UNEXPECTED; - } - - if (!::JS_SetPrivate(cx, gsp, doc)) { + if (!::JS_SetPrototype(cx, o, gsp) || + !::JS_SetPrivate(cx, gsp, doc)) { + ::JS_EndRequest(cx); return NS_ERROR_UNEXPECTED; } + ::JS_EndRequest(cx); // The global scope polluter will release doc on destruction (or // invalidation). @@ -4087,18 +4112,22 @@ nsWindowSH::GetProperty(nsIXPConnectWrap { nsGlobalWindow *win = nsGlobalWindow::FromWrapper(wrapper); + ::JS_BeginRequest(cx); #ifdef DEBUG_SH_FORWARDING { - nsDependentJSString str(::JS_ValueToString(cx, id)); + jschar *jsstr = ::JS_ValueToString(cx, id); + if (jsstr) { + nsDependentJSString str(jsstr); - if (win->IsInnerWindow()) { + if (win->IsInnerWindow()) { #ifdef DEBUG_PRINT_INNER - printf("Property '%s' get on inner window %p\n", - NS_ConvertUTF16toUTF8(str).get(), (void *)win); + printf("Property '%s' get on inner window %p\n", + NS_ConvertUTF16toUTF8(str).get(), (void *)win); #endif - } else { - printf("Property '%s' get on outer window %p\n", - NS_ConvertUTF16toUTF8(str).get(), (void *)win); + } else { + printf("Property '%s' get on outer window %p\n", + NS_ConvertUTF16toUTF8(str).get(), (void *)win); + } } } #endif @@ -4126,9 +4155,11 @@ nsWindowSH::GetProperty(nsIXPConnectWrap } else { NS_ERROR("Write me!"); + ::JS_EndRequest(cx); return NS_ERROR_NOT_IMPLEMENTED; } + ::JS_EndRequest(cx); return NS_OK; } } @@ -4137,6 +4168,7 @@ nsWindowSH::GetProperty(nsIXPConnectWrap // whacky, that's because this method is *extremely* performace // critical. Don't touch this unless you know what you're doing. + ::JS_EndRequest(cx); if (JSVAL_IS_INT(id)) { // If we're accessing a numeric property we'll treat that as if // window.frames[n] is accessed (since window.frames === window), @@ -4167,25 +4199,29 @@ nsWindowSH::GetProperty(nsIXPConnectWrap // properties on a window, we won't do a security check if we're // accessing a child frame. - if (JSVAL_IS_STRING(id) && !JSVAL_IS_PRIMITIVE(*vp) && - ::JS_TypeOfValue(cx, *vp) != JSTYPE_FUNCTION) { - // A named property accessed which could have been resolved to a - // child frame in nsWindowSH::NewResolve() (*vp will tell us if - // that's the case). If *vp is a window object (i.e. a child - // frame), return without doing a security check. - - nsCOMPtr vpwrapper; - sXPConnect->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(*vp), - getter_AddRefs(vpwrapper)); - - if (vpwrapper) { - nsCOMPtr window(do_QueryWrappedNative(vpwrapper)); - - if (window) { - // Yup, *vp is a window object, return early (*vp is already - // the window, so no need to wrap it again). + if (JSVAL_IS_STRING(id) && !JSVAL_IS_PRIMITIVE(*vp)) { + ::JS_BeginRequest(cx); + JSBool notfun = ::JS_TypeOfValue(cx, *vp) != JSTYPE_FUNCTION; + ::JS_EndRequest(cx); + if (notfun) { + // A named property accessed which could have been resolved to a + // child frame in nsWindowSH::NewResolve() (*vp will tell us if + // that's the case). If *vp is a window object (i.e. a child + // frame), return without doing a security check. + + nsCOMPtr vpwrapper; + sXPConnect->GetWrappedNativeOfJSObject(cx, JSVAL_TO_OBJECT(*vp), + getter_AddRefs(vpwrapper)); + + if (vpwrapper) { + nsCOMPtr window(do_QueryWrappedNative(vpwrapper)); + + if (window) { + // Yup, *vp is a window object, return early (*vp is already + // the window, so no need to wrap it again). - return NS_SUCCESS_I_DID_SOMETHING; + return NS_SUCCESS_I_DID_SOMETHING; + } } } } @@ -4277,7 +4313,9 @@ nsWindowSH::SetProperty(nsIXPConnectWrap } if (id == sLocation_id) { + ::JS_BeginRequest(cx); JSString *val = ::JS_ValueToString(cx, *vp); + ::JS_EndRequest(cx); NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED); nsCOMPtr window(do_QueryWrappedNative(wrapper)); @@ -5748,9 +5799,9 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp JSBool did_resolve = JS_FALSE; PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty; sDoSecurityCheckInAddProperty = PR_FALSE; - + ::JS_BeginRequest(my_cx); JSBool ok = ::JS_ResolveStandardClass(my_cx, obj, id, &did_resolve); - + ::JS_EndRequest(my_cx); sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty; if (!ok) { @@ -5758,7 +5809,10 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp // the exception in the JS engine. jsval exn; - if (!JS_GetPendingException(my_cx, &exn)) { + ::JS_BeginRequest(my_cx); + ok = JS_GetPendingException(my_cx, &exn); + ::JS_EndRequest(my_cx); + if (!ok) { return NS_ERROR_UNEXPECTED; } @@ -5767,8 +5821,10 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp // Note that the order of the JS_ClearPendingException and // JS_SetPendingException is important in the case that my_cx == cx. + ::JS_BeginRequest(my_cx); JS_ClearPendingException(my_cx); JS_SetPendingException(cx, exn); + ::JS_EndRequest(my_cx); *_retval = JS_FALSE; return NS_OK; } @@ -5852,9 +5908,11 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty; sDoSecurityCheckInAddProperty = PR_FALSE; + ::JS_BeginRequest(cx); PRBool ok = ::JS_DefineUCProperty(cx, obj, chars, ::JS_GetStringLength(str), v, nsnull, nsnull, 0); + ::JS_EndRequest(cx); sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty; @@ -5878,7 +5936,9 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp // which have been registered with the script namespace manager. JSBool did_resolve = JS_FALSE; + ::JS_BeginRequest(cx); rv = GlobalResolve(win, cx, obj, str, flags, &did_resolve); + ::JS_EndRequest(cx); NS_ENSURE_SUCCESS(rv, rv); if (did_resolve) { @@ -5896,19 +5956,23 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp JSObject *windowObj = win->GetGlobalJSObject(); + ::JS_BeginRequest(cx); JSFunction *fun = ::JS_NewFunction(cx, ContentWindowGetter, 0, 0, windowObj, "_content"); if (!fun) { + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } JSObject *funObj = ::JS_GetFunctionObject(fun); - if (!::JS_DefineUCProperty(cx, windowObj, ::JS_GetStringChars(str), - ::JS_GetStringLength(str), JSVAL_VOID, - (JSPropertyOp)funObj, nsnull, - JSPROP_ENUMERATE | JSPROP_GETTER | - JSPROP_SHARED)) { + JSBool ok = ::JS_DefineUCProperty(cx, windowObj, ::JS_GetStringChars(str), + ::JS_GetStringLength(str), JSVAL_VOID, + (JSPropertyOp)funObj, nsnull, + JSPROP_ENUMERATE | JSPROP_GETTER | + JSPROP_SHARED); + ::JS_EndRequest(cx); + if (!ok) { return NS_ERROR_FAILURE; } @@ -5951,9 +6015,11 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty; sDoSecurityCheckInAddProperty = PR_FALSE; + ::JS_BeginRequest(cx); JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), ::JS_GetStringLength(str), v, nsnull, nsnull, JSPROP_ENUMERATE); + ::JS_EndRequest(cx); sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty; @@ -5975,10 +6041,13 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp // undefined to override the predefined property. This is done // for compatibility with other browsers. - if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), - ::JS_GetStringLength(str), - JSVAL_VOID, nsnull, nsnull, - JSPROP_ENUMERATE)) { + ::JS_BeginRequest(cx); + JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), + ::JS_GetStringLength(str), + JSVAL_VOID, nsnull, nsnull, + JSPROP_ENUMERATE); + ::JS_EndRequest(cx); + if (!ok) { return NS_ERROR_FAILURE; } @@ -5998,9 +6067,12 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); - if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), - ::JS_GetStringLength(str), v, nsnull, - nsnull, JSPROP_ENUMERATE)) { + ::JS_BeginRequest(cx); + JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), + ::JS_GetStringLength(str), v, nsnull, + nsnull, JSPROP_ENUMERATE); + ::JS_EndRequest(cx); + if (!ok) { return NS_ERROR_FAILURE; } @@ -6032,11 +6104,14 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp win = win->GetOuterWindowInternal(); NS_ENSURE_TRUE(win, NS_ERROR_NOT_AVAILABLE); - if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), - ::JS_GetStringLength(str), - OBJECT_TO_JSVAL(win->GetGlobalJSObject()), - nsnull, nsnull, - JSPROP_READONLY | JSPROP_ENUMERATE)) { + ::JS_BeginRequest(cx); + JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), + ::JS_GetStringLength(str), + OBJECT_TO_JSVAL(win->GetGlobalJSObject()), + nsnull, nsnull, + JSPROP_READONLY | JSPROP_ENUMERATE); + ::JS_EndRequest(cx); + if (!ok) { return NS_ERROR_FAILURE; } @@ -6695,7 +6772,10 @@ nsEventReceiverSH::SetProperty(nsIXPConn JSContext *cx, JSObject *obj, jsval id, jsval *vp, PRBool *_retval) { - if ((::JS_TypeOfValue(cx, *vp) != JSTYPE_FUNCTION && !JSVAL_IS_NULL(*vp)) || + ::JS_BeginRequest(cx); + JSBool notfun = ::JS_TypeOfValue(cx, *vp) != JSTYPE_FUNCTION; + ::JS_EndRequest(cx); + if ((notfun && !JSVAL_IS_NULL(*vp)) || !JSVAL_IS_STRING(id) || id == sAddEventListener_id) { return NS_OK; } @@ -6891,6 +6971,7 @@ nsGenericArraySH::Enumerate(nsIXPConnect sCurrentlyEnumerating = PR_TRUE; jsval len_val; + ::JS_BeginRequest(cx); JSBool ok = ::JS_GetProperty(cx, obj, "length", &len_val); if (ok && JSVAL_IS_INT(len_val)) { @@ -6904,6 +6985,7 @@ nsGenericArraySH::Enumerate(nsIXPConnect JSPROP_ENUMERATE | JSPROP_SHARED); } } + ::JS_EndRequest(cx); sCurrentlyEnumerating = PR_FALSE; @@ -7263,9 +7345,11 @@ nsDocumentSH::NewResolve(nsIXPConnectWra sDoSecurityCheckInAddProperty = PR_FALSE; JSString *str = JSVAL_TO_STRING(id); + ::JS_BeginRequest(cx); JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), ::JS_GetStringLength(str), v, nsnull, nsnull, JSPROP_ENUMERATE); + ::JS_EndRequest(cx); sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty; @@ -7358,7 +7442,9 @@ nsDocumentSH::SetProperty(nsIXPConnectWr NS_ENSURE_SUCCESS(rv, rv); if (location) { + ::JS_BeginRequest(cx); JSString *val = ::JS_ValueToString(cx, *vp); + ::JS_EndRequest(cx); NS_ENSURE_TRUE(val, NS_ERROR_UNEXPECTED); rv = location->SetHref(nsDependentJSString(val)); @@ -8012,11 +8098,15 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnec if (!(flags & JSRESOLVE_ASSIGNING)) { // For native wrappers, do not resolve random names on document + ::JS_BeginRequest(cx); if (!ObjectIsNativeWrapper(cx, obj)) { nsCOMPtr result; nsresult rv = ResolveImpl(cx, wrapper, id, getter_AddRefs(result)); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_FAILED(rv)) { + ::JS_EndRequest(cx); + NS_ENSURE_SUCCESS(rv, rv); + } if (result) { JSString *str = JS_ValueToString(cx, id); @@ -8027,6 +8117,7 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnec nsnull, 0); *objp = obj; + ::JS_EndRequest(cx); return ok ? NS_OK : NS_ERROR_FAILURE; } } @@ -8039,77 +8130,84 @@ nsHTMLDocumentSH::NewResolve(nsIXPConnec *objp = obj; + ::JS_EndRequest(cx); return fnc ? NS_OK : NS_ERROR_UNEXPECTED; } - if (id == sAll_id && !sDisableDocumentAllSupport && - !ObjectIsNativeWrapper(cx, obj)) { - nsCOMPtr doc(do_QueryWrappedNative(wrapper)); - - if (doc->GetCompatibilityMode() == eCompatibility_NavQuirks) { - JSObject *helper = - GetDocumentAllHelper(cx, ::JS_GetPrototype(cx, obj)); - - JSObject *proto = ::JS_GetPrototype(cx, helper ? helper : obj); - - // Check if the property all is defined on obj's (or helper's - // if obj doesn't exist) prototype, it it is, don't expose our - // document.all helper. + if (id != sAll_id || + sDisableDocumentAllSupport || + ObjectIsNativeWrapper(cx, obj)) { + ::JS_EndRequest(cx); + return NS_OK; + } + nsCOMPtr doc(do_QueryWrappedNative(wrapper)); - JSBool hasAll = JS_FALSE; - if (proto && !JS_HasProperty(cx, proto, "all", &hasAll)) { - return NS_ERROR_UNEXPECTED; - } + if (doc->GetCompatibilityMode() == eCompatibility_NavQuirks) { + JSObject *helper = + GetDocumentAllHelper(cx, ::JS_GetPrototype(cx, obj)); - if (hasAll && helper) { - // Our helper's prototype now has an "all" property, remove - // the helper out of the prototype chain to prevent - // shadowing of the now defined "all" property. - JSObject *tmp = obj, *tmpProto; + JSObject *proto = ::JS_GetPrototype(cx, helper ? helper : obj); - while ((tmpProto = ::JS_GetPrototype(cx, tmp)) != helper) { - tmp = tmpProto; - } + // Check if the property all is defined on obj's (or helper's + // if obj doesn't exist) prototype, it it is, don't expose our + // document.all helper. - ::JS_SetPrototype(cx, tmp, proto); - } + JSBool hasAll = JS_FALSE; + if (proto && !JS_HasProperty(cx, proto, "all", &hasAll)) { + ::JS_EndRequest(cx); + return NS_ERROR_UNEXPECTED; + } - // If we don't already have a helper, and we're resolving - // document.all qualified, and we're *not* detecting - // document.all, e.g. if (document.all), and "all" isn't - // already defined on our prototype, create a helper. - if (!helper && flags & JSRESOLVE_QUALIFIED && - !(flags & JSRESOLVE_DETECTING) && !hasAll) { - helper = JS_NewObject(cx, &sHTMLDocumentAllHelperClass, - ::JS_GetPrototype(cx, obj), - GetGlobalJSObject(cx, obj)); + if (hasAll && helper) { + // Our helper's prototype now has an "all" property, remove + // the helper out of the prototype chain to prevent + // shadowing of the now defined "all" property. + JSObject *tmp = obj, *tmpProto; - if (!helper) { - return NS_ERROR_OUT_OF_MEMORY; - } + while ((tmpProto = ::JS_GetPrototype(cx, tmp)) != helper) { + tmp = tmpProto; + } - // Insert the helper into our prototype chain. helper's prototype - // is already obj's current prototype. - if (!::JS_SetPrototype(cx, obj, helper)) { - nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_UNEXPECTED); + ::JS_SetPrototype(cx, tmp, proto); + } - return NS_ERROR_UNEXPECTED; - } + // If we don't already have a helper, and we're resolving + // document.all qualified, and we're *not* detecting + // document.all, e.g. if (document.all), and "all" isn't + // already defined on our prototype, create a helper. + if (!helper && flags & JSRESOLVE_QUALIFIED && + !(flags & JSRESOLVE_DETECTING) && !hasAll) { + helper = JS_NewObject(cx, &sHTMLDocumentAllHelperClass, + ::JS_GetPrototype(cx, obj), + GetGlobalJSObject(cx, obj)); + + if (!helper) { + ::JS_EndRequest(cx); + return NS_ERROR_OUT_OF_MEMORY; } - // If we have (or just created) a helper, pass the resolve flags - // to the helper as its private data. - if (helper && - !::JS_SetPrivate(cx, helper, - JSVAL_TO_PRIVATE(INT_TO_JSVAL(flags)))) { + // Insert the helper into our prototype chain. helper's prototype + // is already obj's current prototype. + if (!::JS_SetPrototype(cx, obj, helper)) { nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_UNEXPECTED); + ::JS_EndRequest(cx); return NS_ERROR_UNEXPECTED; } } - return NS_OK; + // If we have (or just created) a helper, pass the resolve flags + // to the helper as its private data. + if (helper && + !::JS_SetPrivate(cx, helper, + JSVAL_TO_PRIVATE(INT_TO_JSVAL(flags)))) { + nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_UNEXPECTED); + ::JS_EndRequest(cx); + + return NS_ERROR_UNEXPECTED; + } } + ::JS_EndRequest(cx); } return nsDocumentSH::NewResolve(wrapper, cx, obj, id, flags, objp, _retval); @@ -8134,7 +8232,9 @@ nsHTMLDocumentSH::GetProperty(nsIXPConne nsCOMPtr result; + ::JS_BeginRequest(cx); rv = ResolveImpl(cx, wrapper, id, getter_AddRefs(result)); + ::JS_EndRequest(cx); NS_ENSURE_SUCCESS(rv, rv); if (result) { @@ -8189,9 +8289,11 @@ nsHTMLElementSH::NewResolve(nsIXPConnect { if (id == sScrollIntoView_id && !(JSRESOLVE_ASSIGNING & flags)) { JSString *str = JSVAL_TO_STRING(id); + ::JS_BeginRequest(cx); JSFunction *cfnc = ::JS_DefineFunction(cx, obj, ::JS_GetStringBytes(str), ScrollIntoView, 0, 0); + ::JS_EndRequest(cx); *objp = obj; @@ -8348,9 +8450,11 @@ nsHTMLFormElementSH::NewResolve(nsIXPCon FindNamedItem(form, str, getter_AddRefs(result)); if (result) { + ::JS_BeginRequest(cx); *_retval = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), ::JS_GetStringLength(str), JSVAL_VOID, nsnull, nsnull, 0); + ::JS_EndRequest(cx); *objp = obj; @@ -8459,14 +8563,16 @@ nsHTMLFormElementSH::NewEnumerate(nsIXPC // If name is not there, use index instead attr.AppendInt(index); } + ::JS_BeginRequest(cx); JSString *jsname = JS_NewUCStringCopyN(cx, NS_REINTERPRET_CAST(const jschar *, attr.get()), attr.Length()); + if (jsname) + JS_ValueToId(cx, STRING_TO_JSVAL(jsname), idp); + ::JS_EndRequest(cx); NS_ENSURE_TRUE(jsname, NS_ERROR_OUT_OF_MEMORY); - JS_ValueToId(cx, STRING_TO_JSVAL(jsname), idp); - *statep = INT_TO_JSVAL(++index); } else { *statep = JSVAL_NULL; @@ -8523,9 +8629,12 @@ nsHTMLSelectElementSH::SetOption(JSConte nsIDOMNSHTMLOptionCollection *aOptCollection) { // vp must refer to an object - if (!JSVAL_IS_OBJECT(*vp) && !::JS_ConvertValue(cx, *vp, JSTYPE_OBJECT, - vp)) { - return NS_ERROR_UNEXPECTED; + if (!JSVAL_IS_OBJECT(*vp)) { + ::JS_BeginRequest(cx); + JSBool ok = ::JS_ConvertValue(cx, *vp, JSTYPE_OBJECT, vp); + ::JS_EndRequest(cx); + if (!ok) + return NS_ERROR_UNEXPECTED; } nsCOMPtr new_option; @@ -8605,15 +8714,18 @@ IsObjInProtoChain(JSContext *cx, JSObjec { JSObject *o = obj; + ::JS_BeginRequest(cx); while (o) { JSObject *p = ::JS_GetPrototype(cx, o); if (p == proto) { + ::JS_EndRequest(cx); return PR_TRUE; } o = p; } + ::JS_EndRequest(cx); return PR_FALSE; } @@ -8674,7 +8786,9 @@ nsHTMLExternalObjSH::PostCreate(nsIXPCon NS_ENSURE_SUCCESS(rv, rv); // Set 'this.__proto__' to pi + ::JS_BeginRequest(cx); if (!::JS_SetPrototype(cx, obj, pi_obj)) { + ::JS_EndRequest(cx); return NS_ERROR_UNEXPECTED; } @@ -8682,6 +8796,7 @@ nsHTMLExternalObjSH::PostCreate(nsIXPCon // The plugin wrapper has a proto that's not Object.prototype, set // 'pi.__proto__.__proto__' to the original 'this.__proto__' if (!::JS_SetPrototype(cx, pi_proto, my_proto)) { + ::JS_EndRequest(cx); return NS_ERROR_UNEXPECTED; } } else { @@ -8689,9 +8804,11 @@ nsHTMLExternalObjSH::PostCreate(nsIXPCon // (i.e. pi is an LiveConnect wrapped Java applet), set // 'pi.__proto__' to the original 'this.__proto__' if (!::JS_SetPrototype(cx, pi_obj, my_proto)) { + ::JS_EndRequest(cx); return NS_ERROR_UNEXPECTED; } } + ::JS_EndRequest(cx); // Before this proto dance the objects involved looked like this: // @@ -8751,6 +8868,7 @@ nsHTMLExternalObjSH::GetProperty(nsIXPCo JSContext *cx, JSObject *obj, jsval id, jsval *vp, PRBool *_retval) { + ::JS_BeginRequest(cx); JSObject *pi_obj = ::JS_GetPrototype(cx, obj); const jschar *id_chars = nsnull; @@ -8771,6 +8889,7 @@ nsHTMLExternalObjSH::GetProperty(nsIXPCo } if (!*_retval) { + ::JS_EndRequest(cx); return NS_ERROR_UNEXPECTED; } } @@ -8782,8 +8901,10 @@ nsHTMLExternalObjSH::GetProperty(nsIXPCo *_retval = ::JS_GetElement(cx, pi_obj, JSVAL_TO_INT(id), vp); } + ::JS_EndRequest(cx); return *_retval ? NS_SUCCESS_I_DID_SOMETHING : NS_ERROR_FAILURE; } + ::JS_EndRequest(cx); return NS_OK; } @@ -8793,6 +8914,7 @@ nsHTMLExternalObjSH::SetProperty(nsIXPCo JSContext *cx, JSObject *obj, jsval id, jsval *vp, PRBool *_retval) { + ::JS_BeginRequest(cx); JSObject *pi_obj = ::JS_GetPrototype(cx, obj); const jschar *id_chars = nsnull; @@ -8813,6 +8935,7 @@ nsHTMLExternalObjSH::SetProperty(nsIXPCo } if (!*_retval) { + ::JS_EndRequest(cx); return NS_ERROR_UNEXPECTED; } } @@ -8824,8 +8947,10 @@ nsHTMLExternalObjSH::SetProperty(nsIXPCo *_retval = ::JS_SetElement(cx, pi_obj, JSVAL_TO_INT(id), vp); } + ::JS_EndRequest(cx); return *_retval ? NS_SUCCESS_I_DID_SOMETHING : NS_ERROR_FAILURE; } + ::JS_EndRequest(cx); return nsElementSH::SetProperty(wrapper, cx, obj, id, vp, _retval); } @@ -8858,8 +8983,10 @@ nsHTMLExternalObjSH::Call(nsIXPConnectWr // XPConnect passes us the XPConnect wrapper JSObject as obj, and // not the 'this' parameter that the JS engine passes in. Pass in // the real this parameter from JS (argv[-1]) here. + ::JS_BeginRequest(cx); *_retval = ::JS_CallFunctionValue(cx, JSVAL_TO_OBJECT(argv[-1]), OBJECT_TO_JSVAL(pi_obj), argc, argv, vp); + ::JS_EndRequest(cx); return NS_OK; } @@ -9132,9 +9259,11 @@ nsHTMLOptionsCollectionSH::NewResolve(ns { if (id == sAdd_id) { JSString *str = JSVAL_TO_STRING(id); + ::JS_BeginRequest(cx); JSFunction *fnc = ::JS_DefineFunction(cx, obj, ::JS_GetStringBytes(str), Add, 0, JSPROP_ENUMERATE); + ::JS_EndRequest(cx); *objp = obj; @@ -9344,9 +9473,11 @@ nsStringArraySH::GetProperty(nsIXPConnec // XXX: Null strings? + ::JS_BeginRequest(cx); JSString *str = ::JS_NewUCStringCopyN(cx, NS_REINTERPRET_CAST(const jschar *, val.get()), val.Length()); + ::JS_EndRequest(cx); NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY); *vp = STRING_TO_JSVAL(str); Index: dom/src/base/nsGlobalWindow.cpp =================================================================== RCS file: /cvsroot/mozilla/dom/src/base/nsGlobalWindow.cpp,v retrieving revision 1.812 diff -up -r1.812 dom/src/base/nsGlobalWindow.cpp --- dom/src/base/nsGlobalWindow.cpp +++ dom/src/base/nsGlobalWindow.cpp @@ -163,6 +163,8 @@ // belonging to the back-end like nsIContentPolicy #include "nsIPopupWindowManager.h" +#include "jsobj.h" + #ifdef MOZ_LOGGING // so we can get logging even in release builds #define FORCE_PR_LOG 1 @@ -495,8 +498,10 @@ nsGlobalWindow::FreeInnerObjects(JSConte mDoc = nsnull; if (mJSObject && cx) { + ::JS_BeginRequest(cx); ::JS_ClearScope(cx, mJSObject); ::JS_ClearWatchPointsForObject(cx, mJSObject); + ::JS_EndRequest(cx); nsWindowSH::InvalidateGlobalScopePolluter(cx, mJSObject); } @@ -824,7 +829,9 @@ WindowStateHolder::~WindowStateHolder() return; } + ::JS_BeginRequest(cx); mInnerWindow->FreeInnerObjects(cx); + ::JS_EndRequest(cx); if (mLocation) { // Don't leave the weak reference to the docshell lying around. @@ -1031,12 +1043,14 @@ nsGlobalWindow::SetNewDocument(nsIDocume // initialize the new inner window. If we don't, things // (Object.prototype etc) could leak from the old outer to the new // inner scope. + ::JS_BeginRequest(cx); ::JS_ClearScope(cx, mJSObject); ::JS_ClearWatchPointsForObject(cx, mJSObject); // Clear the regexp statics for the new page unconditionally. // XXX They don't get restored on the inner window when we go back. ::JS_ClearRegExpStatics(cx); + ::JS_EndRequest(cx); if (reUseInnerWindow) { // We're reusing the current inner window. @@ -1139,9 +1153,11 @@ nsGlobalWindow::SetNewDocument(nsIDocume // calling scope. NS_ASSERTION(!currentInner->IsFrozen(), "How does this opened window get into session history"); + ::JS_BeginRequest(cx); callerScx->SetTerminationFunction(ClearWindowScope, NS_STATIC_CAST(nsIDOMWindow *, currentInner)); + ::JS_EndRequest(cx); termFuncSet = PR_TRUE; } @@ -1151,8 +1167,10 @@ nsGlobalWindow::SetNewDocument(nsIDocume // held in the bfcache. if (!currentInner->IsFrozen()) { if (!termFuncSet) { + ::JS_BeginRequest(cx); ::JS_ClearScope(cx, currentInner->mJSObject); ::JS_ClearWatchPointsForObject(cx, currentInner->mJSObject); + ::JS_EndRequest(cx); } // Make the current inner window release its strong references @@ -1167,6 +1185,7 @@ nsGlobalWindow::SetNewDocument(nsIDocume mInnerWindow = newInnerWindow; } + ::JS_BeginRequest(cx); if (!aState && !reUseInnerWindow) { // Loading a new page and creating a new inner window, *not* // restoring from session history. @@ -1212,6 +1231,7 @@ nsGlobalWindow::SetNewDocument(nsIDocume ::JS_SetPrototype(cx, newInnerWindow->mJSObject, proto); ::JS_SetPrototype(cx, proto, innerProtoProto); } + ::JS_EndRequest(cx); // Now that the prototype is all set up, install the global scope // polluter. This must happen after the above prototype fixup. If @@ -1274,7 +1294,9 @@ nsGlobalWindow::SetNewDocument(nsIDocume // case we don't clear the inner window's scope, but we must // make sure the cached document property gets updated. + ::JS_BeginRequest(cx); ::JS_DeleteProperty(cx, currentInner->mJSObject, "document"); + ::JS_EndRequest(cx); } else { rv = newInnerWindow->SetNewDocument(aDocument, nsnull, aClearScopeHint, PR_TRUE); @@ -1289,19 +1311,23 @@ nsGlobalWindow::SetNewDocument(nsIDocume JSObject *nav; navigatorHolder->GetJSObject(&nav); + ::JS_BeginRequest(cx); ::JS_DefineProperty(cx, newInnerWindow->mJSObject, "navigator", OBJECT_TO_JSVAL(nav), nsnull, nsnull, JSPROP_ENUMERATE); + ::JS_EndRequest(cx); } } if (mArguments) { jsval args = OBJECT_TO_JSVAL(mArguments); + ::JS_BeginRequest(cx); ::JS_SetProperty(cx, newInnerWindow->mJSObject, "arguments", &args); ::JS_UnlockGCThing(cx, mArguments); + ::JS_EndRequest(cx); mArguments = nsnull; } @@ -1344,6 +1370,7 @@ nsGlobalWindow::SetDocShell(nsIDocShell* nsGlobalWindow *currentInner = GetCurrentInnerWindowInternal(); if (currentInner) { + ::JS_BeginRequest(cx); currentInner->FreeInnerObjects(cx); NS_ASSERTION(mDoc, "Must have doc!"); @@ -1366,6 +1393,7 @@ nsGlobalWindow::SetDocShell(nsIDocShell* } ::JS_ClearRegExpStatics(cx); + ::JS_EndRequest(cx); } // if we are closing the window while in full screen mode, be sure @@ -1714,12 +1749,14 @@ nsGlobalWindow::SetNewArguments(PRUint32 (cx = (JSContext *)mContext->GetNativeContext()), NS_ERROR_NOT_INITIALIZED); + JS_BeginRequest(cx); if (mArguments) { ::JS_UnlockGCThing(cx, mArguments); mArguments = nsnull; } if (aArgc == 0) { + JS_EndRequest(cx); return NS_OK; } @@ -1735,7 +1772,10 @@ nsGlobalWindow::SetNewArguments(PRUint32 JSObject *argArray = ::JS_NewArrayObject(cx, aArgc, argv); Thaw(); - NS_ENSURE_TRUE(argArray, NS_ERROR_OUT_OF_MEMORY); + if (!argArray) { + JS_EndRequest(cx); + return NS_ERROR_OUT_OF_MEMORY; + } // Note that currentInner may be non-null if someone's doing a // window.open with an existing window name. @@ -1746,6 +1786,7 @@ nsGlobalWindow::SetNewArguments(PRUint32 // The object newborn keeps argArray alive across this set. if (currentInner && currentInner->mJSObject) { if (!::JS_SetProperty(cx, currentInner->mJSObject, "arguments", &args)) { + JS_EndRequest(cx); return NS_ERROR_FAILURE; } } @@ -1754,6 +1795,7 @@ nsGlobalWindow::SetNewArguments(PRUint32 // document is loaded. mArguments = argArray; ::JS_LockGCThing(cx, mArguments); + JS_EndRequest(cx); return NS_OK; } @@ -3394,19 +3436,21 @@ nsGlobalWindow::Prompt(nsAString& aRetur PRUint32 savePassword = nsIAuthPrompt::SAVE_PASSWORD_NEVER; if (argc > 0) { - nsJSUtils::ConvertJSValToString(message, cx, argv[0]); - - if (argc > 1) { + ::JS_BeginRequest(cx); + switch (argc) { + default: + case 4: + nsJSUtils::ConvertJSValToUint32(&savePassword, cx, argv[3]); + case 3: + nsJSUtils::ConvertJSValToString(title, cx, argv[2]); + case 2: nsJSUtils::ConvertJSValToString(initial, cx, argv[1]); - - if (argc > 2) { - nsJSUtils::ConvertJSValToString(title, cx, argv[2]); - - if (argc > 3) { - nsJSUtils::ConvertJSValToUint32(&savePassword, cx, argv[3]); - } - } + case 1: + nsJSUtils::ConvertJSValToString(message, cx, argv[0]); + case 0: + break; } + ::JS_EndRequest(cx); } return Prompt(message, initial, title, savePassword, aReturn); @@ -4262,21 +4312,19 @@ nsGlobalWindow::Open(nsIDOMWindow **_ret ncc->GetArgvPtr(&argv); if (argc > 0) { - nsJSUtils::ConvertJSValToString(url, cx, argv[0]); - - if (argc > 1) { + ::JS_BeginRequest(cx); + switch (argc) { + default: + case 3: + nsJSUtils::ConvertJSValToString(options, cx, argv[2]); + case 2: nsJSUtils::ConvertJSValToString(name, cx, argv[1]); - - if (argc > 2) { - nsJSUtils::ConvertJSValToString(options, cx, argv[2]); - } + case 1: + nsJSUtils::ConvertJSValToString(url, cx, argv[0]); + case 0: + break; } + ::JS_EndRequest(cx); } PopupControlState abuseLevel = CheckForAbusePoint(); @@ -4360,15 +4413,19 @@ nsGlobalWindow::OpenDialog(nsIDOMWindow* ncc->GetArgvPtr(&argv); if (argc > 0) { - nsJSUtils::ConvertJSValToString(url, cx, argv[0]); - - if (argc > 1) { + ::JS_BeginRequest(cx); + switch (argc) { + default: + case 3: + nsJSUtils::ConvertJSValToString(options, cx, argv[2]); + case 2: nsJSUtils::ConvertJSValToString(name, cx, argv[1]); - - if (argc > 2) { - nsJSUtils::ConvertJSValToString(options, cx, argv[2]); - } + case 1: + nsJSUtils::ConvertJSValToString(url, cx, argv[0]); + case 0: + break; } + ::JS_EndRequest(cx); } return OpenInternal(url, name, options, PR_TRUE, argv, argc, nsnull, @@ -4836,37 +4893,45 @@ nsGlobalWindow::Find(PRBool *aDidFind) if (argc > 0) { // First arg is the search pattern - nsJSUtils::ConvertJSValToString(searchStr, cx, argv[0]); - } - - if (argc > 1 && !JS_ValueToBoolean(cx, argv[1], &caseSensitive)) { - // Second arg is the case sensitivity - caseSensitive = PR_FALSE; - } - - if (argc > 2 && !JS_ValueToBoolean(cx, argv[2], &backwards)) { - // Third arg specifies whether to search backwards - backwards = PR_FALSE; - } - - if (argc > 3 && !JS_ValueToBoolean(cx, argv[3], &wrapAround)) { - // Fourth arg specifies whether we should wrap the search - wrapAround = PR_FALSE; - } - - if (argc > 4 && !JS_ValueToBoolean(cx, argv[4], &wholeWord)) { - // Fifth arg specifies whether we should show the Find dialog - wholeWord = PR_FALSE; - } - - if (argc > 5 && !JS_ValueToBoolean(cx, argv[5], &searchInFrames)) { - // Sixth arg specifies whether we should search only for whole words - searchInFrames = PR_FALSE; - } - - if (argc > 6 && !JS_ValueToBoolean(cx, argv[6], &showDialog)) { - // Seventh arg specifies whether we should search in all frames - showDialog = PR_FALSE; + ::JS_BeginRequest(cx); + switch (argc) { + default: + case 7: + if (!JS_ValueToBoolean(cx, argv[6], &showDialog)) { + // Seventh arg specifies whether we should search in all frames + showDialog = PR_FALSE; + } + case 6: + if (!JS_ValueToBoolean(cx, argv[5], &searchInFrames)) { + // Sixth arg specifies whether we should search only for whole words + searchInFrames = PR_FALSE; + } + case 5: + if (!JS_ValueToBoolean(cx, argv[4], &wholeWord)) { + // Fifth arg specifies whether we should show the Find dialog + wholeWord = PR_FALSE; + } + case 4: + if (!JS_ValueToBoolean(cx, argv[3], &wrapAround)) { + // Fourth arg specifies whether we should wrap the search + wrapAround = PR_FALSE; + } + case 3: + if (!JS_ValueToBoolean(cx, argv[2], &backwards)) { + // Third arg specifies whether to search backwards + backwards = PR_FALSE; + } + case 2: + if (!JS_ValueToBoolean(cx, argv[1], &caseSensitive)) { + // Second arg is the case sensitivity + caseSensitive = PR_FALSE; + } + case 1: + nsJSUtils::ConvertJSValToString(searchStr, cx, argv[0]); + case 0: + break; + } + ::JS_EndRequest(cx); } return FindInternal(searchStr, caseSensitive, backwards, wrapAround, @@ -5379,18 +5478,22 @@ nsGlobalWindow::GetObjectProperty(const jsval propertyVal; + nsresult rv = NS_OK; + ::JS_BeginRequest(cx); if (!::JS_LookupUCProperty(cx, mJSObject, NS_REINTERPRET_CAST(const jschar *, aProperty), nsCRT::strlen(aProperty), &propertyVal)) { - return NS_ERROR_FAILURE; + rv = NS_ERROR_FAILURE; } - if (!nsJSUtils::ConvertJSValToXPCObject(aObject, NS_GET_IID(nsISupports), + if (NS_SUCCEEDED(rv) && + !nsJSUtils::ConvertJSValToXPCObject(aObject, NS_GET_IID(nsISupports), cx, propertyVal)) { - return NS_ERROR_FAILURE; + rv = NS_ERROR_FAILURE; } + ::JS_EndRequest(cx); - return NS_OK; + return rv; } static nsresult @@ -5888,12 +5991,14 @@ nsGlobalWindow::ClearWindowScope(nsISupp JSContext *cx = (JSContext *)scx->GetNativeContext(); JSObject *global = sgo->GetGlobalJSObject(); + ::JS_BeginRequest(cx); if (global) { ::JS_ClearScope(cx, global); ::JS_ClearWatchPointsForObject(cx, global); } ::JS_ClearRegExpStatics(cx); + ::JS_EndRequest(cx); } } @@ -5943,18 +6048,20 @@ nsGlobalWindow::SetTimeoutOrInterval(PRB nsTimeout *timeout; jsdouble interval = 0.0; + ::JS_BeginRequest(cx); + JSBool thrown = JS_TRUE; if (argc < 1) { ::JS_ReportError(cx, "Function %s requires at least 1 parameter", aIsInterval ? kSetIntervalStr : kSetTimeoutStr); - - return ncc->SetExceptionWasThrown(PR_TRUE); - } - - if (argc > 1 && !::JS_ValueToNumber(cx, argv[1], &interval)) { + } else if (argc > 1 && !::JS_ValueToNumber(cx, argv[1], &interval)) { ::JS_ReportError(cx, "Second argument to %s must be a millisecond interval", aIsInterval ? kSetIntervalStr : kSetTimeoutStr); - + } else { + thrown = JS_FALSE; + } + if (thrown) { + ::JS_EndRequest(cx); return ncc->SetExceptionWasThrown(PR_TRUE); } @@ -5966,14 +6073,17 @@ nsGlobalWindow::SetTimeoutOrInterval(PRB case JSTYPE_STRING: case JSTYPE_OBJECT: expr = ::JS_ValueToString(cx, argv[0]); - if (!expr) + if (!expr) { + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; + } argv[0] = STRING_TO_JSVAL(expr); break; default: ::JS_ReportError(cx, "useless %s call (missing quotes around argument?)", aIsInterval ? kSetIntervalStr : kSetTimeoutStr); + ::JS_EndRequest(cx); return ncc->SetExceptionWasThrown(PR_TRUE); } @@ -5986,8 +6096,10 @@ nsGlobalWindow::SetTimeoutOrInterval(PRB } timeout = new nsTimeout(); - if (!timeout) + if (!timeout) { + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; + } // Increment the timeout's reference count to represent this function's hold // on the timeout. @@ -6000,6 +6112,7 @@ nsGlobalWindow::SetTimeoutOrInterval(PRB if (expr) { if (!::JS_AddNamedRoot(cx, &timeout->mExpr, "timeout.mExpr")) { timeout->Release(scx); + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } @@ -6012,12 +6125,14 @@ nsGlobalWindow::SetTimeoutOrInterval(PRB if (!timeout->mArgv) { timeout->Release(scx); + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } if (!::JS_AddNamedRoot(cx, &timeout->mFunObj, "timeout.mFunObj")) { timeout->Release(scx); + ::JS_EndRequest(cx); return NS_ERROR_FAILURE; } @@ -6030,6 +6145,7 @@ nsGlobalWindow::SetTimeoutOrInterval(PRB if (!::JS_AddNamedRoot(cx, &timeout->mArgv[i - 2], "timeout.mArgv[i]")) { timeout->Release(scx); + ::JS_EndRequest(cx); return NS_ERROR_FAILURE; } @@ -6044,12 +6160,14 @@ nsGlobalWindow::SetTimeoutOrInterval(PRB if (!timeout->mFileName) { timeout->Release(scx); + ::JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; } } timeout->mVersion = ::JS_VersionToString(::JS_GetVersion(cx)); + ::JS_EndRequest(cx); // Get principal of currently executing code, save for execution of timeout @@ -6532,7 +6650,14 @@ nsGlobalWindow::ClearTimeoutOrInterval() int32 timer_id; - if (argv[0] == JSVAL_VOID || !::JS_ValueToInt32(cx, argv[0], &timer_id) || + // Undefined or non-positive number passed as argument, return + // early. + if (argv[0] == JSVAL_VOID) + return NS_OK; + ::JS_BeginRequest(cx); + JSBool ok = ::JS_ValueToInt32(cx, argv[0], &timer_id); + ::JS_EndRequest(cx); + if (!ok || timer_id <= 0) { // Undefined or non-positive number passed as argument, return // early. Make sure that JS_ValueToInt32 didn't set an exception. @@ -7708,15 +7842,17 @@ nsNavigator::Preference() //--Check to see if the caller is allowed to access prefs if (sPrefInternal_id == JSVAL_VOID) { + ::JS_BeginRequest(cx); sPrefInternal_id = STRING_TO_JSVAL(::JS_InternString(cx, "preferenceinternal")); + ::JS_EndRequest(cx); } PRUint32 action; if (argc == 1) { - action = nsIXPCSecurityManager::ACCESS_GET_PROPERTY; + action = nsIXPCSecurityManager::ACCESS_GET_PROPERTY; } else { - action = nsIXPCSecurityManager::ACCESS_SET_PROPERTY; + action = nsIXPCSecurityManager::ACCESS_SET_PROPERTY; } nsCOMPtr secMan = @@ -7732,7 +7868,9 @@ nsNavigator::Preference() nsIPrefBranch *prefBranch = nsContentUtils::GetPrefBranch(); NS_ENSURE_STATE(prefBranch); + ::JS_BeginRequest(cx); JSString *str = ::JS_ValueToString(cx, argv[0]); + ::JS_EndRequest(cx); NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY); jsval *retval = nsnull; @@ -7753,7 +7891,9 @@ nsNavigator::Preference() rv = prefBranch->GetCharPref(prefStr, getter_Copies(prefCharVal)); NS_ENSURE_SUCCESS(rv, rv); + ::JS_BeginRequest(cx); JSString *retStr = ::JS_NewStringCopyZ(cx, prefCharVal); + ::JS_EndRequest(cx); NS_ENSURE_TRUE(retStr, NS_ERROR_OUT_OF_MEMORY); *retval = STRING_TO_JSVAL(retStr); @@ -7794,7 +7934,9 @@ nsNavigator::Preference() ncc->SetReturnValueWasSet(PR_TRUE); } else { if (JSVAL_IS_STRING(argv[1])) { + ::JS_BeginRequest(cx); JSString *valueJSStr = ::JS_ValueToString(cx, argv[1]); + ::JS_EndRequest(cx); NS_ENSURE_TRUE(valueJSStr, NS_ERROR_OUT_OF_MEMORY); rv = prefBranch->SetCharPref(prefStr, ::JS_GetStringBytes(valueJSStr)); Index: dom/src/base/nsJSEnvironment.cpp =================================================================== RCS file: /cvsroot/mozilla/dom/src/base/nsJSEnvironment.cpp,v retrieving revision 1.275 diff -up -r1.275 dom/src/base/nsJSEnvironment.cpp --- dom/src/base/nsJSEnvironment.cpp +++ dom/src/base/nsJSEnvironment.cpp @@ -880,6 +880,7 @@ nsJSContext::EvaluateStringWithValue(con if (aVersion) oldVersion = ::JS_SetVersion(mContext, newVersion); + ::JS_BeginRequest(mContext); ok = ::JS_EvaluateUCScriptForPrincipals(mContext, (JSObject *)aScopeObject, jsprin, @@ -889,6 +890,7 @@ nsJSContext::EvaluateStringWithValue(con aLineNo, &val); + ::JS_EndRequest(mContext); if (aVersion) { ::JS_SetVersion(mContext, oldVersion); } @@ -1062,6 +1064,7 @@ nsJSContext::EvaluateString(const nsAStr if (ok) { JSVersion oldVersion = JSVERSION_UNKNOWN; + ::JS_BeginRequest(mContext); if (aVersion) oldVersion = ::JS_SetVersion(mContext, newVersion); ok = ::JS_EvaluateUCScriptForPrincipals(mContext, @@ -1076,6 +1079,7 @@ nsJSContext::EvaluateString(const nsAStr if (aVersion) { ::JS_SetVersion(mContext, oldVersion); } + ::JS_EndRequest(mContext); if (!ok) { // Tell XPConnect about any pending exceptions. This is needed @@ -1092,7 +1096,9 @@ nsJSContext::EvaluateString(const nsAStr // If all went well, convert val to a string (XXXbe unless undefined?). if (ok) { + ::JS_BeginRequest(mContext); rv = JSValueToAString(mContext, val, aRetValue, aIsUndefined); + ::JS_EndRequest(mContext); } else { if (aIsUndefined) { @@ -1154,6 +1160,7 @@ nsJSContext::CompileScript(const PRUnich if (!aVersion || (newVersion = ::JS_StringToVersion(aVersion)) != JSVERSION_UNKNOWN) { JSVersion oldVersion = JSVERSION_UNKNOWN; + ::JS_BeginRequest(mContext); if (aVersion) oldVersion = ::JS_SetVersion(mContext, newVersion); @@ -1177,6 +1184,7 @@ nsJSContext::CompileScript(const PRUnich if (aVersion) ::JS_SetVersion(mContext, oldVersion); + ::JS_EndRequest(mContext); } } @@ -1226,6 +1234,7 @@ nsJSContext::ExecuteScript(void* aScript JSBool ok; nsJSContext::TerminationFuncHolder holder(this); + ::JS_BeginRequest(mContext); ok = ::JS_ExecuteScript(mContext, (JSObject*) aScopeObject, (JSScript*) ::JS_GetPrivate(mContext, @@ -1236,7 +1245,9 @@ nsJSContext::ExecuteScript(void* aScript // If all went well, convert val to a string (XXXbe unless undefined?). rv = JSValueToAString(mContext, val, aRetValue, aIsUndefined); - } else { + } + ::JS_EndRequest(mContext); + if (!ok) { if (aIsUndefined) { *aIsUndefined = PR_TRUE; } @@ -1323,6 +1334,7 @@ nsJSContext::CompileEventHandler(void *a const char *argList[] = { aEventName }; + ::JS_BeginRequest(mContext); JSFunction* fun = ::JS_CompileUCFunctionForPrincipals(mContext, aShared ? nsnull : target, jsprin, @@ -1334,14 +1346,14 @@ nsJSContext::CompileEventHandler(void *a if (jsprin) { JSPRINCIPALS_DROP(mContext, jsprin); } - if (!fun) { - return NS_ERROR_FAILURE; - } - JSObject *handler = ::JS_GetFunctionObject(fun); - if (aHandler) - *aHandler = (void*) handler; - return NS_OK; + if (fun) { + JSObject *handler = ::JS_GetFunctionObject(fun); + if (aHandler) + *aHandler = (void*) handler; + } + ::JS_EndRequest(mContext); + return fun ? NS_OK : NS_ERROR_FAILURE; } nsresult @@ -1372,6 +1384,7 @@ nsJSContext::CompileFunction(void* aTarg } JSObject *target = (JSObject*)aTarget; + ::JS_BeginRequest(mContext); JSFunction* fun = ::JS_CompileUCFunctionForPrincipals(mContext, aShared ? nsnull : target, jsprin, @@ -1380,6 +1393,7 @@ nsJSContext::CompileFunction(void* aTarg (jschar*)PromiseFlatString(aBody).get(), aBody.Length(), aURL, aLineNo); + ::JS_EndRequest(mContext); if (jsprin) JSPRINCIPALS_DROP(mContext, jsprin); @@ -1420,8 +1434,10 @@ nsJSContext::CallEventHandler(JSObject * if (NS_SUCCEEDED(rv)) { jsval funval = OBJECT_TO_JSVAL(aHandler); + ::JS_BeginRequest(mContext); PRBool ok = ::JS_CallFunctionValue(mContext, aTarget, funval, argc, argv, rval); + ::JS_EndRequest(mContext); if (!ok) { // Tell XPConnect about any pending exceptions. This is needed @@ -1444,7 +1460,9 @@ nsJSContext::CallEventHandler(JSObject * // Need to lock, since ScriptEvaluated can GC. PRBool locked = PR_FALSE; if (NS_SUCCEEDED(rv) && JSVAL_IS_GCTHING(*rval)) { + ::JS_BeginRequest(mContext); locked = ::JS_LockGCThing(mContext, JSVAL_TO_GCTHING(*rval)); + ::JS_EndRequest(mContext); if (!locked) { rv = NS_ERROR_OUT_OF_MEMORY; } @@ -1454,7 +1472,9 @@ nsJSContext::CallEventHandler(JSObject * ScriptEvaluated(PR_TRUE); if (locked) { + ::JS_BeginRequest(mContext); ::JS_UnlockGCThing(mContext, JSVAL_TO_GCTHING(*rval)); + ::JS_EndRequest(mContext); } return rv; @@ -1482,6 +1502,7 @@ nsJSContext::BindCompiledEventHandler(vo } // Make sure the handler function is parented by its event target object + ::JS_BeginRequest(mContext); if (funobj && ::JS_GetParent(mContext, funobj) != target) { funobj = ::JS_CloneFunctionObject(mContext, funobj, target); if (!funobj) @@ -1498,6 +1519,7 @@ nsJSContext::BindCompiledEventHandler(vo if (NS_FAILED(stack->Pop(nsnull)) && NS_SUCCEEDED(rv)) { rv = NS_ERROR_FAILURE; } + ::JS_EndRequest(mContext); return rv; } @@ -1621,7 +1650,9 @@ nsJSContext::InitContext(nsIScriptGlobal // Now check whether we need to grab a pointer to the // XPCNativeWrapper class if (!NS_DOMClassInfo_GetXPCNativeWrapperClass()) { + ::JS_BeginRequest(mContext); rv = FindXPCNativeWrapperClass(holder); + ::JS_EndRequest(mContext); NS_ENSURE_SUCCESS(rv, rv); } } else { @@ -1689,7 +1720,9 @@ nsJSContext::InitializeLiveConnectClasse do_QueryInterface(jvmManager); if (liveConnectManager) { + ::JS_BeginRequest(mContext); rv = liveConnectManager->InitLiveConnectClasses(mContext, aGlobalObj); + ::JS_EndRequest(mContext); } } } @@ -1828,13 +1861,13 @@ TraceMallocOpenLogFile(JSContext *cx, JS if (argc == 0) { fd = -1; } else { - str = JS_ValueToString(cx, argv[0]); + str = ::JS_ValueToString(cx, argv[0]); if (!str) return JS_FALSE; - filename = JS_GetStringBytes(str); + filename = ::JS_GetStringBytes(str); fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd < 0) { - JS_ReportError(cx, "can't open %s: %s", filename, strerror(errno)); + ::JS_ReportError(cx, "can't open %s: %s", filename, strerror(errno)); return JS_FALSE; } } @@ -1850,11 +1883,11 @@ TraceMallocChangeLogFD(JSContext *cx, JS if (argc == 0) { oldfd = -1; } else { - if (!JS_ValueToECMAInt32(cx, argv[0], &fd)) + if (!::JS_ValueToECMAInt32(cx, argv[0], &fd)) return JS_FALSE; oldfd = NS_TraceMallocChangeLogFD(fd); if (oldfd == -2) { - JS_ReportOutOfMemory(cx); + ::JS_ReportOutOfMemory(cx); return JS_FALSE; } } @@ -1869,7 +1902,7 @@ TraceMallocCloseLogFD(JSContext *cx, JSO if (argc == 0) return JS_TRUE; - if (!JS_ValueToECMAInt32(cx, argv[0], &fd)) + if (!::JS_ValueToECMAInt32(cx, argv[0], &fd)) return JS_FALSE; NS_TraceMallocCloseLogFD((int) fd); return JS_TRUE; @@ -1881,10 +1914,10 @@ TraceMallocLogTimestamp(JSContext *cx, J JSString *str; const char *caption; - str = JS_ValueToString(cx, argv[0]); + str = ::JS_ValueToString(cx, argv[0]); if (!str) return JS_FALSE; - caption = JS_GetStringBytes(str); + caption = ::JS_GetStringBytes(str); NS_TraceMallocLogTimestamp(caption); return JS_TRUE; } @@ -1895,12 +1928,12 @@ TraceMallocDumpAllocations(JSContext *cx JSString *str; const char *pathname; - str = JS_ValueToString(cx, argv[0]); + str = ::JS_ValueToString(cx, argv[0]); if (!str) return JS_FALSE; - pathname = JS_GetStringBytes(str); + pathname = ::JS_GetStringBytes(str); if (NS_TraceMallocDumpAllocations(pathname) < 0) { - JS_ReportError(cx, "can't dump to %s: %s", pathname, strerror(errno)); + ::JS_ReportError(cx, "can't dump to %s: %s", pathname, strerror(errno)); return JS_FALSE; } return JS_TRUE; @@ -1992,6 +2025,7 @@ nsJSContext::InitClasses(JSObject *aGlob rv = InitializeLiveConnectClasses(aGlobalObj); NS_ENSURE_SUCCESS(rv, rv); + ::JS_BeginRequest(mContext); // Initialize the options object and set default options in mContext JSObject *optionsObj = ::JS_DefineObject(mContext, aGlobalObj, "_options", &OptionsClass, nsnull, 0); @@ -2011,6 +2045,7 @@ nsJSContext::InitClasses(JSObject *aGlob // Attempt to initialize JProf functions ::JS_DefineFunctions(mContext, aGlobalObj, JProfFunctions); #endif + ::JS_EndRequest(mContext); return rv; } Index: dom/src/base/nsLocation.cpp =================================================================== RCS file: /cvsroot/mozilla/dom/src/base/nsLocation.cpp,v retrieving revision 1.138 diff -up -r1.138 dom/src/base/nsLocation.cpp --- dom/src/base/nsLocation.cpp +++ dom/src/base/nsLocation.cpp @@ -897,7 +905,9 @@ nsLocation::Reload() rv = ncc->GetJSContext(&cx); NS_ENSURE_SUCCESS(rv, rv); + JS_BeginRequest(cx); JS_ValueToBoolean(cx, argv[0], &force_get); + JS_EndRequest(cx); } return Reload(force_get); Index: dom/src/base/nsPluginArray.cpp =================================================================== RCS file: /cvsroot/mozilla/dom/src/base/nsPluginArray.cpp,v retrieving revision 1.29 diff -up -r1.29 dom/src/base/nsPluginArray.cpp --- dom/src/base/nsPluginArray.cpp +++ dom/src/base/nsPluginArray.cpp @@ -253,7 +262,9 @@ nsPluginArray::Refresh() rv = ncc->GetJSContext(&cx); NS_ENSURE_SUCCESS(rv, rv); + JS_BeginRequest(cx); JS_ValueToBoolean(cx, argv[0], &reload_doc); + JS_EndRequest(cx); } return Refresh(reload_doc); Index: dom/src/events/nsJSEventListener.cpp =================================================================== RCS file: /cvsroot/mozilla/dom/src/events/nsJSEventListener.cpp,v retrieving revision 1.51 diff -up -r1.51 dom/src/events/nsJSEventListener.cpp --- dom/src/events/nsJSEventListener.cpp +++ dom/src/events/nsJSEventListener.cpp @@ -60,7 +74,9 @@ nsJSEventListener::nsJSEventListener(nsI if (aScopeObject && aContext) { JSContext *cx = (JSContext *)aContext->GetNativeContext(); + ::JS_BeginRequest(cx); ::JS_LockGCThing(cx, aScopeObject); + ::JS_EndRequest(cx); } } @@ -69,7 +85,9 @@ nsJSEventListener::~nsJSEventListener() if (mScopeObject && mContext) { JSContext *cx = (JSContext *)mContext->GetNativeContext(); + ::JS_BeginRequest(cx); ::JS_UnlockGCThing(cx, mScopeObject); + ::JS_EndRequest(cx); } } @@ -97,6 +115,7 @@ nsJSEventListener::HandleEvent(nsIDOMEve jsval funval; jsval arg; jsval *argv = &arg; + jsval rval; PRInt32 argc = 0; void *stackPtr; // For JS_[Push|Pop]Arguments() nsAutoString eventString; @@ -138,56 +157,77 @@ nsJSEventListener::HandleEvent(nsIDOMEve rv = wrapper->GetJSObject(&obj); NS_ENSURE_SUCCESS(rv, rv); - if (!JS_LookupUCProperty(cx, obj, - NS_REINTERPRET_CAST(const jschar *, - eventString.get()), - eventString.Length(), &funval)) { - return NS_ERROR_FAILURE; - } - - if (JS_TypeOfValue(cx, funval) != JSTYPE_FUNCTION) { - return NS_OK; - } + JS_BeginRequest(cx); + do { + if (!JS_LookupUCProperty(cx, obj, + NS_REINTERPRET_CAST(const jschar *, + eventString.get()), + eventString.Length(), &funval)) { + rv = NS_ERROR_FAILURE; + break; + } - PRBool handledScriptError = PR_FALSE; - if (eventString.EqualsLiteral("onerror")) { - nsCOMPtr priv(do_QueryInterface(aEvent)); - NS_ENSURE_TRUE(priv, NS_ERROR_UNEXPECTED); - - nsEvent* event; - priv->GetInternalNSEvent(&event); - if (event->message == NS_SCRIPT_ERROR) { - nsScriptErrorEvent *scriptEvent = - NS_STATIC_CAST(nsScriptErrorEvent*, event); - - argv = ::JS_PushArguments(cx, &stackPtr, "WWi", scriptEvent->errorMsg, - scriptEvent->fileName, scriptEvent->lineNr); - NS_ENSURE_TRUE(argv, NS_ERROR_OUT_OF_MEMORY); - argc = 3; - handledScriptError = PR_TRUE; + if (JS_TypeOfValue(cx, funval) != JSTYPE_FUNCTION) { + rv = NS_OK; + break; } - } - if (!handledScriptError) { - rv = xpc->WrapNative(cx, obj, aEvent, NS_GET_IID(nsIDOMEvent), - getter_AddRefs(wrapper)); - NS_ENSURE_SUCCESS(rv, rv); - - JSObject *eventObj = nsnull; - rv = wrapper->GetJSObject(&eventObj); - NS_ENSURE_SUCCESS(rv, rv); + PRBool handledScriptError = PR_FALSE; + if (eventString.EqualsLiteral("onerror")) { + nsCOMPtr priv(do_QueryInterface(aEvent)); + NS_ASSERTION(priv, "not expected"); + if (!priv) { + rv = NS_ERROR_UNEXPECTED; + break; + } - argv[0] = OBJECT_TO_JSVAL(eventObj); - argc = 1; - } + nsEvent* event; + priv->GetInternalNSEvent(&event); + if (event->message == NS_SCRIPT_ERROR) { + nsScriptErrorEvent *scriptEvent = + NS_STATIC_CAST(nsScriptErrorEvent*, event); + + argv = ::JS_PushArguments(cx, &stackPtr, "WWi", scriptEvent->errorMsg, + scriptEvent->fileName, scriptEvent->lineNr); + NS_ASSERTION(argv, "out of memory"); + if (!argv) { + rv = NS_ERROR_OUT_OF_MEMORY; + argv = &arg; + break; + } + argc = 3; + handledScriptError = PR_TRUE; + } + } - jsval rval; - rv = mContext->CallEventHandler(obj, JSVAL_TO_OBJECT(funval), argc, argv, - &rval); + if (!handledScriptError) { + rv = xpc->WrapNative(cx, obj, aEvent, NS_GET_IID(nsIDOMEvent), + getter_AddRefs(wrapper)); + NS_ASSERTION(NS_SUCCEEDED(rv), "..."); + if (NS_FAILED(rv)) + break; + + JSObject *eventObj = nsnull; + rv = wrapper->GetJSObject(&eventObj); + NS_ASSERTION(NS_SUCCEEDED(rv), "..."); + if (NS_FAILED(rv)) + break; + argv[0] = OBJECT_TO_JSVAL(eventObj); + argc = 1; + } + + JSObject* funobj = JSVAL_TO_OBJECT(funval); + jsrefcount suspendCount = JS_SuspendRequest(cx); + rv = mContext->CallEventHandler(obj, funobj, argc, argv, + &rval); + + JS_ResumeRequest(cx, suspendCount); + } while (0); if (argv != &arg) { ::JS_PopArguments(cx, stackPtr); } + JS_EndRequest(cx); if (NS_SUCCEEDED(rv)) { if (eventString.EqualsLiteral("onbeforeunload")) { Index: embedding/components/windowwatcher/src/nsWindowWatcher.cpp =================================================================== RCS file: /cvsroot/mozilla/embedding/components/windowwatcher/src/nsWindowWatcher.cpp,v retrieving revision 1.108 diff -up -r1.108 embedding/components/windowwatcher/src/nsWindowWatcher.cpp --- embedding/components/windowwatcher/src/nsWindowWatcher.cpp +++ embedding/components/windowwatcher/src/nsWindowWatcher.cpp @@ -1861,8 +1861,9 @@ nsWindowWatcher::AddSupportsTojsvals(nsI p->GetData(data); - + ::JS_BeginRequest(cx); JSString *str = ::JS_NewStringCopyN(cx, data.get(), data.Length()); + ::JS_EndRequest(cx); NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY); *aArgv = STRING_TO_JSVAL(str); @@ -1879,10 +1880,12 @@ nsWindowWatcher::AddSupportsTojsvals(nsI // cast is probably safe since wchar_t and jschar are expected // to be equivalent; both unsigned 16-bit entities + ::JS_BeginRequest(cx); JSString *str = ::JS_NewUCStringCopyN(cx, NS_REINTERPRET_CAST(const jschar *,data.get()), data.Length()); + ::JS_EndRequest(cx); NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY); *aArgv = STRING_TO_JSVAL(str); @@ -1944,7 +1947,9 @@ nsWindowWatcher::AddSupportsTojsvals(nsI p->GetData(&data); + ::JS_BeginRequest(cx); JSString *str = ::JS_NewStringCopyN(cx, &data, 1); + ::JS_EndRequest(cx); NS_ENSURE_TRUE(str, NS_ERROR_OUT_OF_MEMORY); *aArgv = STRING_TO_JSVAL(str); @@ -1983,7 +1988,9 @@ nsWindowWatcher::AddSupportsTojsvals(nsI p->GetData(&data); + ::JS_BeginRequest(cx); jsdouble *d = ::JS_NewDouble(cx, data); + ::JS_EndRequest(cx); *aArgv = DOUBLE_TO_JSVAL(d); @@ -1997,7 +2004,9 @@ nsWindowWatcher::AddSupportsTojsvals(nsI p->GetData(&data); + ::JS_BeginRequest(cx); jsdouble *d = ::JS_NewDouble(cx, data); + ::JS_EndRequest(cx); *aArgv = DOUBLE_TO_JSVAL(d); Index: extensions/xmlextras/base/src/nsXMLHttpRequest.cpp =================================================================== RCS file: /cvsroot/mozilla/extensions/xmlextras/base/src/nsXMLHttpRequest.cpp,v retrieving revision 1.143 diff -up -r1.143 extensions/xmlextras/base/src/nsXMLHttpRequest.cpp --- extensions/xmlextras/base/src/nsXMLHttpRequest.cpp +++ extensions/xmlextras/base/src/nsXMLHttpRequest.cpp @@ -1041,21 +1041,12 @@ nsXMLHttpRequest::Open(const nsACString& } if (argc > 2) { - JSBool asyncBool; - ::JS_ValueToBoolean(cx, argv[2], &asyncBool); - async = (PRBool)asyncBool; - - if (argc > 3) { - JSString* userStr = ::JS_ValueToString(cx, argv[3]); - - if (userStr) { - user.Assign(NS_REINTERPRET_CAST(PRUnichar *, - ::JS_GetStringChars(userStr)), - ::JS_GetStringLength(userStr)); - } - - if (argc > 4) { - JSString* passwdStr = JS_ValueToString(cx, argv[4]); + ::JS_BeginRequest(cx); + switch (argc) { + default: + case 5: + { + JSString* passwdStr = ::JS_ValueToString(cx, argv[4]); if (passwdStr) { password.Assign(NS_REINTERPRET_CAST(PRUnichar *, @@ -1063,7 +1054,28 @@ nsXMLHttpRequest::Open(const nsACString& ::JS_GetStringLength(passwdStr)); } } + case 4: + { + JSString* userStr = ::JS_ValueToString(cx, argv[3]); + + if (userStr) { + user.Assign(NS_REINTERPRET_CAST(PRUnichar *, + ::JS_GetStringChars(userStr)), + ::JS_GetStringLength(userStr)); + } + } + case 3: + { + JSBool asyncBool; + ::JS_ValueToBoolean(cx, argv[2], &asyncBool); + async = (PRBool)asyncBool; + } + case 2: + case 1: + case 0: + break; } + ::JS_EndRequest(cx); } } Index: js/jsd/jsd_high.c =================================================================== RCS file: /cvsroot/mozilla/js/jsd/jsd_high.c,v retrieving revision 3.12 diff -up -r3.12 js/jsd/jsd_high.c --- js/jsd/jsd_high.c +++ js/jsd/jsd_high.c @@ -135,12 +155,15 @@ _newJSDContext(JSRuntime* jsrt, if( ! jsdc->dumbContext ) goto label_newJSDContext_failure; + JS_BeginRequest(jsdc->dumbContext); + /* do we have to JS_EndRequest if we discard the context (label_newJSDContext_failure) */ jsdc->glob = JS_NewObject(jsdc->dumbContext, &global_class, NULL, NULL); if( ! jsdc->glob ) goto label_newJSDContext_failure; if( ! JS_InitStandardClasses(jsdc->dumbContext, jsdc->glob) ) goto label_newJSDContext_failure; + JS_EndRequest(jsdc->dumbContext); jsdc->data = NULL; jsdc->inited = JS_TRUE; Index: js/jsd/jsd_stak.c =================================================================== RCS file: /cvsroot/mozilla/js/jsd/jsd_stak.c,v retrieving revision 3.21 diff -up -r3.21 js/jsd/jsd_stak.c --- js/jsd/jsd_stak.c +++ js/jsd/jsd_stak.c @@ -316,7 +318,9 @@ jsd_GetScopeChainForStackFrame(JSDContex if( jsd_IsValidFrameInThreadState(jsdc, jsdthreadstate, jsdframe) ) { + JS_BeginRequest(jsdthreadstate->context); obj = JS_GetFrameScopeChain(jsdthreadstate->context, jsdframe->fp); + JS_EndRequest(jsdthreadstate->context); if(obj) jsdval = JSD_NewValue(jsdc, OBJECT_TO_JSVAL(obj)); } Index: js/jsd/jsd_val.c =================================================================== RCS file: /cvsroot/mozilla/js/jsd/jsd_val.c,v retrieving revision 3.9 diff -up -r3.9 js/jsd/jsd_val.c --- js/jsd/jsd_val.c +++ js/jsd/jsd_val.c @@ -155,15 +157,16 @@ jsd_IsValueNative(JSDContext* jsdc, JSDV if(JSVAL_IS_FUNCTION(cx, val)) { + JSBool ok = JS_FALSE; + JS_BeginRequest(cx); exceptionState = JS_SaveExceptionState(cx); fun = JS_ValueToFunction(cx, val); JS_RestoreExceptionState(cx, exceptionState); - if(!fun) - { - JS_ASSERT(0); - return JS_FALSE; - } - return JS_GetFunctionScript(cx, fun) ? JS_FALSE : JS_TRUE; + if (fun) + ok = !JS_GetFunctionScript(cx, fun); + JS_EndRequest(cx); + JS_ASSERT(fun); + return ok; } return JSVAL_TO_OBJECT(val) && OBJ_IS_NATIVE(JSVAL_TO_OBJECT(val)); } @@ -205,6 +208,7 @@ jsd_GetValueString(JSDContext* jsdc, JSD jsdval->string = JSVAL_TO_STRING(jsdval->val); else { + JS_BeginRequest(cx); exceptionState = JS_SaveExceptionState(cx); jsdval->string = JS_ValueToString(cx, jsdval->val); JS_RestoreExceptionState(cx, exceptionState); @@ -218,6 +229,7 @@ jsd_GetValueString(JSDContext* jsdc, JSD if(!JS_AddNamedRoot(cx, &jsdval->string, "ValueString")) jsdval->string = NULL; } + JS_EndRequest(cx); } } return jsdval->string; @@ -233,9 +245,11 @@ jsd_GetValueFunctionName(JSDContext* jsd if(!jsdval->funName && JSVAL_IS_FUNCTION(cx, val)) { + JS_BeginRequest(cx); exceptionState = JS_SaveExceptionState(cx); fun = JS_ValueToFunction(cx, val); JS_RestoreExceptionState(cx, exceptionState); + JS_EndRequest(cx); if(!fun) return NULL; jsdval->funName = JS_GetFunctionName(fun); @@ -255,7 +269,11 @@ jsd_NewValue(JSDContext* jsdc, jsval val if(JSVAL_IS_GCTHING(val)) { - if(!JS_AddNamedRoot(jsdc->dumbContext, &jsdval->val, "JSDValue")) + JSBool ok; + JS_BeginRequest(jsdc->dumbContext); + ok = JS_AddNamedRoot(jsdc->dumbContext, &jsdval->val, "JSDValue"); + JS_EndRequest(jsdc->dumbContext); + if(!ok) { free(jsdval); return NULL; @@ -275,8 +293,11 @@ jsd_DropValue(JSDContext* jsdc, JSDValue if(0 == --jsdval->nref) { jsd_RefreshValue(jsdc, jsdval); - if(JSVAL_IS_GCTHING(jsdval->val)) + if(JSVAL_IS_GCTHING(jsdval->val)) { + JS_BeginRequest(jsdc->dumbContext); JS_RemoveRoot(jsdc->dumbContext, &jsdval->val); + JS_EndRequest(jsdc->dumbContext); + } free(jsdval); } } @@ -343,8 +364,11 @@ static JSBool _buildProps(JSDContext* js if(!JSVAL_IS_OBJECT(jsdval->val) || JSVAL_IS_NULL(jsdval->val)) return JS_FALSE; - if(!JS_GetPropertyDescArray(cx, JSVAL_TO_OBJECT(jsdval->val), &pda)) + JS_BeginRequest(cx); + if(!JS_GetPropertyDescArray(cx, JSVAL_TO_OBJECT(jsdval->val), &pda)) { + JS_EndRequest(cx); return JS_FALSE; + } for(i = 0; i < pda.length; i++) { @@ -357,6 +381,7 @@ static JSBool _buildProps(JSDContext* js JS_APPEND_LINK(&prop->links, &jsdval->props); } JS_PutPropertyDescArray(cx, &pda); + JS_EndRequest(cx); SET_BIT_FLAG(jsdval->flags, GOT_PROPS); return !JS_CLIST_IS_EMPTY(&jsdval->props); } @@ -371,9 +396,15 @@ jsd_RefreshValue(JSDContext* jsdc, JSDVa if(jsdval->string) { +#ifndef USE_SCARY_NOT_ROOTING /* if the jsval is a string, then we didn't need to root the string */ if(!JSVAL_IS_STRING(jsdval->val)) +#endif + { + JS_BeginRequest(cx); JS_RemoveRoot(cx, &jsdval->string); + JS_EndRequest(cx); + } jsdval->string = NULL; } @@ -462,9 +493,12 @@ jsd_GetValueProperty(JSDContext* jsdc, J nameChars = JS_GetStringChars(name); nameLen = JS_GetStringLength(name); + JS_BeginRequest(cx); JS_GetUCPropertyAttributes(cx, obj, nameChars, nameLen, &attrs, &found); - if (!found) + if (!found) { + JS_EndRequest(cx); return NULL; + } JS_ClearPendingException(cx); @@ -472,8 +506,10 @@ jsd_GetValueProperty(JSDContext* jsdc, J { if (JS_IsExceptionPending(cx)) { - if (!JS_GetPendingException(cx, &pd.value)) + if (!JS_GetPendingException(cx, &pd.value)) { + JS_EndRequest(cx); return NULL; + } pd.flags = JSPD_EXCEPTION; } else @@ -486,6 +522,7 @@ jsd_GetValueProperty(JSDContext* jsdc, J { pd.value = val; } + JS_EndRequest(cx); pd.id = STRING_TO_JSVAL(name); pd.alias = pd.slot = pd.spare = 0; @@ -510,7 +547,10 @@ jsd_GetValuePrototype(JSDContext* jsdc, return NULL; if(!(obj = JSVAL_TO_OBJECT(jsdval->val))) return NULL; - if(!(proto = OBJ_GET_PROTO(jsdc->dumbContext,obj))) + JS_BeginRequest(jsdc->dumbContext); + proto = OBJ_GET_PROTO(jsdc->dumbContext,obj); + JS_EndRequest(jsdc->dumbContext); + if(!proto) return NULL; jsdval->proto = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(proto)); } @@ -532,7 +572,10 @@ jsd_GetValueParent(JSDContext* jsdc, JSD return NULL; if(!(obj = JSVAL_TO_OBJECT(jsdval->val))) return NULL; - if(!(parent = OBJ_GET_PARENT(jsdc->dumbContext,obj))) + JS_BeginRequest(jsdc->dumbContext); + parent = OBJ_GET_PARENT(jsdc->dumbContext,obj); + JS_EndRequest(jsdc->dumbContext); + if(!parent) return NULL; jsdval->parent = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(parent)); } @@ -548,16 +591,19 @@ jsd_GetValueConstructor(JSDContext* jsdc { JSObject* obj; JSObject* proto; - JSObject* ctor; + JSObject* ctor = NULL; JS_ASSERT(!jsdval->ctor); SET_BIT_FLAG(jsdval->flags, GOT_CTOR); if(!JSVAL_IS_OBJECT(jsdval->val)) return NULL; if(!(obj = JSVAL_TO_OBJECT(jsdval->val))) return NULL; - if(!(proto = OBJ_GET_PROTO(jsdc->dumbContext,obj))) - return NULL; - if(!(ctor = JS_GetConstructor(jsdc->dumbContext,proto))) + JS_BeginRequest(jsdc->dumbContext); + proto = OBJ_GET_PROTO(jsdc->dumbContext,obj); + if(proto) + ctor = JS_GetConstructor(jsdc->dumbContext,proto); + JS_EndRequest(jsdc->dumbContext); + if(!ctor) return NULL; jsdval->ctor = jsd_NewValue(jsdc, OBJECT_TO_JSVAL(ctor)); } @@ -575,8 +621,10 @@ jsd_GetValueClassName(JSDContext* jsdc, JSObject* obj; if(!(obj = JSVAL_TO_OBJECT(val))) return NULL; + JS_BeginRequest(jsdc->dumbContext); if(OBJ_GET_CLASS(jsdc->dumbContext, obj)) jsdval->className = OBJ_GET_CLASS(jsdc->dumbContext, obj)->name; + JS_EndRequest(jsdc->dumbContext); } return jsdval->className; } Index: js/jsd/jsd_xpc.cpp =================================================================== RCS file: /cvsroot/mozilla/js/jsd/jsd_xpc.cpp,v retrieving revision 1.72 diff -up -r1.72 js/jsd/jsd_xpc.cpp --- js/jsd/jsd_xpc.cpp +++ js/jsd/jsd_xpc.cpp @@ -1015,55 +1026,65 @@ jsdScript::~jsdScript () */ PCMapEntry * jsdScript::CreatePPLineMap() -{ +{ JSContext *cx = JSD_GetDefaultJSContext (mCx); + JS_BeginRequest(cx); JSObject *obj = JS_NewObject(cx, NULL, NULL, NULL); JSFunction *fun = JSD_GetJSFunction (mCx, mScript); JSScript *script; PRUint32 baseLine; PRBool scriptOwner = PR_FALSE; - + if (fun) { if (fun->nargs > 12) return nsnull; JSString *jsstr = JS_DecompileFunctionBody (cx, fun, 4); - if (!jsstr) + if (!jsstr) { + JS_EndRequest(cx); return nsnull; - - const char *argnames[] = {"arg1", "arg2", "arg3", "arg4", + } + + const char *argnames[] = {"arg1", "arg2", "arg3", "arg4", "arg5", "arg6", "arg7", "arg8", "arg9", "arg10", "arg11", "arg12" }; fun = JS_CompileUCFunction (cx, obj, "ppfun", fun->nargs, argnames, JS_GetStringChars(jsstr), JS_GetStringLength(jsstr), "x-jsd:ppbuffer?type=function", 3); - if (!fun || !(script = JS_GetFunctionScript(cx, fun))) + if (!fun || !(script = JS_GetFunctionScript(cx, fun))) { + JS_EndRequest(cx); return nsnull; + } + baseLine = 3; } else { JSString *jsstr = JS_DecompileScript (cx, JSD_GetJSScript(mCx, mScript), "ppscript", 4); - if (!jsstr) + if (!jsstr) { + JS_EndRequest(cx); return nsnull; + } script = JS_CompileUCScript (cx, obj, JS_GetStringChars(jsstr), JS_GetStringLength(jsstr), "x-jsd:ppbuffer?type=script", 1); - if (!script) + if (!script) { + JS_EndRequest(cx); return nsnull; + } scriptOwner = PR_TRUE; baseLine = 1; } PRUint32 scriptExtent = JS_GetScriptLineExtent (cx, script); jsbytecode* firstPC = JS_LineNumberToPC (cx, script, 0); /* allocate worst case size of map (number of lines in script + 1 * for our 0 record), we'll shrink it with a realloc later. */ - mPPLineMap = + mPPLineMap = NS_STATIC_CAST(PCMapEntry *, PR_Malloc((scriptExtent + 1) * sizeof (PCMapEntry))); - if (mPPLineMap) { + if (mPPLineMap) { mPCMapSize = 0; for (PRUint32 line = baseLine; line < scriptExtent + baseLine; ++line) { jsbytecode* pc = JS_LineNumberToPC (cx, script, line); @@ -1083,6 +1104,7 @@ jsdScript::CreatePPLineMap() if (scriptOwner) JS_DestroyScript (cx, script); + JS_EndRequest(cx); return mPPLineMap; } @@ -1263,6 +1287,7 @@ jsdScript::GetFunctionSource(nsAString & } JSFunction *fun = JSD_GetJSFunction (mCx, mScript); JSString *jsstr; + JS_BeginRequest(cx); if (fun) { jsstr = JS_DecompileFunction (cx, fun, 4); @@ -1272,6 +1297,7 @@ jsdScript::GetFunctionSource(nsAString & JSScript *script = JSD_GetJSScript (mCx, mScript); jsstr = JS_DecompileScript (cx, script, "ppscript", 4); } + JS_EndRequest(cx); if (!jsstr) return NS_ERROR_FAILURE; aFunctionSource = NS_REINTERPRET_CAST(PRUnichar*, JS_GetStringChars(jsstr)); @@ -1911,6 +1967,7 @@ jsdStackFrame::Eval (const nsAString &by jsval jv; JSContext *cx = JSD_GetJSContext (mCx, mThreadState); + JS_BeginRequest(cx); estate = JS_SaveExceptionState (cx); JS_ClearPendingException (cx); @@ -1926,6 +1983,7 @@ jsdStackFrame::Eval (const nsAString &by } JS_RestoreExceptionState (cx, estate); + JS_EndRequest(cx); JSDValue *jsdv = JSD_NewValue (mCx, jv); if (!jsdv) return NS_ERROR_FAILURE; @@ -2215,27 +2273,37 @@ jsdValue::GetProperties (jsdIProperty ** pa_temp[i] = jsdProperty::FromPtr (mCx, prop); ++i; } - - NS_ASSERTION (prop_count == i, "property count mismatch"); + + NS_ASSERTION (prop_count == i, "property count mismatch"); /* if caller doesn't care about length, don't bother telling them */ *propArray = pa_temp; if (length) *length = prop_count; - + return NS_OK; } NS_IMETHODIMP -jsdValue::GetProperty (const char *name, jsdIProperty **_rval) +jsdValue::GetProperty (const nsAString &aName, jsdIProperty **_rval) { ASSERT_VALID_EPHEMERAL; JSContext *cx = JSD_GetDefaultJSContext (mCx); + const nsString& name = PromiseFlatString(aName); /* not rooting this */ - JSString *jstr_name = JS_NewStringCopyZ (cx, name); + /* XXX timeless: ok, so it isn't being rooted, what prevents TOO_MUCH_GC from killing it? + * it looks like this string only needs to last until JSD_GetValueProperty + * finishes. isn't there some way to do this using shareable strings? + * XXX JS_NewExternalString ? + */ + JS_BeginRequest(cx); + JSString *jstr_name = JS_NewUCStringCopyN (cx, name.get(), name.Length()); + JS_EndRequest(cx); + if (!jstr_name) + return NS_ERROR_OUT_OF_MEMORY; JSDProperty *prop = JSD_GetValueProperty (mCx, mValue, jstr_name); - + *_rval = jsdProperty::FromPtr (mCx, prop); return NS_OK; } Index: js/src/js.c =================================================================== RCS file: /cvsroot/mozilla/js/src/js.c,v retrieving revision 3.103 diff -up -r3.103 js/src/js.c --- js/src/js.c +++ js/src/js.c @@ -103,6 +103,16 @@ JSBool gQuitting = JS_FALSE; FILE *gErrFile = NULL; FILE *gOutFile = NULL; +/***************************************************************************/ + +#ifdef JS_THREADSAFE +#define DoBeginRequest(cx) JS_BeginRequest((cx)) +#define DoEndRequest(cx) JS_EndRequest((cx)) +#else +#define DoBeginRequest(cx) ((void)0) +#define DoEndRequest(cx) ((void)0) +#endif + #ifdef JSDEBUGGER static JSDContext *_jsdc; #ifdef JSDEBUGGER_JAVA_UI @@ -218,19 +228,21 @@ Process(JSContext *cx, JSObject *obj, ch } } ungetc(ch, file); + DoBeginRequest(cx); script = JS_CompileFileHandle(cx, obj, filename, file); if (script) { if (!compileOnly) (void)JS_ExecuteScript(cx, obj, script, &result); JS_DestroyScript(cx, script); } - + DoEndRequest(cx); return; } /* It's an interactive filehandle; drop into read-eval-print loop. */ lineno = 1; hitEOF = JS_FALSE; + DoBeginRequest(cx); do { bufp = buffer; *bufp = '\0'; @@ -243,12 +255,14 @@ Process(JSContext *cx, JSObject *obj, ch */ startline = lineno; do { + DoEndRequest(cx); if (!GetLine(cx, bufp, file, startline == lineno ? "js> " : "")) { hitEOF = JS_TRUE; break; } bufp += strlen(bufp); lineno++; + DoBeginRequest(cx); } while (!JS_BufferIsCompilableUnit(cx, obj, buffer, strlen(buffer))); /* Clear any pending exception from previous failed compiles. */ @@ -259,16 +273,22 @@ Process(JSContext *cx, JSObject *obj, ch if (!compileOnly) { ok = JS_ExecuteScript(cx, obj, script, &result); if (ok && result != JSVAL_VOID) { - str = JS_ValueToString(cx, result); - if (str) - fprintf(gOutFile, "%s\n", JS_GetStringBytes(str)); - else - ok = JS_FALSE; + ok = JS_AddNamedRoot(cx, &result, "script result"); + if (ok) { + str = JS_ValueToString(cx, result); + + if (str) + fprintf(gOutFile, "%s\n", JS_GetStringBytes(str)); + else + ok = JS_FALSE; + JS_RemoveRoot(cx, &result); + } } } JS_DestroyScript(cx, script); } } while (!hitEOF && !gQuitting); + DoEndRequest(cx); fprintf(gOutFile, "\n"); return; } @@ -344,12 +364,21 @@ ProcessArgs(JSContext *cx, JSObject *obj * Create arguments early and define it to root it, so it's safe from any * GC calls nested below, and so it is available to -f arguments. */ + DoBeginRequest(cx); argsObj = JS_NewArrayObject(cx, 0, NULL); if (!argsObj) return 1; - if (!JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj), - NULL, NULL, 0)) { + + if (!JS_EnterLocalRootScope(cx)) return 1; + + { + JSBool ok = + JS_DefineProperty(cx, obj, "arguments", OBJECT_TO_JSVAL(argsObj), + NULL, NULL, 0); + JS_LeaveLocalRootScope(cx); + if (!ok) + return 1; } length = argc - i; @@ -362,6 +391,7 @@ ProcessArgs(JSContext *cx, JSObject *obj return 1; } } + DoEndRequest(cx); for (i = 0; i < argc; i++) { if (argv[i][0] != '-' || argv[i][1] == '\0') { @@ -400,7 +430,9 @@ ProcessArgs(JSContext *cx, JSObject *obj if (!JS_SealObject(cx, obj, JS_TRUE)) return JS_FALSE; + DoBeginRequest(cx); gobj = JS_NewObject(cx, &global_class, NULL, NULL); + DoEndRequest(cx); if (!gobj) return JS_FALSE; if (!JS_SetPrototype(cx, gobj, obj)) @@ -2205,12 +2241,18 @@ env_setProperty(JSContext *cx, JSObject const char *name, *value; int rv; + if (!JS_EnterLocalRootScope(cx)) + return JS_FALSE; + idstr = JS_ValueToString(cx, id); valstr = JS_ValueToString(cx, *vp); - if (!idstr || !valstr) + if (!idstr || !valstr) { + JS_LeaveLocalRootScope(cx); return JS_FALSE; + } name = JS_GetStringBytes(idstr); value = JS_GetStringBytes(valstr); + JS_LeaveLocalRootScope(cx); #if defined XP_WIN || defined HPUX || defined OSF1 || defined IRIX { char *waste = JS_smprintf("%s=%s", name, value); @@ -2519,6 +2561,7 @@ main(int argc, char **argv, char **envp) return 1; JS_SetErrorReporter(cx, my_ErrorReporter); + DoBeginRequest(cx); glob = JS_NewObject(cx, &global_class, NULL, NULL); if (!glob) return 1; @@ -2606,6 +2649,7 @@ main(int argc, char **argv, char **envp) } } #endif + DoEndRequest(cx); result = ProcessArgs(cx, glob, argv, argc); Index: js/src/xpconnect/loader/mozJSComponentLoader.h =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/loader/mozJSComponentLoader.h,v retrieving revision 1.26 diff -up -r1.26 js/src/xpconnect/loader/mozJSComponentLoader.h --- js/src/xpconnect/loader/mozJSComponentLoader.h +++ js/src/xpconnect/loader/mozJSComponentLoader.h @@ -143,8 +143,10 @@ class mozJSComponentLoader : public nsIM module = nsnull; if (global) { + JS_BeginRequest(sSelf->mContext); JS_ClearScope(sSelf->mContext, global); JS_RemoveRoot(sSelf->mContext, &global); + JS_EndRequest(sSelf->mContext); } if (location) Index: js/src/xpconnect/loader/mozJSSubScriptLoader.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/loader/mozJSSubScriptLoader.cpp,v retrieving revision 1.20 diff -up -r1.20 js/src/xpconnect/loader/mozJSSubScriptLoader.cpp --- js/src/xpconnect/loader/mozJSSubScriptLoader.cpp +++ js/src/xpconnect/loader/mozJSSubScriptLoader.cpp @@ -77,7 +77,8 @@ ExceptionalErrorReporter (JSContext *cx, if (report && JSREPORT_IS_EXCEPTION (report->flags)) /* if it's already an exception, our job is done. */ return; - + + JS_BeginRequest(cx); ex = JS_NewObject (cx, nsnull, nsnull, nsnull); /* create a jsobject to throw */ if (!ex) @@ -114,6 +115,7 @@ ExceptionalErrorReporter (JSContext *cx, } JS_SetPendingException (cx, OBJECT_TO_JSVAL(ex)); + JS_EndRequest(cx); return; @@ -123,6 +125,7 @@ ExceptionalErrorReporter (JSContext *cx, "mozJSSubScriptLoader: Error occurred while reporting error :/\n") #endif ; + JS_EndRequest(cx); } mozJSSubScriptLoader::mozJSSubScriptLoader() : mSystemPrincipal(nsnull) @@ -196,7 +199,9 @@ mozJSSubScriptLoader::LoadSubScript (con char *url; JSObject *target_obj = nsnull; + JS_BeginRequest(cx); ok = JS_ConvertArguments (cx, argc, argv, "s / o", &url, &target_obj); + JS_EndRequest(cx); if (!ok) { cc->SetExceptionWasThrown (JS_TRUE); @@ -273,6 +278,7 @@ mozJSSubScriptLoader::LoadSubScript (con nsCOMPtr instream; nsCOMPtr serv = do_GetService(kIOServiceCID); + JS_BeginRequest(cx); if (!serv) { errmsg = JS_NewStringCopyZ (cx, LOAD_ERROR_NOSERVICE); @@ -302,8 +308,10 @@ mozJSSubScriptLoader::LoadSubScript (con } buf = new char[len + 1]; - if (!buf) + if (!buf) { + JS_EndRequest(cx); return NS_ERROR_OUT_OF_MEMORY; + } buf[len] = '\0'; do { @@ -328,6 +336,7 @@ mozJSSubScriptLoader::LoadSubScript (con rv = mSystemPrincipal->GetJSPrincipals(cx, &jsPrincipals); if (NS_FAILED(rv) || !jsPrincipals) { delete[] buf; + JS_EndRequest(cx); return rv; } @@ -339,6 +348,7 @@ mozJSSubScriptLoader::LoadSubScript (con buf, len, url, 1, rval); /* repent for our evil deeds */ JS_SetErrorReporter (cx, er); + JS_EndRequest(cx); cc->SetExceptionWasThrown (!ok); cc->SetReturnValueWasSet (ok); @@ -352,6 +362,7 @@ mozJSSubScriptLoader::LoadSubScript (con delete[] buf; JS_SetPendingException (cx, STRING_TO_JSVAL(errmsg)); + JS_EndRequest(cx); cc->SetExceptionWasThrown (JS_TRUE); return NS_OK; Index: js/src/xpconnect/src/XPCNativeWrapper.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/XPCNativeWrapper.cpp,v retrieving revision 1.38 diff -up -r1.38 js/src/xpconnect/src/XPCNativeWrapper.cpp --- js/src/xpconnect/src/XPCNativeWrapper.cpp +++ js/src/xpconnect/src/XPCNativeWrapper.cpp @@ -757,7 +757,10 @@ XPC_NW_NewResolve(JSContext *cx, JSObjec ccx.SetResolvingWrapper(oldResolvingWrapper); } - if (!::JS_SetReservedSlot(cx, obj, 0, oldFlags)) { + ::JS_BeginRequest(cx); + JSBool ok = ::JS_SetReservedSlot(cx, obj, 0, oldFlags); + ::JS_EndRequest(cx); + if (!ok) { return JS_FALSE; } @@ -767,7 +770,9 @@ XPC_NW_NewResolve(JSContext *cx, JSObjec if (newObj) { #ifdef DEBUG_XPCNativeWrapper + ::JS_BeginRequest(cx); JSString* strId = ::JS_ValueToString(cx, id); + ::JS_EndRequest(cx); if (strId) { NS_ConvertUTF16toUTF8 propName((PRUnichar*)::JS_GetStringChars(strId), ::JS_GetStringLength(strId)); @@ -862,9 +867,12 @@ XPC_NW_NewResolve(JSContext *cx, JSObjec } } - if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), - ::JS_GetStringLength(str), v, nsnull, nsnull, - attrs)) { + ::JS_BeginRequest(cx); + JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), + ::JS_GetStringLength(str), v, nsnull, nsnull, + attrs); + ::JS_EndRequest(cx); + if (!ok) { return JS_FALSE; } Index: js/src/xpconnect/src/xpcdebug.cpp =================================================================== RCS file: /cvsroot/mozilla/js/src/xpconnect/src/xpcdebug.cpp,v retrieving revision 1.14 diff -up -r1.14 js/src/xpconnect/src/xpcdebug.cpp --- js/src/xpconnect/src/xpcdebug.cpp +++ js/src/xpconnect/src/xpcdebug.cpp @@ -49,7 +49,9 @@ static const char* JSVAL2String(JSContext* cx, jsval val, JSBool* isString) { const char* value = nsnull; + JS_BeginRequest(cx); JSString* value_str = JS_ValueToString(cx, val); + JS_EndRequest(cx); if(value_str) value = JS_GetStringBytes(value_str); if(value) @@ -89,6 +91,7 @@ static char* FormatJSFrame(JSContext* cx JSScript* script = JS_GetFrameScript(cx, fp); jsbytecode* pc = JS_GetFramePC(cx, fp); + JS_BeginRequest(cx); if(script && pc) { filename = JS_GetScriptFilename(cx, script); @@ -257,6 +260,7 @@ static char* FormatJSFrame(JSContext* cx } out: + JS_EndRequest(cx); if(callProps.array) JS_PutPropertyDescArray(cx, &callProps); if(thisProps.array) @@ -337,6 +341,7 @@ xpc_DumpEvalInJSStackFrame(JSContext* cx return JS_FALSE; } + JS_BeginRequest(cx); JSExceptionState* exceptionState = JS_SaveExceptionState(cx); JSErrorReporter older = JS_SetErrorReporter(cx, xpcDumpEvalErrorReporter); @@ -353,6 +358,7 @@ xpc_DumpEvalInJSStackFrame(JSContext* cx puts("eval failed!"); JS_SetErrorReporter(cx, older); JS_RestoreExceptionState(cx, exceptionState); + JS_EndRequest(cx); return JS_TRUE; } Index: modules/plugin/base/src/ns4xPlugin.cpp =================================================================== RCS file: /cvsroot/mozilla/modules/plugin/base/src/ns4xPlugin.cpp,v retrieving revision 1.131 diff -up -r1.131 modules/plugin/base/src/ns4xPlugin.cpp --- modules/plugin/base/src/ns4xPlugin.cpp +++ modules/plugin/base/src/ns4xPlugin.cpp @@ -1402,7 +1402,10 @@ _getstringidentifier(const NPUTF8* name) if (!cx) return NULL; - return doGetIdentifier(cx, name); + ::JS_BeginRequest(cx); + NPIdentifier npi = doGetIdentifier(cx, name); + ::JS_EndRequest(cx); + return npi; } void NP_EXPORT @@ -1419,9 +1422,11 @@ _getstringidentifiers(const NPUTF8** nam if (!cx) return; + ::JS_BeginRequest(cx); for (int32_t i = 0; i < nameCount; ++i) { identifiers[i] = doGetIdentifier(cx, names[i]); } + ::JS_EndRequest(cx); } NPIdentifier NP_EXPORT Index: modules/plugin/base/src/nsJSNPRuntime.cpp =================================================================== RCS file: /cvsroot/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp,v retrieving revision 1.12 diff -up -r1.12 modules/plugin/base/src/nsJSNPRuntime.cpp --- modules/plugin/base/src/nsJSNPRuntime.cpp +++ modules/plugin/base/src/nsJSNPRuntime.cpp @@ -474,6 +474,7 @@ GetProperty(JSContext *cx, JSObject *obj if (JSVAL_IS_STRING(id)) { JSString *str = JSVAL_TO_STRING(id); + /* XXX what protects str from being destroyed while JS_GetUCProperty runs? */ return ::JS_GetUCProperty(cx, obj, ::JS_GetStringChars(str), ::JS_GetStringLength(str), rval); @@ -497,25 +498,19 @@ nsJSObjWrapper::NP_HasMethod(NPObject *n nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; jsval v; - JSBool ok = GetProperty(cx, npjsobj->mJSObj, identifier, &v); - - return ok && !JSVAL_IS_PRIMITIVE(v) && - ::JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(v)); + ::JS_BeginRequest(cx); + bool ok = GetProperty(cx, npjsobj->mJSObj, identifier, &v) && + !JSVAL_IS_PRIMITIVE(v) && + ::JS_ObjectIsFunction(cx, JSVAL_TO_OBJECT(v)); + ::JS_EndRequest(cx); + return ok; } static bool -doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args, - uint32_t argCount, NPVariant *result) +doInvoke2(NPP npp, JSContext *cx, + NPObject *npobj, NPIdentifier method, const NPVariant *args, + uint32_t argCount, NPVariant *result) { - NPP npp = NPPStack::Peek(); - JSContext *cx = GetJSContext(npp); - - if (!cx || !npobj || !result) { - // XXX: Throw null-ptr exception - - return PR_FALSE; - } - // Initialize *result VOID_TO_NPVARIANT(*result); @@ -527,7 +522,7 @@ doInvoke(NPObject *npobj, NPIdentifier m if ((jsval)method != JSVAL_VOID) { if (!GetProperty(cx, npjsobj->mJSObj, method, &fv) || ::JS_TypeOfValue(cx, fv) != JSTYPE_FUNCTION) { - return PR_FALSE; + return false; } } else { fv = OBJECT_TO_JSVAL(npjsobj->mJSObj); @@ -544,7 +539,7 @@ doInvoke(NPObject *npobj, NPIdentifier m if (!jsargs) { // XXX: throw an OOM exception! - return PR_FALSE; + return false; } } @@ -568,6 +563,24 @@ doInvoke(NPObject *npobj, NPIdentifier m return ok == JS_TRUE; } +static bool +doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args, + uint32_t argCount, NPVariant *result) +{ + NPP npp = NPPStack::Peek(); + JSContext *cx = GetJSContext(npp); + + if (!cx || !npobj || !result) { + // XXX: Throw null-ptr exception + + return false; + } + ::JS_BeginRequest(cx); + bool ok = doInvoke2(npp, cx, npobj, method, args, argCount, result); + ::JS_EndRequest(cx); + return ok; +} + // static bool nsJSObjWrapper::NP_Invoke(NPObject *npobj, NPIdentifier method, @@ -575,7 +588,7 @@ nsJSObjWrapper::NP_Invoke(NPObject *npob NPVariant *result) { if ((jsval)method == JSVAL_VOID) { - return PR_FALSE; + return false; } return doInvoke(npobj, method, args, argCount, result); @@ -599,13 +612,14 @@ nsJSObjWrapper::NP_HasProperty(NPObject if (!cx || !npobj) { // XXX: Throw null ptr exception - return PR_FALSE; + return false; } nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; jsval id = (jsval)identifier; JSBool found, ok = JS_FALSE; + ::JS_BeginRequest(cx); if (JSVAL_IS_STRING(id)) { JSString *str = JSVAL_TO_STRING(id); @@ -616,6 +630,7 @@ nsJSObjWrapper::NP_HasProperty(NPObject ok = ::JS_HasElement(cx, npjsobj->mJSObj, JSVAL_TO_INT(id), &found); } + ::JS_EndRequest(cx); return ok && found; } @@ -629,15 +644,18 @@ nsJSObjWrapper::NP_GetProperty(NPObject JSContext *cx = GetJSContext(npp); if (!cx || !npobj) - return PR_FALSE; + return false; nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; AutoCXPusher pusher(cx); jsval v; - return (GetProperty(cx, npjsobj->mJSObj, identifier, &v) && + ::JS_BeginRequest(cx); + bool ok = (GetProperty(cx, npjsobj->mJSObj, identifier, &v) && JSValToNPVariant(npp, cx, v, result)); + ::JS_EndRequest(cx); + return ok; } // static @@ -649,7 +667,7 @@ nsJSObjWrapper::NP_SetProperty(NPObject JSContext *cx = GetJSContext(npp); if (!cx || !npobj) - return PR_FALSE; + return false; nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; jsval id = (jsval)identifier; @@ -657,6 +675,7 @@ nsJSObjWrapper::NP_SetProperty(NPObject AutoCXPusher pusher(cx); + ::JS_BeginRequest(cx); jsval v = NPVariantToJSVal(npp, cx, value); if (JSVAL_IS_STRING(id)) { @@ -669,6 +688,7 @@ nsJSObjWrapper::NP_SetProperty(NPObject ok = ::JS_SetElement(cx, npjsobj->mJSObj, JSVAL_TO_INT(id), &v); } + ::JS_EndRequest(cx); // return ok == JS_TRUE to quiet down compiler warning, even if // return ok is what we really want. @@ -683,7 +703,7 @@ nsJSObjWrapper::NP_RemoveProperty(NPObje JSContext *cx = GetJSContext(npp); if (!cx || !npobj) - return PR_FALSE; + return false; nsJSObjWrapper *npjsobj = (nsJSObjWrapper *)npobj; jsval id = (jsval)identifier; @@ -691,6 +711,7 @@ nsJSObjWrapper::NP_RemoveProperty(NPObje AutoCXPusher pusher(cx); + ::JS_BeginRequest(cx); if (JSVAL_IS_STRING(id)) { JSString *str = JSVAL_TO_STRING(id); @@ -702,6 +723,7 @@ nsJSObjWrapper::NP_RemoveProperty(NPObje ok = ::JS_DeleteElement(cx, npjsobj->mJSObj, JSVAL_TO_INT(id)); } + ::JS_EndRequest(cx); // return ok == JS_TRUE to quiet down compiler warning, even if // return ok is what we really want. @@ -836,7 +858,10 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JS // Root the JSObject, its lifetime is now tied to that of the // NPObject. - if (!::JS_AddNamedRoot(cx, &wrapper->mJSObj, "nsJSObjWrapper::mJSObject")) { + ::JS_BeginRequest(cx); + JSBool ok = ::JS_AddNamedRoot(cx, &wrapper->mJSObj, "nsJSObjWrapper::mJSObject"); + ::JS_EndRequest(cx); + if (!ok) { NS_ERROR("Failed to root JSObject!"); _releaseobject(wrapper); @@ -1272,9 +1297,11 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JS // No existing JSObject, create one. + ::JS_BeginRequest(cx); JSObject *obj = ::JS_NewObject(cx, &sNPObjectJSWrapperClass, nsnull, nsnull); if (!obj) { + ::JS_EndRequest(cx); // OOM? Remove the stale entry from the hash. PL_DHashTableRawRemove(&sJSObjWrappers, entry); @@ -1286,7 +1313,9 @@ nsNPObjWrapper::GetNewOrUsed(NPP npp, JS entry->mJSObj = obj; - if (!::JS_SetPrivate(cx, obj, npobj)) { + JSBool ok = ::JS_SetPrivate(cx, obj, npobj); + ::JS_EndRequest(cx); + if (!ok) { NS_ERROR("Error setting private NPObject data in JS wrapper!"); PL_DHashTableRawRemove(&sJSObjWrappers, entry);