Fixes issue #1281; linux hosted mode was crashing sometimes during
JS_SetReservedSlot(). There might have also been an unrelated issue with
storing stale JSContext*'s inside of JsRootedValues.
- Keeps a static stack of JSContext*'s instead of storing them; this is
safe to do because the JS engine is always higher on the call stack than
any client-side Java code (including gwtOnLoad).
- Protects newborns that could sometimes be insta-gc'd within
JsValueMoz._setWrappedJavaObject() and _setWrappedFunction().
- Reorganized some functions into more appropriate cpp files.
Patch by: jat, scottb
Review by: scottb, jat :)
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1268 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/jni/linux/ExternalWrapper.cpp b/jni/linux/ExternalWrapper.cpp
index eff2802..d13d8b1 100644
--- a/jni/linux/ExternalWrapper.cpp
+++ b/jni/linux/ExternalWrapper.cpp
@@ -41,6 +41,7 @@
{
Tracer tracer("gwtOnLoad");
tracer.log("context=%08x", unsigned(cx));
+ JsRootedValue::ContextManager context(cx);
JsRootedValue::ensureRuntime(cx);
if (argc < 2) {
tracer.setFail("less than 2 args");
@@ -120,6 +121,7 @@
JSObject *obj, jsval id, jsval *vp)
{
Tracer tracer("gwt_external_getProperty");
+ JsRootedValue::ContextManager context(cx);
if (*vp != JSVAL_VOID)
return JS_TRUE;
@@ -166,10 +168,13 @@
static void JS_DLL_CALLBACK gwt_external_finalize(JSContext *cx, JSObject *obj)
{
+ // We don't need to push a context if all we do is DeleteGlobalRef
+ Tracer tracer("gwt_external_finalize", obj);
jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj));
- if (externalObject)
+ if (externalObject) {
savedJNIEnv->DeleteGlobalRef(externalObject);
- JS_FinalizeStub(cx,obj);
+ }
+ JS_FinalizeStub(cx, obj);
}
static JSBool JS_DLL_CALLBACK gwt_external_setProperty(JSContext *cx,
@@ -201,7 +206,14 @@
tracer.setFail("null script object pointer");
return NS_ERROR_INVALID_POINTER;
}
- if (!mScriptObject) {
+ if (!jsWindowExternalObject) {
+ JSContext* cx = NS_REINTERPRET_CAST(JSContext*,
+ aContext->GetNativeContext());
+ if (!cx) {
+ tracer.setFail("can't get JSContext");
+ return NS_ERROR_UNEXPECTED;
+ }
+ JsRootedValue::ContextManager context(cx);
*aScriptObject = 0;
nsIScriptGlobalObject* globalObject = aContext->GetGlobalObject();
@@ -239,12 +251,6 @@
tracer.setFail("can't get GlobalRef for external object");
return NS_ERROR_UNEXPECTED;
}
- JSContext* cx = NS_REINTERPRET_CAST(JSContext*,
- aContext->GetNativeContext());
- if (!cx) {
- tracer.setFail("can't get JSContext");
- return NS_ERROR_UNEXPECTED;
- }
JSObject* newObj = JS_NewObject(cx, &gwt_external_class, 0,
globalObject->GetGlobalJSObject());
if (!newObj) {
@@ -262,16 +268,16 @@
tracer.setFail("can't define gwtOnLoad function on JavaScript object");
return NS_ERROR_UNEXPECTED;
}
- mScriptObject = newObj;
+ jsWindowExternalObject = newObj;
}
- *aScriptObject = mScriptObject;
+ *aScriptObject = jsWindowExternalObject;
return NS_OK;
}
NS_IMETHODIMP ExternalWrapper::SetScriptObject(void* aScriptObject)
{
- mScriptObject = aScriptObject;
+ jsWindowExternalObject = aScriptObject;
return NS_OK;
}