зеркало из https://github.com/mozilla/pjs.git
Bug 565157 - typed JS_AddRoot (r=igor)
This commit is contained in:
Родитель
90d168b8d7
Коммит
1581c6693c
|
@ -1748,46 +1748,39 @@ public:
|
|||
// aPtr should be the pointer to the jsval we want to protect
|
||||
nsAutoGCRoot(jsval* aPtr, nsresult* aResult
|
||||
MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM) :
|
||||
mPtr(aPtr)
|
||||
mPtr(aPtr), mRootType(RootType_JSVal)
|
||||
{
|
||||
MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
|
||||
mResult = *aResult = AddJSGCRoot(aPtr, RootType_JSVal, "nsAutoGCRoot");
|
||||
}
|
||||
|
||||
// aPtr should be the pointer to the JSObject* we want to protect
|
||||
nsAutoGCRoot(JSObject** aPtr, nsresult* aResult
|
||||
MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM) :
|
||||
mPtr(aPtr)
|
||||
mPtr(aPtr), mRootType(RootType_Object)
|
||||
{
|
||||
MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
|
||||
}
|
||||
|
||||
// aPtr should be the pointer to the thing we want to protect
|
||||
nsAutoGCRoot(void* aPtr, nsresult* aResult
|
||||
MOZILLA_GUARD_OBJECT_NOTIFIER_PARAM) :
|
||||
mPtr(aPtr)
|
||||
{
|
||||
MOZILLA_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
|
||||
mResult = *aResult = AddJSGCRoot(aPtr, RootType_Object, "nsAutoGCRoot");
|
||||
}
|
||||
|
||||
~nsAutoGCRoot() {
|
||||
if (NS_SUCCEEDED(mResult)) {
|
||||
RemoveJSGCRoot(mPtr);
|
||||
RemoveJSGCRoot(mPtr, mRootType);
|
||||
}
|
||||
}
|
||||
|
||||
static void Shutdown();
|
||||
|
||||
private:
|
||||
static nsresult AddJSGCRoot(void *aPtr, const char* aName);
|
||||
static nsresult RemoveJSGCRoot(void *aPtr);
|
||||
enum RootType { RootType_JSVal, RootType_Object };
|
||||
static nsresult AddJSGCRoot(void *aPtr, RootType aRootType, const char* aName);
|
||||
static nsresult RemoveJSGCRoot(void *aPtr, RootType aRootType);
|
||||
|
||||
static nsIJSRuntimeService* sJSRuntimeService;
|
||||
static JSRuntime* sJSScriptRuntime;
|
||||
|
||||
void* mPtr;
|
||||
RootType mRootType;
|
||||
nsresult mResult;
|
||||
MOZILLA_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||
};
|
||||
|
|
|
@ -3082,7 +3082,7 @@ nsContentUtils::GetContentPolicy()
|
|||
|
||||
// static
|
||||
nsresult
|
||||
nsAutoGCRoot::AddJSGCRoot(void* aPtr, const char* aName)
|
||||
nsAutoGCRoot::AddJSGCRoot(void* aPtr, RootType aRootType, const char* aName)
|
||||
{
|
||||
if (!sJSScriptRuntime) {
|
||||
nsresult rv = CallGetService("@mozilla.org/js/xpc/RuntimeService;1",
|
||||
|
@ -3098,7 +3098,10 @@ nsAutoGCRoot::AddJSGCRoot(void* aPtr, const char* aName)
|
|||
}
|
||||
|
||||
PRBool ok;
|
||||
ok = ::JS_AddNamedRootRT(sJSScriptRuntime, aPtr, aName);
|
||||
if (aRootType == RootType_JSVal)
|
||||
ok = ::js_AddRootRT(sJSScriptRuntime, (jsval *)aPtr, aName);
|
||||
else
|
||||
ok = ::js_AddGCThingRootRT(sJSScriptRuntime, (void **)aPtr, aName);
|
||||
if (!ok) {
|
||||
NS_WARNING("JS_AddNamedRootRT failed");
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
@ -3109,14 +3112,17 @@ nsAutoGCRoot::AddJSGCRoot(void* aPtr, const char* aName)
|
|||
|
||||
/* static */
|
||||
nsresult
|
||||
nsAutoGCRoot::RemoveJSGCRoot(void* aPtr)
|
||||
nsAutoGCRoot::RemoveJSGCRoot(void* aPtr, RootType aRootType)
|
||||
{
|
||||
if (!sJSScriptRuntime) {
|
||||
NS_NOTREACHED("Trying to remove a JS GC root when none were added");
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
::JS_RemoveRootRT(sJSScriptRuntime, aPtr);
|
||||
if (aRootType == RootType_JSVal)
|
||||
::js_RemoveRoot(sJSScriptRuntime, (jsval *)aPtr);
|
||||
else
|
||||
::js_RemoveRoot(sJSScriptRuntime, (JSObject **)aPtr);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -2,39 +2,19 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIJSRuntimeService.h"
|
||||
|
||||
nsIJSRuntimeService* NativeJSContext::sJSRuntimeService = 0;
|
||||
JSRuntime* NativeJSContext::sJSScriptRuntime = 0;
|
||||
|
||||
PRBool
|
||||
NativeJSContext::AddGCRoot(void *aPtr, const char *aName)
|
||||
NativeJSContext::AddGCRoot(JSObject **aPtr, const char *aName)
|
||||
{
|
||||
NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
|
||||
if (!sJSScriptRuntime) {
|
||||
nsresult rv = CallGetService("@mozilla.org/js/xpc/RuntimeService;1",
|
||||
&sJSRuntimeService);
|
||||
NS_ENSURE_SUCCESS(rv, PR_FALSE);
|
||||
NS_ABORT_IF_FALSE(sJSRuntimeService, "CallGetService succeeded but returned a null pointer?");
|
||||
|
||||
sJSRuntimeService->GetRuntime(&sJSScriptRuntime);
|
||||
if (!sJSScriptRuntime) {
|
||||
NS_RELEASE(sJSRuntimeService);
|
||||
NS_WARNING("Unable to get JS runtime from JS runtime service");
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool ok;
|
||||
return ok = ::JS_AddNamedRootRT(sJSScriptRuntime, aPtr, aName);
|
||||
return ok = ::JS_AddNamedObjectRoot(ctx, aPtr, aName);
|
||||
}
|
||||
|
||||
void
|
||||
NativeJSContext::ReleaseGCRoot(void *aPtr)
|
||||
NativeJSContext::ReleaseGCRoot(JSObject **aPtr)
|
||||
{
|
||||
NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
|
||||
if (!sJSScriptRuntime) {
|
||||
NS_NOTREACHED("Trying to remove a JS GC root when none were added");
|
||||
return;
|
||||
}
|
||||
|
||||
::JS_RemoveRootRT(sJSScriptRuntime, aPtr);
|
||||
::JS_RemoveObjectRoot(ctx, aPtr);
|
||||
}
|
||||
|
|
|
@ -62,8 +62,8 @@ public:
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool AddGCRoot (void *aPtr, const char *aName);
|
||||
void ReleaseGCRoot (void *aPtr);
|
||||
PRBool AddGCRoot (JSObject **aPtr, const char *aName);
|
||||
void ReleaseGCRoot (JSObject **aPtr);
|
||||
|
||||
void SetRetVal (PRInt32 val) {
|
||||
NS_ASSERTION(NS_SUCCEEDED(error), "class failed to initialize and caller used class without checking!");
|
||||
|
@ -186,9 +186,6 @@ public:
|
|||
PRUint32 argc;
|
||||
jsval *argv;
|
||||
|
||||
static nsIJSRuntimeService* sJSRuntimeService;
|
||||
static JSRuntime* sJSScriptRuntime;
|
||||
|
||||
public:
|
||||
// static JS helpers
|
||||
|
||||
|
|
|
@ -231,7 +231,7 @@ jsd_GetValueString(JSDContext* jsdc, JSDValue* jsdval)
|
|||
JS_RestoreExceptionState(cx, exceptionState);
|
||||
if(jsdval->string)
|
||||
{
|
||||
if(!JS_AddNamedRoot(cx, &jsdval->string, "ValueString"))
|
||||
if(!JS_AddNamedStringRoot(cx, &jsdval->string, "ValueString"))
|
||||
jsdval->string = NULL;
|
||||
}
|
||||
JS_EndRequest(cx);
|
||||
|
@ -275,7 +275,7 @@ jsd_NewValue(JSDContext* jsdc, jsval val)
|
|||
{
|
||||
JSBool ok = JS_FALSE;
|
||||
JS_BeginRequest(jsdc->dumbContext);
|
||||
ok = JS_AddNamedRoot(jsdc->dumbContext, &jsdval->val, "JSDValue");
|
||||
ok = JS_AddNamedValueRoot(jsdc->dumbContext, &jsdval->val, "JSDValue");
|
||||
JS_EndRequest(jsdc->dumbContext);
|
||||
if(!ok)
|
||||
{
|
||||
|
@ -300,7 +300,7 @@ jsd_DropValue(JSDContext* jsdc, JSDValue* jsdval)
|
|||
if(JSVAL_IS_GCTHING(jsdval->val))
|
||||
{
|
||||
JS_BeginRequest(jsdc->dumbContext);
|
||||
JS_RemoveRoot(jsdc->dumbContext, &jsdval->val);
|
||||
JS_RemoveValueRoot(jsdc->dumbContext, &jsdval->val);
|
||||
JS_EndRequest(jsdc->dumbContext);
|
||||
}
|
||||
free(jsdval);
|
||||
|
@ -422,7 +422,7 @@ jsd_RefreshValue(JSDContext* jsdc, JSDValue* jsdval)
|
|||
if(!JSVAL_IS_STRING(jsdval->val))
|
||||
{
|
||||
JS_BeginRequest(cx);
|
||||
JS_RemoveRoot(cx, &jsdval->string);
|
||||
JS_RemoveStringRoot(cx, &jsdval->string);
|
||||
JS_EndRequest(cx);
|
||||
}
|
||||
jsdval->string = NULL;
|
||||
|
|
|
@ -52,13 +52,13 @@ public:
|
|||
explicit jsvalRoot(JSContext *context, jsval value = JSVAL_NULL)
|
||||
: cx(context), v(value)
|
||||
{
|
||||
if (!JS_AddRoot(cx, &v)) {
|
||||
if (!JS_AddValueRoot(cx, &v)) {
|
||||
fprintf(stderr, "Out of memory in jsvalRoot constructor, aborting\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
~jsvalRoot() { JS_RemoveRoot(cx, &v); }
|
||||
~jsvalRoot() { JS_RemoveValueRoot(cx, &v); }
|
||||
|
||||
operator jsval() const { return value(); }
|
||||
|
||||
|
|
111
js/src/jsapi.cpp
111
js/src/jsapi.cpp
|
@ -1770,37 +1770,110 @@ JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval)
|
|||
}
|
||||
|
||||
#undef JS_AddRoot
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddRoot(JSContext *cx, void *rp)
|
||||
JS_AddValueRoot(JSContext *cx, jsval *vp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AddRoot(cx, rp, NULL);
|
||||
return js_AddRoot(cx, vp, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedRootRT(JSRuntime *rt, void *rp, const char *name)
|
||||
{
|
||||
return js_AddRootRT(rt, rp, name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveRoot(JSContext *cx, void *rp)
|
||||
JS_AddStringRoot(JSContext *cx, JSString **rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_RemoveRoot(cx->runtime, rp);
|
||||
return js_AddGCThingRoot(cx, (void **)rp, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveRootRT(JSRuntime *rt, void *rp)
|
||||
{
|
||||
return js_RemoveRoot(rt, rp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedRoot(JSContext *cx, void *rp, const char *name)
|
||||
JS_AddObjectRoot(JSContext *cx, JSObject **rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AddRoot(cx, rp, name);
|
||||
return js_AddGCThingRoot(cx, (void **)rp, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddDoubleRoot(JSContext *cx, jsdouble **rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AddGCThingRoot(cx, (void **)rp, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddGCThingRoot(JSContext *cx, void **rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AddGCThingRoot(cx, (void **)rp, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedValueRoot(JSContext *cx, jsval *vp, const char *name)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AddRoot(cx, vp, name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedStringRoot(JSContext *cx, JSString **rp, const char *name)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AddGCThingRoot(cx, (void **)rp, name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedObjectRoot(JSContext *cx, JSObject **rp, const char *name)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AddGCThingRoot(cx, (void **)rp, name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedDoubleRoot(JSContext *cx, jsdouble **rp, const char *name)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AddGCThingRoot(cx, (void **)rp, name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedGCThingRoot(JSContext *cx, void **rp, const char *name)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_AddGCThingRoot(cx, (void **)rp, name);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveValueRoot(JSContext *cx, jsval *vp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_RemoveRoot(cx->runtime, (void *)vp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveStringRoot(JSContext *cx, JSString **rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_RemoveRoot(cx->runtime, (void *)rp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveObjectRoot(JSContext *cx, JSObject **rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_RemoveRoot(cx->runtime, (void *)rp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveDoubleRoot(JSContext *cx, jsdouble **rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_RemoveRoot(cx->runtime, (void *)rp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveGCThingRoot(JSContext *cx, void **rp)
|
||||
{
|
||||
CHECK_REQUEST(cx);
|
||||
return js_RemoveRoot(cx->runtime, (void *)rp);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
|
@ -5324,7 +5397,7 @@ JS_DropExceptionState(JSContext *cx, JSExceptionState *state)
|
|||
CHECK_REQUEST(cx);
|
||||
if (state) {
|
||||
if (state->throwing && JSVAL_IS_GCTHING(state->exception))
|
||||
JS_RemoveRoot(cx, &state->exception);
|
||||
JS_RemoveValueRoot(cx, &state->exception);
|
||||
cx->free(state);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -903,41 +903,101 @@ extern JS_PUBLIC_API(JSBool)
|
|||
JS_NewNumberValue(JSContext *cx, jsdouble d, jsval *rval);
|
||||
|
||||
/*
|
||||
* A JS GC root is a pointer to a JSObject *, JSString *, or jsdouble * that
|
||||
* itself points into the GC heap (more recently, we support this extension:
|
||||
* a root may be a pointer to a jsval v for which JSVAL_IS_GCTHING(v) is true).
|
||||
* A GC root is a pointer to a jsval, JSObject * or JSString * that itself
|
||||
* points into the GC heap. JS_AddValueRoot takes a pointer to a jsval and
|
||||
* JS_AddGCThingRoot takes a pointer to a JSObject * or JString *.
|
||||
*
|
||||
* Therefore, you never pass JSObject *obj to JS_AddRoot(cx, obj). You always
|
||||
* call JS_AddRoot(cx, &obj), passing obj by reference. And later, before obj
|
||||
* or the structure it is embedded within goes out of scope or is freed, you
|
||||
* must call JS_RemoveRoot(cx, &obj).
|
||||
* Note that, since JS_Add*Root stores the address of a variable (of type
|
||||
* jsval, JSString *, or JSObject *), that variable must live until
|
||||
* JS_Remove*Root is called to remove that variable. For example, after:
|
||||
*
|
||||
* Also, use JS_AddNamedRoot(cx, &structPtr->memberObj, "structPtr->memberObj")
|
||||
* in preference to JS_AddRoot(cx, &structPtr->memberObj), in order to identify
|
||||
* void some_function() {
|
||||
* jsval v;
|
||||
* JS_AddNamedRootedValue(cx, &v, "name");
|
||||
*
|
||||
* the caller must perform
|
||||
*
|
||||
* JS_RemoveRootedValue(cx, &v);
|
||||
*
|
||||
* before some_function() returns.
|
||||
*
|
||||
* Also, use JS_AddNamed*Root(cx, &structPtr->memberObj, "structPtr->memberObj")
|
||||
* in preference to JS_Add*Root(cx, &structPtr->memberObj), in order to identify
|
||||
* roots by their source callsites. This way, you can find the callsite while
|
||||
* debugging if you should fail to do JS_RemoveRoot(cx, &structPtr->memberObj)
|
||||
* debugging if you should fail to do JS_Remove*Root(cx, &structPtr->memberObj)
|
||||
* before freeing structPtr's memory.
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddRoot(JSContext *cx, void *rp);
|
||||
JS_AddValueRoot(JSContext *cx, jsval *vp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddStringRoot(JSContext *cx, JSString **rp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddObjectRoot(JSContext *cx, JSObject **rp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddDoubleRoot(JSContext *cx, jsdouble **rp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddGCThingRoot(JSContext *cx, void **rp);
|
||||
|
||||
#ifdef NAME_ALL_GC_ROOTS
|
||||
#define JS_DEFINE_TO_TOKEN(def) #def
|
||||
#define JS_DEFINE_TO_STRING(def) JS_DEFINE_TO_TOKEN(def)
|
||||
#define JS_AddRoot(cx,rp) JS_AddNamedRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
|
||||
#define JS_AddValueRoot(cx,vp) JS_AddNamedValueRoot((cx), (vp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
|
||||
#define JS_AddStringRoot(cx,rp) JS_AddNamedStringRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
|
||||
#define JS_AddObjectRoot(cx,rp) JS_AddNamedObjectRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
|
||||
#define JS_AddDoubleRoot(cx,rp) JS_AddNamedDoubleRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
|
||||
#define JS_AddGCThingRoot(cx,rp) JS_AddNamedGCThingRoot((cx), (rp), (__FILE__ ":" JS_TOKEN_TO_STRING(__LINE__))
|
||||
#endif
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedRoot(JSContext *cx, void *rp, const char *name);
|
||||
JS_AddNamedValueRoot(JSContext *cx, jsval *vp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedRootRT(JSRuntime *rt, void *rp, const char *name);
|
||||
JS_AddNamedStringRoot(JSContext *cx, JSString **rp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveRoot(JSContext *cx, void *rp);
|
||||
JS_AddNamedObjectRoot(JSContext *cx, JSObject **rp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveRootRT(JSRuntime *rt, void *rp);
|
||||
JS_AddNamedDoubleRoot(JSContext *cx, jsdouble **rp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_AddNamedGCThingRoot(JSContext *cx, void **rp, const char *name);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveValueRoot(JSContext *cx, jsval *vp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveStringRoot(JSContext *cx, JSString **rp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveObjectRoot(JSContext *cx, JSObject **rp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveDoubleRoot(JSContext *cx, jsdouble **rp);
|
||||
|
||||
extern JS_PUBLIC_API(JSBool)
|
||||
JS_RemoveGCThingRoot(JSContext *cx, void **rp);
|
||||
|
||||
/* TODO: remove these APIs */
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_AddRootRT(JSRuntime *rt, jsval *vp, const char *name);
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_AddGCThingRootRT(JSRuntime *rt, void **rp, const char *name);
|
||||
|
||||
extern JS_FRIEND_API(JSBool)
|
||||
js_RemoveRoot(JSRuntime *rt, void *rp);
|
||||
|
||||
/*
|
||||
* This symbol may be used by embedders to detect the change from the old
|
||||
* JS_AddRoot(JSContext *, void *) APIs to the new ones above.
|
||||
*/
|
||||
#define JS_TYPED_ROOTING_API
|
||||
|
||||
/*
|
||||
* The last GC thing of each type (object, string, double, external string
|
||||
|
@ -965,7 +1025,7 @@ JS_ClearNewbornRoots(JSContext *cx);
|
|||
* Scoped local root management allows native functions, getter/setters, etc.
|
||||
* to avoid worrying about the newborn root pigeon-holes, overloading local
|
||||
* roots allocated in argv and *rval, or ending up having to call JS_Add*Root
|
||||
* and JS_RemoveRoot to manage global roots temporarily.
|
||||
* and JS_Remove*Root to manage global roots temporarily.
|
||||
*
|
||||
* Instead, calling JS_EnterLocalRootScope and JS_LeaveLocalRootScope around
|
||||
* the body of the native hook causes the engine to allocate a local root for
|
||||
|
@ -2227,13 +2287,13 @@ JS_CompileFileHandleForPrincipals(JSContext *cx, JSObject *obj,
|
|||
*
|
||||
* JSScript *script = JS_CompileFile(cx, global, filename);
|
||||
* JSObject *scrobj = JS_NewScriptObject(cx, script);
|
||||
* JS_AddNamedRoot(cx, &scrobj, "scrobj");
|
||||
* JS_AddNamedObjectRoot(cx, &scrobj, "scrobj");
|
||||
* do {
|
||||
* jsval result;
|
||||
* JS_ExecuteScript(cx, global, script, &result);
|
||||
* JS_GC();
|
||||
* } while (!JSVAL_IS_BOOLEAN(result) || JSVAL_TO_BOOLEAN(result));
|
||||
* JS_RemoveRoot(cx, &scrobj);
|
||||
* JS_RemoveObjectRoot(cx, &scrobj);
|
||||
*/
|
||||
extern JS_PUBLIC_API(JSObject *)
|
||||
JS_NewScriptObject(JSContext *cx, JSScript *script);
|
||||
|
|
|
@ -1129,16 +1129,25 @@ js_FinishGC(JSRuntime *rt)
|
|||
}
|
||||
|
||||
JSBool
|
||||
js_AddRoot(JSContext *cx, void *rp, const char *name)
|
||||
js_AddRoot(JSContext *cx, jsval *vp, const char *name)
|
||||
{
|
||||
JSBool ok = js_AddRootRT(cx->runtime, rp, name);
|
||||
JSBool ok = js_AddRootRT(cx->runtime, vp, name);
|
||||
if (!ok)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
JSBool
|
||||
js_AddRootRT(JSRuntime *rt, void *rp, const char *name)
|
||||
js_AddGCThingRoot(JSContext *cx, void **rp, const char *name)
|
||||
{
|
||||
JSBool ok = js_AddGCThingRootRT(cx->runtime, rp, name);
|
||||
if (!ok)
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
AddRoot(JSRuntime *rt, void *rp, const char *name)
|
||||
{
|
||||
js::GCRoots *roots = &rt->gcRootsHash;
|
||||
|
||||
|
@ -1154,11 +1163,23 @@ js_AddRootRT(JSRuntime *rt, void *rp, const char *name)
|
|||
return !!roots->put(rp, name);
|
||||
}
|
||||
|
||||
JSBool
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_AddRootRT(JSRuntime *rt, jsval *vp, const char *name)
|
||||
{
|
||||
return AddRoot(rt, vp, name);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_AddGCThingRootRT(JSRuntime *rt, void **rp, const char *name)
|
||||
{
|
||||
return AddRoot(rt, rp, name);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSBool)
|
||||
js_RemoveRoot(JSRuntime *rt, void *rp)
|
||||
{
|
||||
/*
|
||||
* Due to the JS_RemoveRootRT API, we may be called outside of a request.
|
||||
* Due to the JS_RemoveRoot API, we may be called outside of a request.
|
||||
* Same synchronization drill as above in js_AddRoot.
|
||||
*/
|
||||
AutoLockGC lock(rt);
|
||||
|
|
|
@ -99,13 +99,10 @@ js_ChangeExternalStringFinalizer(JSStringFinalizeOp oldop,
|
|||
JSStringFinalizeOp newop);
|
||||
|
||||
extern JSBool
|
||||
js_AddRoot(JSContext *cx, void *rp, const char *name);
|
||||
js_AddRoot(JSContext *cx, jsval *vp, const char *name);
|
||||
|
||||
extern JSBool
|
||||
js_AddRootRT(JSRuntime *rt, void *rp, const char *name);
|
||||
|
||||
extern JSBool
|
||||
js_RemoveRoot(JSRuntime *rt, void *rp);
|
||||
js_AddGCThingRoot(JSContext *cx, void **rp, const char *name);
|
||||
|
||||
#ifdef DEBUG
|
||||
extern void
|
||||
|
|
|
@ -638,7 +638,7 @@ js_BeginJSONParse(JSContext *cx, jsval *rootVal)
|
|||
return NULL;
|
||||
|
||||
jp->objectStack = arr;
|
||||
if (!js_AddRoot(cx, &jp->objectStack, "JSON parse stack"))
|
||||
if (!JS_AddNamedObjectRoot(cx, &jp->objectStack, "JSON parse stack"))
|
||||
goto bad;
|
||||
|
||||
jp->statep = jp->stateStack;
|
||||
|
|
|
@ -227,10 +227,10 @@ public:
|
|||
if (!JS_ReportPendingException(cx))
|
||||
JS_ClearPendingException(cx);
|
||||
}
|
||||
JS_AddNamedRoot(cx, &mStr, "Value ToString helper");
|
||||
JS_AddNamedStringRoot(cx, &mStr, "Value ToString helper");
|
||||
}
|
||||
~ToString() {
|
||||
JS_RemoveRoot(cx, &mStr);
|
||||
JS_RemoveStringRoot(cx, &mStr);
|
||||
}
|
||||
JSBool threw() { return !mStr; }
|
||||
jsval getJSVal() { return STRING_TO_JSVAL(mStr); }
|
||||
|
@ -3263,10 +3263,10 @@ Scatter(JSContext *cx, uintN argc, jsval *vp)
|
|||
goto fail;
|
||||
for (i = 0; i < n; i++) {
|
||||
sd.results[i] = JSVAL_VOID;
|
||||
ok = JS_AddRoot(cx, &sd.results[i]);
|
||||
ok = JS_AddValueRoot(cx, &sd.results[i]);
|
||||
if (!ok) {
|
||||
while (i-- > 0)
|
||||
JS_RemoveRoot(cx, &sd.results[i]);
|
||||
JS_RemoveValueRoot(cx, &sd.results[i]);
|
||||
free(sd.results);
|
||||
sd.results = NULL;
|
||||
goto fail;
|
||||
|
@ -3283,14 +3283,14 @@ Scatter(JSContext *cx, uintN argc, jsval *vp)
|
|||
sd.threads[i].cx = NULL;
|
||||
sd.threads[i].fn = JSVAL_NULL;
|
||||
|
||||
ok = JS_AddRoot(cx, &sd.threads[i].fn);
|
||||
ok = JS_AddValueRoot(cx, &sd.threads[i].fn);
|
||||
if (ok && !JS_GetElement(cx, inArr, (jsint) i, &sd.threads[i].fn)) {
|
||||
JS_RemoveRoot(cx, &sd.threads[i].fn);
|
||||
JS_RemoveValueRoot(cx, &sd.threads[i].fn);
|
||||
ok = JS_FALSE;
|
||||
}
|
||||
if (!ok) {
|
||||
while (i-- > 0)
|
||||
JS_RemoveRoot(cx, &sd.threads[i].fn);
|
||||
JS_RemoveValueRoot(cx, &sd.threads[i].fn);
|
||||
free(sd.threads);
|
||||
sd.threads = NULL;
|
||||
goto fail;
|
||||
|
@ -3358,7 +3358,7 @@ out:
|
|||
JSContext *acx;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
JS_RemoveRoot(cx, &sd.threads[i].fn);
|
||||
JS_RemoveValueRoot(cx, &sd.threads[i].fn);
|
||||
acx = sd.threads[i].cx;
|
||||
if (acx) {
|
||||
JS_SetContextThread(acx);
|
||||
|
@ -3369,7 +3369,7 @@ out:
|
|||
}
|
||||
if (sd.results) {
|
||||
for (i = 0; i < n; i++)
|
||||
JS_RemoveRoot(cx, &sd.results[i]);
|
||||
JS_RemoveValueRoot(cx, &sd.results[i]);
|
||||
free(sd.results);
|
||||
}
|
||||
if (sd.cvar)
|
||||
|
@ -4199,13 +4199,13 @@ its_setter(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
|||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!JS_AddRoot(cx, val)) {
|
||||
if (!JS_AddValueRoot(cx, val)) {
|
||||
delete val;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!JS_SetPrivate(cx, obj, (void*)val)) {
|
||||
JS_RemoveRoot(cx, val);
|
||||
JS_RemoveValueRoot(cx, val);
|
||||
delete val;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
@ -4437,7 +4437,7 @@ its_finalize(JSContext *cx, JSObject *obj)
|
|||
fprintf(gOutFile, "finalizing it\n");
|
||||
rootedVal = (jsval *) JS_GetPrivate(cx, obj);
|
||||
if (rootedVal) {
|
||||
JS_RemoveRoot(cx, rootedVal);
|
||||
JS_RemoveValueRoot(cx, rootedVal);
|
||||
JS_SetPrivate(cx, obj, NULL);
|
||||
delete rootedVal;
|
||||
}
|
||||
|
@ -5016,7 +5016,7 @@ shell(JSContext *cx, int argc, char **argv, char **envp)
|
|||
JSObject *newGlobalObject(JSContext *cx) { return NewGlobalObject(cx); }
|
||||
};
|
||||
ShellWorkerHooks hooks;
|
||||
if (!JS_AddNamedRoot(cx, &gWorkers, "Workers") ||
|
||||
if (!JS_AddNamedObjectRoot(cx, &gWorkers, "Workers") ||
|
||||
!js::workers::init(cx, &hooks, glob, &gWorkers)) {
|
||||
return 1;
|
||||
}
|
||||
|
@ -5026,7 +5026,7 @@ shell(JSContext *cx, int argc, char **argv, char **envp)
|
|||
|
||||
#ifdef JS_THREADSAFE
|
||||
js::workers::finish(cx, gWorkers);
|
||||
JS_RemoveRoot(cx, &gWorkers);
|
||||
JS_RemoveObjectRoot(cx, &gWorkers);
|
||||
if (result == 0)
|
||||
result = gExitCode;
|
||||
#endif
|
||||
|
|
|
@ -1394,7 +1394,7 @@ mozJSComponentLoader::GlobalForLocation(nsILocalFile *aComponent,
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
JS_AddNamedRoot(cx, aGlobal, *aLocation);
|
||||
JS_AddNamedObjectRoot(cx, aGlobal, *aLocation);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -151,7 +151,7 @@ class mozJSComponentLoader : public nsIModuleLoader,
|
|||
if (global) {
|
||||
JSAutoRequest ar(sSelf->mContext);
|
||||
JS_ClearScope(sSelf->mContext, global);
|
||||
JS_RemoveRoot(sSelf->mContext, &global);
|
||||
JS_RemoveObjectRoot(sSelf->mContext, &global);
|
||||
}
|
||||
|
||||
if (location)
|
||||
|
|
|
@ -82,7 +82,7 @@ public:
|
|||
*/
|
||||
JSBool Hold(JSRuntime* aRt) {
|
||||
if (!mHeld) {
|
||||
if (JS_AddNamedRootRT(aRt, &mGCThing, "nsAutoJSValHolder")) {
|
||||
if (js_AddGCThingRootRT(aRt, &mGCThing, "nsAutoJSValHolder")) {
|
||||
mRt = aRt;
|
||||
mHeld = JS_TRUE;
|
||||
} else {
|
||||
|
@ -102,7 +102,7 @@ public:
|
|||
jsval oldval = mVal;
|
||||
|
||||
if (mHeld) {
|
||||
JS_RemoveRootRT(mRt, &mGCThing); // infallible
|
||||
js_RemoveRoot(mRt, &mGCThing); // infallible
|
||||
mHeld = JS_FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -583,7 +583,7 @@ nsJSObjWrapper::NP_Invalidate(NPObject *npobj)
|
|||
|
||||
if (jsnpobj && jsnpobj->mJSObj) {
|
||||
// Unroot the object's JSObject
|
||||
::JS_RemoveRootRT(sJSRuntime, &jsnpobj->mJSObj);
|
||||
js_RemoveRoot(sJSRuntime, &jsnpobj->mJSObj);
|
||||
|
||||
if (sJSObjWrappers.ops) {
|
||||
// Remove the wrapper from the hash
|
||||
|
@ -1157,7 +1157,7 @@ nsJSObjWrapper::GetNewOrUsed(NPP npp, JSContext *cx, JSObject *obj)
|
|||
|
||||
// Root the JSObject, its lifetime is now tied to that of the
|
||||
// NPObject.
|
||||
if (!::JS_AddNamedRoot(cx, &wrapper->mJSObj, "nsJSObjWrapper::mJSObject")) {
|
||||
if (!::JS_AddNamedObjectRoot(cx, &wrapper->mJSObj, "nsJSObjWrapper::mJSObject")) {
|
||||
NS_ERROR("Failed to root JSObject!");
|
||||
|
||||
_releaseobject(wrapper);
|
||||
|
@ -2137,7 +2137,7 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
|
|||
}
|
||||
|
||||
*vp = OBJECT_TO_JSVAL(memobj);
|
||||
::JS_AddRoot(cx, vp);
|
||||
::JS_AddValueRoot(cx, vp);
|
||||
|
||||
::JS_SetPrivate(cx, memobj, (void *)memberPrivate);
|
||||
|
||||
|
@ -2156,12 +2156,12 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
|
|||
NPBool hasProperty = npobj->_class->getProperty(npobj, (NPIdentifier)id,
|
||||
&npv);
|
||||
if (!ReportExceptionIfPending(cx)) {
|
||||
::JS_RemoveRoot(cx, vp);
|
||||
::JS_RemoveValueRoot(cx, vp);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!hasProperty) {
|
||||
::JS_RemoveRoot(cx, vp);
|
||||
::JS_RemoveValueRoot(cx, vp);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -2181,7 +2181,7 @@ CreateNPObjectMember(NPP npp, JSContext *cx, JSObject *obj, NPObject* npobj,
|
|||
memberPrivate->methodName = id;
|
||||
memberPrivate->npp = npp;
|
||||
|
||||
::JS_RemoveRoot(cx, vp);
|
||||
::JS_RemoveValueRoot(cx, vp);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
|
|
@ -2159,7 +2159,7 @@ nsCryptoRunnable::nsCryptoRunnable(nsCryptoRunArgs *args)
|
|||
NS_ASSERTION(args,"Passed nsnull to nsCryptoRunnable constructor.");
|
||||
m_args = args;
|
||||
NS_IF_ADDREF(m_args);
|
||||
JS_AddNamedRoot(args->m_cx, &args->m_scope,"nsCryptoRunnable::mScope");
|
||||
JS_AddNamedObjectRoot(args->m_cx, &args->m_scope,"nsCryptoRunnable::mScope");
|
||||
}
|
||||
|
||||
nsCryptoRunnable::~nsCryptoRunnable()
|
||||
|
@ -2168,7 +2168,7 @@ nsCryptoRunnable::~nsCryptoRunnable()
|
|||
|
||||
{
|
||||
JSAutoRequest ar(m_args->m_cx);
|
||||
JS_RemoveRoot(m_args->m_cx, &m_args->m_scope);
|
||||
JS_RemoveObjectRoot(m_args->m_cx, &m_args->m_scope);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(m_args);
|
||||
|
|
|
@ -195,7 +195,7 @@ nsXPITriggerInfo::~nsXPITriggerInfo()
|
|||
|
||||
if ( mCx && !JSVAL_IS_NULL(mCbval) ) {
|
||||
JS_BeginRequest(mCx);
|
||||
JS_RemoveRoot( mCx, &mCbval );
|
||||
JS_RemoveValueRoot(mCx, &mCbval );
|
||||
JS_EndRequest(mCx);
|
||||
}
|
||||
|
||||
|
@ -219,7 +219,7 @@ void nsXPITriggerInfo::SaveCallback( JSContext *aCx, jsval aVal )
|
|||
|
||||
if ( !JSVAL_IS_NULL(mCbval) ) {
|
||||
JS_BeginRequest(mCx);
|
||||
JS_AddRoot( mCx, &mCbval );
|
||||
JS_AddValueRoot(mCx, &mCbval );
|
||||
JS_EndRequest(mCx);
|
||||
}
|
||||
}
|
||||
|
@ -227,7 +227,7 @@ void nsXPITriggerInfo::SaveCallback( JSContext *aCx, jsval aVal )
|
|||
XPITriggerEvent::~XPITriggerEvent()
|
||||
{
|
||||
JS_BeginRequest(cx);
|
||||
JS_RemoveRoot(cx, &cbval);
|
||||
JS_RemoveValueRoot(cx, &cbval);
|
||||
JS_EndRequest(cx);
|
||||
}
|
||||
|
||||
|
@ -328,7 +328,7 @@ void nsXPITriggerInfo::SendStatus(const PRUnichar* URL, PRInt32 status)
|
|||
|
||||
event->cbval = mCbval;
|
||||
JS_BeginRequest(event->cx);
|
||||
JS_AddNamedRoot(event->cx, &event->cbval,
|
||||
JS_AddNamedValueRoot(event->cx, &event->cbval,
|
||||
"XPITriggerEvent::cbval" );
|
||||
JS_EndRequest(event->cx);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче