зеркало из https://github.com/mozilla/gecko-dev.git
Reworked to use nsIThreadManager::PostEvent() to execute JSObject methods from an arbitrary Java thread.
This commit is contained in:
Родитель
8921d7ff71
Коммит
f56a05205d
|
@ -27,6 +27,7 @@
|
|||
#include "nsILiveconnect.h"
|
||||
#include "nsICapsManager.h"
|
||||
#include "nsISecurityContext.h"
|
||||
#include "nsIPluginInstancePeer2.h"
|
||||
|
||||
#include "MRJPlugin.h"
|
||||
#include "MRJContext.h"
|
||||
|
@ -35,6 +36,7 @@
|
|||
#include "JavaMessageQueue.h"
|
||||
#include "MRJMonitor.h"
|
||||
#include "NativeMonitor.h"
|
||||
#include "RunnableMixin.h"
|
||||
|
||||
#include "netscape_javascript_JSObject.h" /* javah-generated headers */
|
||||
|
||||
|
@ -146,6 +148,20 @@ static jobject NewLocalRef(JNIEnv* env, jobject global_ref)
|
|||
return env->CallStaticObjectMethod(netscape_oji_JNIUtils, netscape_oji_JNIUtils_NewLocalRef, global_ref);
|
||||
}
|
||||
|
||||
static jobject ToGlobalRef(JNIEnv* env, jobject localRef)
|
||||
{
|
||||
jobject globalRef = env->NewGlobalRef(localRef);
|
||||
env->DeleteLocalRef(localRef);
|
||||
return globalRef;
|
||||
}
|
||||
|
||||
static jobject ToLocalRef(JNIEnv* env, jobject globalRef)
|
||||
{
|
||||
jobject localRef = NewLocalRef(env, globalRef);
|
||||
env->DeleteGlobalRef(globalRef);
|
||||
return localRef;
|
||||
}
|
||||
|
||||
static jobject GetCurrentThread(JNIEnv* env)
|
||||
{
|
||||
return env->CallStaticObjectMethod(netscape_oji_JNIUtils, netscape_oji_JNIUtils_GetCurrentThread);
|
||||
|
@ -196,7 +212,13 @@ static jobject GetObjectClassLoader(JNIEnv* env, jobject object)
|
|||
return env->CallStaticObjectMethod(netscape_oji_JNIUtils, netscape_oji_JNIUtils_GetObjectClassLoader, object);
|
||||
}
|
||||
|
||||
static MRJPluginInstance* GetCurrentPlugin(JNIEnv* env)
|
||||
/**
|
||||
* Maps the given JNIEnv to a given plugin instance by comparing the current class loader
|
||||
* with the class loader of the applet of each plugin instance. This could be made
|
||||
* faster, but it's probably good enough. Note: the reference count of the plugin
|
||||
* instance isn't affected by this call.
|
||||
*/
|
||||
static MRJPluginInstance* GetCurrentInstance(JNIEnv* env)
|
||||
{
|
||||
MRJPluginInstance* pluginInstance = NULL;
|
||||
jobject classLoader = GetCurrentClassLoader(env);
|
||||
|
@ -206,14 +228,80 @@ static MRJPluginInstance* GetCurrentPlugin(JNIEnv* env)
|
|||
jobject applet;
|
||||
pluginInstance->GetJavaObject(&applet);
|
||||
jobject appletClassLoader = GetObjectClassLoader(env, applet);
|
||||
if (env->IsSameObject(appletClassLoader, classLoader))
|
||||
jboolean sameClassLoader = env->IsSameObject(appletClassLoader, classLoader);
|
||||
env->DeleteLocalRef(appletClassLoader);
|
||||
if (sameClassLoader)
|
||||
break;
|
||||
pluginInstance = pluginInstance->getNextInstance();
|
||||
}
|
||||
env->DeleteLocalRef(classLoader);
|
||||
}
|
||||
return pluginInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps a JavaMessage in an nsIRunnable form, so that it runs on the correct native thread.
|
||||
*/
|
||||
class MessageRunnable : public JavaMessage, public RunnableMixin {
|
||||
public:
|
||||
MessageRunnable(PRUint32 threadID, JavaMessage* msg);
|
||||
|
||||
virtual void execute(JNIEnv* env);
|
||||
|
||||
NS_IMETHOD Run();
|
||||
|
||||
private:
|
||||
PRUint32 mThreadID;
|
||||
JavaMessage* mMessage;
|
||||
};
|
||||
|
||||
MessageRunnable::MessageRunnable(PRUint32 threadID, JavaMessage* msg)
|
||||
: mThreadID(threadID), mMessage(msg)
|
||||
{
|
||||
}
|
||||
|
||||
void MessageRunnable::execute(JNIEnv* env)
|
||||
{
|
||||
// because a spontaneous Java thread called us, we have to switch to the JavaScript thread
|
||||
// to handle this request.
|
||||
nsIThreadManager* threadManager = NULL;
|
||||
if (theServiceManager->GetService(nsIJVMManager::GetCID(), nsIThreadManager::GetIID(), (nsISupports**)&threadManager) == NS_OK) {
|
||||
threadManager->PostEvent(mThreadID, this, PR_FALSE);
|
||||
theServiceManager->ReleaseService(nsIJVMManager::GetCID(), threadManager);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP MessageRunnable::Run()
|
||||
{
|
||||
nsIJVMManager* javaManager = NULL;
|
||||
if (theServiceManager->GetService(nsIJVMManager::GetCID(), nsIJVMManager::GetIID(), (nsISupports**)&javaManager) == NS_OK) {
|
||||
JNIEnv* proxyEnv = NULL;
|
||||
if (javaManager->GetProxyJNI(&proxyEnv) == NS_OK && proxyEnv != NULL)
|
||||
mMessage->execute(proxyEnv);
|
||||
theServiceManager->ReleaseService(nsIJVMManager::GetCID(), javaManager);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRUint32 getJavaScriptThread(JNIEnv* env)
|
||||
{
|
||||
PRUint32 threadID = 0;
|
||||
MRJPluginInstance* pluginInstance = GetCurrentInstance(env);
|
||||
if (pluginInstance != NULL) {
|
||||
nsIPluginInstancePeer* peer;
|
||||
if (pluginInstance->GetPeer(&peer) == NS_OK) {
|
||||
nsIPluginInstancePeer2* peer2 = NULL;
|
||||
if (peer->QueryInterface(nsIPluginInstancePeer2::GetIID(), &peer2) == NS_OK) {
|
||||
if (peer2->GetJSThread(&threadID) != NS_OK)
|
||||
threadID = 0;
|
||||
NS_RELEASE(peer2);
|
||||
}
|
||||
NS_RELEASE(peer);
|
||||
}
|
||||
}
|
||||
return threadID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a message by rendezvousing with an existing JavaScript thread, or creates a new one
|
||||
* if none exists for this thread already.
|
||||
|
@ -251,7 +339,20 @@ static void sendMessage(JNIEnv* env, JavaMessage* msg)
|
|||
sharedEnv->AddRef();
|
||||
}
|
||||
sharedEnv->setJavaEnv(env);
|
||||
sharedEnv->sendMessageFromJava(env, msg);
|
||||
|
||||
// In the current Seamonkey architecture, there's really only one thread that JavaScript
|
||||
// can execute in. We take advantage of that fact here. When we have a more multithreaded
|
||||
// system, this will have to be revisited.
|
||||
static PRUint32 theJavaScriptThread = getJavaScriptThread(env);
|
||||
|
||||
// if the JavaScript thread is known, wrap the message in a MessageRunnable to handle
|
||||
// the message in the JavaScript thread.
|
||||
if (theJavaScriptThread != 0) {
|
||||
MessageRunnable* runnableMsg = new MessageRunnable(theJavaScriptThread, msg);
|
||||
NS_ADDREF(runnableMsg);
|
||||
sharedEnv->sendMessageFromJava(env, runnableMsg);
|
||||
NS_IF_RELEASE(runnableMsg);
|
||||
}
|
||||
}
|
||||
sharedMonitor.exit();
|
||||
}
|
||||
|
@ -277,6 +378,29 @@ static nsIPrincipal* newCodebasePrincipal(const char* codebaseURL)
|
|||
* Method: getMember
|
||||
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
|
||||
*/
|
||||
|
||||
class GetMemberMessage : public JavaMessage {
|
||||
jsobject mObject;
|
||||
const jchar* mPropertyName;
|
||||
jsize mLength;
|
||||
jobject* mResultObject;
|
||||
public:
|
||||
GetMemberMessage(jsobject js_obj, const jchar* propertyName, jsize nameLength, jobject* member)
|
||||
: mObject(js_obj), mPropertyName(propertyName), mLength(nameLength), mResultObject(member)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(JNIEnv* env)
|
||||
{
|
||||
jobject member;
|
||||
nsresult result = theLiveConnectManager->GetMember(env, mObject, mPropertyName, mLength, NULL, 0, NULL, &member);
|
||||
if (result == NS_OK) {
|
||||
// convert reference to a global reference, in case we're switching threads.
|
||||
*mResultObject = ToGlobalRef(env, member);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_netscape_javascript_JSObject_getMember(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
|
@ -292,10 +416,15 @@ Java_netscape_javascript_JSObject_getMember(JNIEnv* env,
|
|||
const jchar* property_name_ucs2 = env->GetStringChars(property_name_jstr, &is_copy);
|
||||
jsize property_name_len = env->GetStringLength(property_name_jstr);
|
||||
|
||||
jsobject js_obj = Unwrap_JSObject(env, java_wrapper_obj);
|
||||
jobject member = NULL;
|
||||
nsresult result = theLiveConnectManager->GetMember(env, Unwrap_JSObject(env, java_wrapper_obj), property_name_ucs2, property_name_len,
|
||||
NULL, 0, NULL, &member);
|
||||
if (result != NS_OK) member = NULL;
|
||||
GetMemberMessage msg(js_obj, property_name_ucs2, property_name_len, &member);
|
||||
|
||||
sendMessage(env, &msg);
|
||||
|
||||
// convert the resulting reference back to a local reference.
|
||||
if (member != NULL)
|
||||
member = ToLocalRef(env, member);
|
||||
|
||||
env->ReleaseStringChars(property_name_jstr, property_name_ucs2);
|
||||
|
||||
|
@ -307,13 +436,40 @@ Java_netscape_javascript_JSObject_getMember(JNIEnv* env,
|
|||
* Method: getSlot
|
||||
* Signature: (I)Ljava/lang/Object;
|
||||
*/
|
||||
|
||||
class GetSlotMessage : public JavaMessage {
|
||||
jsobject mObject;
|
||||
jint mSlot;
|
||||
jobject* mResultObject;
|
||||
public:
|
||||
GetSlotMessage(jsobject js_obj, jint slot, jobject* member)
|
||||
: mObject(js_obj), mSlot(slot), mResultObject(member)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(JNIEnv* env)
|
||||
{
|
||||
jobject member;
|
||||
nsresult result = theLiveConnectManager->GetSlot(env, mObject, mSlot, NULL, 0, NULL, &member);
|
||||
if (result == NS_OK) {
|
||||
// convert reference to a global reference, in case we're switching threads.
|
||||
*mResultObject = ToGlobalRef(env, member);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_netscape_javascript_JSObject_getSlot(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
jint slot)
|
||||
{
|
||||
jsobject js_obj = Unwrap_JSObject(env, java_wrapper_obj);
|
||||
jobject member = NULL;
|
||||
nsresult result = theLiveConnectManager->GetSlot(env, Unwrap_JSObject(env, java_wrapper_obj), slot, NULL, 0, NULL, &member);
|
||||
GetSlotMessage msg(js_obj, slot, &member);
|
||||
sendMessage(env, &msg);
|
||||
// convert the resulting reference back to a local reference.
|
||||
if (member != NULL)
|
||||
member = ToLocalRef(env, member);
|
||||
return member;
|
||||
}
|
||||
|
||||
|
@ -322,6 +478,24 @@ Java_netscape_javascript_JSObject_getSlot(JNIEnv* env,
|
|||
* Method: setMember
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/Object;)V
|
||||
*/
|
||||
|
||||
class SetMemberMessage : public JavaMessage {
|
||||
jsobject mObject;
|
||||
const jchar* mPropertyName;
|
||||
jsize mLength;
|
||||
jobject mJavaObject;
|
||||
public:
|
||||
SetMemberMessage(jsobject js_obj, const jchar* propertyName, jsize nameLength, jobject java_obj)
|
||||
: mObject(js_obj), mPropertyName(propertyName), mLength(nameLength), mJavaObject(java_obj)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(JNIEnv* env)
|
||||
{
|
||||
nsresult result = theLiveConnectManager->SetMember(env, mObject, mPropertyName, mLength, NULL, 0, NULL, mJavaObject);
|
||||
}
|
||||
};
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_netscape_javascript_JSObject_setMember(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
|
@ -337,11 +511,14 @@ Java_netscape_javascript_JSObject_setMember(JNIEnv* env,
|
|||
jboolean is_copy;
|
||||
const jchar* property_name_ucs2 = env->GetStringChars(property_name_jstr, &is_copy);
|
||||
jsize property_name_len = env->GetStringLength(property_name_jstr);
|
||||
|
||||
jobject member = NULL;
|
||||
nsresult result = theLiveConnectManager->SetMember(env, Unwrap_JSObject(env, java_wrapper_obj), property_name_ucs2, property_name_len, NULL, 0, NULL, java_obj);
|
||||
if (result != NS_OK) member = NULL;
|
||||
|
||||
jsobject js_obj = Unwrap_JSObject(env, java_wrapper_obj);
|
||||
java_obj = ToGlobalRef(env, java_obj);
|
||||
SetMemberMessage msg(js_obj, property_name_ucs2, property_name_len, java_obj);
|
||||
|
||||
sendMessage(env, &msg);
|
||||
|
||||
env->DeleteGlobalRef(java_obj);
|
||||
env->ReleaseStringChars(property_name_jstr, property_name_ucs2);
|
||||
}
|
||||
|
||||
|
@ -350,13 +527,34 @@ Java_netscape_javascript_JSObject_setMember(JNIEnv* env,
|
|||
* Method: setSlot
|
||||
* Signature: (ILjava/lang/Object;)V
|
||||
*/
|
||||
|
||||
class SetSlotMessage : public JavaMessage {
|
||||
jsobject mObject;
|
||||
jint mSlot;
|
||||
jobject mJavaObject;
|
||||
public:
|
||||
SetSlotMessage(jsobject js_obj, jint slot, jobject java_obj)
|
||||
: mObject(js_obj), mSlot(slot), mJavaObject(java_obj)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(JNIEnv* env)
|
||||
{
|
||||
nsresult result = theLiveConnectManager->SetSlot(env, mObject, mSlot, NULL, 0, NULL, mJavaObject);
|
||||
}
|
||||
};
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_netscape_javascript_JSObject_setSlot(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
jint slot,
|
||||
jobject java_obj)
|
||||
{
|
||||
nsresult result = theLiveConnectManager->SetSlot(env, Unwrap_JSObject(env, java_wrapper_obj), slot, NULL, 0, NULL, java_obj);
|
||||
jsobject js_obj = Unwrap_JSObject(env, java_wrapper_obj);
|
||||
java_obj = ToGlobalRef(env, java_obj);
|
||||
SetSlotMessage msg(js_obj, slot, java_obj);
|
||||
sendMessage(env, &msg);
|
||||
env->DeleteGlobalRef(java_obj);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -370,21 +568,17 @@ class RemoveMemberMessage : public JavaMessage {
|
|||
const jchar* mPropertyName;
|
||||
jsize mLength;
|
||||
public:
|
||||
RemoveMemberMessage(jsobject obj, const jchar* propertyName, jsize length);
|
||||
RemoveMemberMessage(jsobject obj, const jchar* propertyName, jsize length)
|
||||
: mObject(obj), mPropertyName(propertyName), mLength(length)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(JNIEnv* env);
|
||||
virtual void execute(JNIEnv* env)
|
||||
{
|
||||
nsresult result = theLiveConnectManager->RemoveMember(env, mObject, mPropertyName, mLength, NULL, 0, NULL);
|
||||
}
|
||||
};
|
||||
|
||||
RemoveMemberMessage::RemoveMemberMessage(jsobject obj, const jchar* propertyName, jsize length)
|
||||
: mObject(obj), mPropertyName(propertyName), mLength(length)
|
||||
{
|
||||
}
|
||||
|
||||
void RemoveMemberMessage::execute(JNIEnv* env)
|
||||
{
|
||||
nsresult result = theLiveConnectManager->RemoveMember(env, mObject, mPropertyName, mLength, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_netscape_javascript_JSObject_removeMember(JNIEnv* env,
|
||||
jobject java_wrapper_obj,
|
||||
|
@ -402,6 +596,7 @@ Java_netscape_javascript_JSObject_removeMember(JNIEnv* env,
|
|||
|
||||
jsobject js_obj = Unwrap_JSObject(env, java_wrapper_obj);
|
||||
RemoveMemberMessage msg(js_obj, property_name_ucs2, property_name_len);
|
||||
|
||||
sendMessage(env, &msg);
|
||||
|
||||
env->ReleaseStringChars(property_name_jstr, property_name_ucs2);
|
||||
|
@ -415,30 +610,29 @@ class CallMessage : public JavaMessage {
|
|||
jobject* mJavaResult;
|
||||
const char* mCodebaseURL;
|
||||
public:
|
||||
CallMessage(jsobject obj, const jchar* functionName, jsize length, jobjectArray java_args, jobject* javaResult, const char* codebaseURL);
|
||||
|
||||
virtual void execute(JNIEnv* env);
|
||||
};
|
||||
|
||||
CallMessage::CallMessage(jsobject obj, const jchar* functionName, jsize length, jobjectArray javaArgs, jobject* javaResult, const char* codebaseURL)
|
||||
: mObject(obj), mFunctionName(functionName), mLength(length),
|
||||
mJavaArgs(javaArgs), mJavaResult(javaResult), mCodebaseURL(codebaseURL)
|
||||
{
|
||||
}
|
||||
|
||||
void CallMessage::execute(JNIEnv* env)
|
||||
{
|
||||
/* If we have an applet, try to create a codebase principle. */
|
||||
nsIPrincipal* principal = NULL;
|
||||
nsISecurityContext* context = NULL;
|
||||
if (mCodebaseURL != NULL) {
|
||||
principal = newCodebasePrincipal(mCodebaseURL);
|
||||
context = newSecurityContext();
|
||||
CallMessage(jsobject obj, const jchar* functionName, jsize length, jobjectArray javaArgs, jobject* javaResult, const char* codebaseURL)
|
||||
: mObject(obj), mFunctionName(functionName), mLength(length),
|
||||
mJavaArgs(javaArgs), mJavaResult(javaResult), mCodebaseURL(codebaseURL)
|
||||
{
|
||||
}
|
||||
nsresult status = theLiveConnectManager->Call(env, mObject, mFunctionName, mLength, mJavaArgs, &principal, (principal != NULL ? 1 : 0), context, mJavaResult);
|
||||
NS_IF_RELEASE(principal);
|
||||
NS_IF_RELEASE(context);
|
||||
}
|
||||
|
||||
virtual void execute(JNIEnv* env)
|
||||
{
|
||||
/* If we have an applet, try to create a codebase principle. */
|
||||
nsIPrincipal* principal = NULL;
|
||||
nsISecurityContext* context = NULL;
|
||||
if (mCodebaseURL != NULL) {
|
||||
principal = newCodebasePrincipal(mCodebaseURL);
|
||||
context = newSecurityContext();
|
||||
}
|
||||
jobject jresult = NULL;
|
||||
nsresult result = theLiveConnectManager->Call(env, mObject, mFunctionName, mLength, mJavaArgs, &principal, (principal != NULL ? 1 : 0), context, &jresult);
|
||||
NS_IF_RELEASE(principal);
|
||||
NS_IF_RELEASE(context);
|
||||
if (result == NS_OK)
|
||||
*mJavaResult = ToGlobalRef(env, jresult);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
|
@ -456,7 +650,7 @@ Java_netscape_javascript_JSObject_call(JNIEnv* env, jobject java_wrapper_obj,
|
|||
|
||||
/* Try to determine which plugin instance is responsible for this thread. This is done by checking class loaders. */
|
||||
const char* codebaseURL = NULL;
|
||||
MRJPluginInstance* pluginInstance = GetCurrentPlugin(env);
|
||||
MRJPluginInstance* pluginInstance = GetCurrentInstance(env);
|
||||
if (pluginInstance != NULL)
|
||||
codebaseURL = pluginInstance->getContext()->getDocumentBase();
|
||||
|
||||
|
@ -474,31 +668,12 @@ Java_netscape_javascript_JSObject_call(JNIEnv* env, jobject java_wrapper_obj,
|
|||
|
||||
env->ReleaseStringChars(function_name_jstr, function_name_ucs2);
|
||||
|
||||
if (jresult != NULL)
|
||||
jresult = ToLocalRef(env, jresult);
|
||||
|
||||
return jresult;
|
||||
}
|
||||
|
||||
class EvalMessage : public JavaMessage {
|
||||
JNIEnv* mEnv;
|
||||
jsobject mObject;
|
||||
const jchar* mScript;
|
||||
jsize mLength;
|
||||
jobject* mJavaResult;
|
||||
public:
|
||||
EvalMessage(jsobject obj, const jchar* script, jsize length, jobject* javaResult);
|
||||
|
||||
virtual void execute(JNIEnv* env);
|
||||
};
|
||||
|
||||
EvalMessage::EvalMessage(jsobject obj, const jchar* script, jsize length, jobject* javaResult)
|
||||
: mObject(obj), mScript(script), mLength(length), mJavaResult(javaResult)
|
||||
{
|
||||
}
|
||||
|
||||
void EvalMessage::execute(JNIEnv* env)
|
||||
{
|
||||
nsresult status = theLiveConnectManager->Eval(env, mObject, mScript, mLength, NULL, 0, NULL, mJavaResult);
|
||||
}
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: eval
|
||||
|
@ -525,8 +700,32 @@ Java_netscape_javascript_JSObject_eval(JNIEnv* env,
|
|||
#ifdef MRJPLUGIN_4X
|
||||
nsresult status = theLiveConnectManager->Eval(env, js_obj, script_ucs2, script_len, NULL, 0, NULL, &jresult);
|
||||
#else
|
||||
class EvalMessage : public JavaMessage {
|
||||
JNIEnv* mEnv;
|
||||
jsobject mObject;
|
||||
const jchar* mScript;
|
||||
jsize mLength;
|
||||
jobject* mJavaResult;
|
||||
public:
|
||||
EvalMessage(jsobject obj, const jchar* script, jsize length, jobject* javaResult)
|
||||
: mObject(obj), mScript(script), mLength(length), mJavaResult(javaResult)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(JNIEnv* env)
|
||||
{
|
||||
jobject jresult = NULL;
|
||||
nsresult result = theLiveConnectManager->Eval(env, mObject, mScript, mLength, NULL, 0, NULL, &jresult);
|
||||
if (result == NS_OK && jresult != NULL) {
|
||||
*mJavaResult = ToGlobalRef(env, jresult);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/* determine the plugin instance so we can obtain its codebase. */
|
||||
MRJPluginInstance* pluginInstance = theJVMPlugin->getPluginInstance(env);
|
||||
// beard: should file a bug with Apple that JMJNIToAWTContext doesn't work.
|
||||
// MRJPluginInstance* pluginInstance = theJVMPlugin->getPluginInstance(env);
|
||||
MRJPluginInstance* pluginInstance = GetCurrentInstance(env);
|
||||
if (pluginInstance == NULL) {
|
||||
env->ThrowNew(env->FindClass("java/lang/NullPointerException"), "illegal JNIEnv (can't find plugin)");
|
||||
return NULL;
|
||||
|
@ -534,9 +733,10 @@ Java_netscape_javascript_JSObject_eval(JNIEnv* env,
|
|||
|
||||
EvalMessage msg(js_obj, script_ucs2, script_len, &jresult);
|
||||
sendMessage(env, &msg);
|
||||
|
||||
// Make sure it gets released!
|
||||
pluginInstance->Release();
|
||||
|
||||
if (jresult != NULL)
|
||||
jresult = ToLocalRef(env, jresult);
|
||||
|
||||
#endif
|
||||
|
||||
env->ReleaseStringChars(script_jstr, script_ucs2);
|
||||
|
@ -572,6 +772,7 @@ Java_netscape_javascript_JSObject_toString(JNIEnv* env, jobject java_wrapper_obj
|
|||
} msg(js_obj, &jresult);
|
||||
|
||||
sendMessage(env, &msg);
|
||||
|
||||
return jresult;
|
||||
}
|
||||
|
||||
|
@ -581,25 +782,6 @@ Java_netscape_javascript_JSObject_toString(JNIEnv* env, jobject java_wrapper_obj
|
|||
* Signature: (Ljava/applet/Applet;)Lnetscape/javascript/JSObject;
|
||||
*/
|
||||
|
||||
class GetWindowMessage : public JavaMessage {
|
||||
nsIPluginInstance* mPluginInstance;
|
||||
jsobject* mWindowResult;
|
||||
public:
|
||||
GetWindowMessage(nsIPluginInstance* pluginInstance, jsobject* windowResult);
|
||||
|
||||
virtual void execute(JNIEnv* env);
|
||||
};
|
||||
|
||||
GetWindowMessage::GetWindowMessage(nsIPluginInstance* pluginInstance, jsobject* windowResult)
|
||||
: mPluginInstance(pluginInstance), mWindowResult(windowResult)
|
||||
{
|
||||
}
|
||||
|
||||
void GetWindowMessage::execute(JNIEnv* env)
|
||||
{
|
||||
nsresult status = theLiveConnectManager->GetWindow(env,mPluginInstance, NULL, 0, NULL, mWindowResult);
|
||||
}
|
||||
|
||||
JNIEXPORT jobject JNICALL
|
||||
Java_netscape_javascript_JSObject_getWindow(JNIEnv* env,
|
||||
jclass js_object_class,
|
||||
|
@ -612,6 +794,21 @@ Java_netscape_javascript_JSObject_getWindow(JNIEnv* env,
|
|||
jobject jwindow = Wrap_JSObject(env, jsobject(pluginInstance));
|
||||
return jwindow;
|
||||
#else
|
||||
class GetWindowMessage : public JavaMessage {
|
||||
nsIPluginInstance* mPluginInstance;
|
||||
jsobject* mWindowResult;
|
||||
public:
|
||||
GetWindowMessage(nsIPluginInstance* pluginInstance, jsobject* windowResult)
|
||||
: mPluginInstance(pluginInstance), mWindowResult(windowResult)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void execute(JNIEnv* env)
|
||||
{
|
||||
nsresult status = theLiveConnectManager->GetWindow(env,mPluginInstance, NULL, 0, NULL, mWindowResult);
|
||||
}
|
||||
};
|
||||
|
||||
jsobject jswindow = NULL;
|
||||
GetWindowMessage msg(pluginInstance, &jswindow);
|
||||
sendMessage(env, &msg);
|
||||
|
@ -651,6 +848,7 @@ Java_netscape_javascript_JSObject_finalize(JNIEnv* env, jobject java_wrapper_obj
|
|||
nsresult result = theLiveConnectManager->FinalizeJSObject(env, m_jsobj);
|
||||
}
|
||||
};
|
||||
|
||||
FinalizeMessage msg(jsobj);
|
||||
sendMessage(env, &msg);
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче