diff --git a/mozilla/js/src/jscntxt.h b/mozilla/js/src/jscntxt.h index 22aa5b55de8..76aa1fce411 100644 --- a/mozilla/js/src/jscntxt.h +++ b/mozilla/js/src/jscntxt.h @@ -54,6 +54,7 @@ #include "jsprvtd.h" #include "jspubtd.h" #include "jsregexp.h" +#include "jsutil.h" JS_BEGIN_EXTERN_C @@ -678,6 +679,35 @@ struct JSContext { #define JS_THREAD_ID(cx) ((cx)->thread ? (cx)->thread->id : 0) +#ifdef __cplusplus +/* FIXME(bug 332648): Move this into a public header. */ +class JSAutoTempValueRooter +{ + public: + JSAutoTempValueRooter(JSContext *cx, size_t len, jsval *vec) + : mContext(cx) { + JS_PUSH_TEMP_ROOT(mContext, len, vec, &mTvr); + } + JSAutoTempValueRooter(JSContext *cx, jsval v) + : mContext(cx) { + JS_PUSH_SINGLE_TEMP_ROOT(mContext, v, &mTvr); + } + + ~JSAutoTempValueRooter() { + JS_POP_TEMP_ROOT(mContext, &mTvr); + } + + private: +#if 0 + static void *operator new(size_t) CPP_THROW_NEW { return 0; }; + static void operator delete(void *, size_t) { }; +#endif + + JSContext *mContext; + JSTempValueRooter mTvr; +}; +#endif + /* * Slightly more readable macros for testing per-context option settings (also * to hide bitset implementation detail). diff --git a/mozilla/modules/plugin/base/src/ns4xPlugin.cpp b/mozilla/modules/plugin/base/src/ns4xPlugin.cpp index 56a8828eba7..d681b46d7b2 100644 --- a/mozilla/modules/plugin/base/src/ns4xPlugin.cpp +++ b/mozilla/modules/plugin/base/src/ns4xPlugin.cpp @@ -64,6 +64,8 @@ #include "nsIScriptContext.h" #include "nsDOMJSUtils.h" +#include "jscntxt.h" + #include "nsIXPConnect.h" #if defined(XP_MACOSX) @@ -1580,6 +1582,11 @@ _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result) return false; } + // Root obj and the rval (below). + jsval vec[] = { OBJECT_TO_JSVAL(obj), JSVAL_NULL }; + JSAutoTempValueRooter tvr(cx, NS_ARRAY_LENGTH(vec), vec); + jsval *rval = &vec[1]; + if (result) { // Initialize the out param to void VOID_TO_NPVARIANT(*result); @@ -1600,20 +1607,11 @@ _evaluate(NPP npp, NPObject* npobj, NPString *script, NPVariant *result) nsIPrincipal *principal = nsnull; // XXX: Get the principal from the security stack (TBD) - jsval rval = JSVAL_NULL; - if (!::JS_AddNamedRoot(cx, &rval, "NPN_evaluate")) { - return false; - } - nsresult rv = scx->EvaluateStringWithValue(utf16script, obj, principal, - nsnull, 0, nsnull, &rval, nsnull); + nsnull, 0, nsnull, rval, nsnull); - bool retval = NS_SUCCEEDED(rv) && - (!result || JSValToNPVariant(npp, cx, rval, result)); - - ::JS_RemoveRoot(cx, &rval); - - return retval; + return NS_SUCCEEDED(rv) && + (!result || JSValToNPVariant(npp, cx, *rval, result)); } bool NP_EXPORT diff --git a/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp b/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp index b422bb97709..215c9d778cd 100644 --- a/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp +++ b/mozilla/modules/plugin/base/src/nsJSNPRuntime.cpp @@ -50,6 +50,9 @@ #include "prmem.h" #include "nsIContent.h" +// FIXME(bug 332648): Give me a real API please! +#include "jscntxt.h" + // Hash of JSObject wrappers that wraps JSObjects as NPObjects. There // will be one wrapper per JSObject per plugin instance, i.e. if two // plugins access the JSObject x, two wrappers for x will be @@ -572,15 +575,21 @@ doInvoke(NPObject *npobj, NPIdentifier method, const NPVariant *args, } } + JSTempValueRooter tvr; + JS_PUSH_TEMP_ROOT(cx, 0, jsargs, &tvr); + // Convert args for (PRUint32 i = 0; i < argCount; ++i) { jsargs[i] = NPVariantToJSVal(npp, cx, args + i); + ++tvr.count; } jsval v; JSBool ok = ::JS_CallFunctionValue(cx, npjsobj->mJSObj, fv, argCount, jsargs, &v); + JS_POP_TEMP_ROOT(cx, &tvr); + if (jsargs != jsargs_buf) PR_Free(jsargs); @@ -710,6 +719,7 @@ nsJSObjWrapper::NP_SetProperty(NPObject *npobj, NPIdentifier identifier, JSAutoRequest ar(cx); jsval v = NPVariantToJSVal(npp, cx, value); + JSAutoTempValueRooter tvr(cx, v); if (JSVAL_IS_STRING(id)) { JSString *str = JSVAL_TO_STRING(id);