changeset in /hg/icedtea6: Updates to NP plugin.
Deepak Bhole
dbhole at redhat.com
Thu Aug 6 07:40:54 PDT 2009
changeset b775cb0d0900 in /hg/icedtea6
details: http://icedtea.classpath.org/hg/icedtea6?cmd=changeset;node=b775cb0d0900
description:
Updates to NP plugin.
- Plugin request processor threads now use condition based wait rather than
periodic polling
- Added support for fetching field information and values, and method
invocation from JS -> Java
- Added support for static calls (e.g. System.out.println(...)) from JS
- Implented a cost-based overloaded method resolver for when JS calls an
overloaded Java method with ambiguous types.
diffstat:
14 files changed, 2098 insertions(+), 287 deletions(-)
ChangeLog | 27
plugin/icedteanp/IcedTeaJavaRequestProcessor.cc | 640 +++++++++-
plugin/icedteanp/IcedTeaJavaRequestProcessor.h | 68 +
plugin/icedteanp/IcedTeaNPPlugin.cc | 173 +-
plugin/icedteanp/IcedTeaNPPlugin.h | 8
plugin/icedteanp/IcedTeaPluginRequestProcessor.cc | 28
plugin/icedteanp/IcedTeaPluginRequestProcessor.h | 4
plugin/icedteanp/IcedTeaPluginUtils.cc | 10
plugin/icedteanp/IcedTeaPluginUtils.h | 9
plugin/icedteanp/IcedTeaRunnable.h | 2
plugin/icedteanp/IcedTeaScriptablePluginObject.cc | 550 ++++++++
plugin/icedteanp/IcedTeaScriptablePluginObject.h | 104 +
plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java | 480 +++++++
plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java | 282 ++--
diffs (truncated from 3026 to 500 lines):
diff -r 8a0ea636a6e5 -r b775cb0d0900 ChangeLog
--- a/ChangeLog Wed Aug 05 20:43:00 2009 +0200
+++ b/ChangeLog Thu Aug 06 10:43:31 2009 -0400
@@ -1,3 +1,30 @@ 2009-08-05 Mark Wielaard <mjw at redhat.c
+2009-08-06 Deepak Bhole <dbhole at redhat.com>
+
+ * plugin/icedteanp/IcedTeaJavaRequestProcessor.cc: Handle error messages
+ from Java side. Add referencing/de-referencing support, and support for
+ fetching fields, invoking methods, and returning applet instances.
+ * plugin/icedteanp/IcedTeaJavaRequestProcessor.h: Decrease timeout to 20
+ seconds. Declare new functions created in the associated .cc file.
+ * plugin/icedteanp/IcedTeaNPPlugin.cc: Add support for dynamic NPObject
+ creation per instance. Add a new global pthread_cond_t for message
+ availability.
+ * plugin/icedteanp/IcedTeaNPPlugin.h: Misc. changes related to the above
+ associated file.
+ * plugin/icedteanp/IcedTeaPluginRequestProcessor.cc: Use condition based
+ wait for message availability, rather than periodic poll.
+ * plugin/icedteanp/IcedTeaPluginRequestProcessor.h: Make
+ getInstanceFromMemberPtr and storeInstanceID global.
+ * plugin/icedteanp/IcedTeaPluginUtils.cc: Force use of file:// src until
+ security subsystem is implemented.
+ * plugin/icedteanp/IcedTeaScriptablePluginObject.cc: Created skeletons for
+ Java and JavaPackage NPObjects, and implemented hasProperty, hasMethod,
+ getProperty and getMethod.
+ * plugin/icedteanp/IcedTeaScriptablePluginObject.h: Appropriate header
+ changes associated with the above.
+ * plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java: New file.
+ Uses a cost-based approach to resolve overloaded methods when JavaScript
+ calls Java methods with potentially ambiguous type arguments.
+
2009-08-05 Mark Wielaard <mjw at redhat.com>
* patches/icedtea-systemtap.patch: Remove workaround for nmethod.cpp.
diff -r 8a0ea636a6e5 -r b775cb0d0900 plugin/icedteanp/IcedTeaJavaRequestProcessor.cc
--- a/plugin/icedteanp/IcedTeaJavaRequestProcessor.cc Wed Aug 05 20:43:00 2009 +0200
+++ b/plugin/icedteanp/IcedTeaJavaRequestProcessor.cc Thu Aug 06 10:43:31 2009 -0400
@@ -66,9 +66,22 @@ JavaRequestProcessor::newMessageOnBus(co
{
// Gather the results
- // GetStringUTFChars
- if (message_parts->at(4) == "GetStringUTFChars" ||
- message_parts->at(4) == "GetToStringValue")
+ // Let's get errors out of the way first
+ if (message_parts->at(4) == "Error")
+ {
+ for (int i=5; i < message_parts->size(); i++)
+ {
+ result->error_msg->append(message_parts->at(i));
+ result->error_msg->append(" ");
+ }
+
+ printf("Error on Java side: %s\n", result->error_msg->c_str());
+
+ result->error_occurred = true;
+ result_ready = true;
+ }
+ else if (message_parts->at(4) == "GetStringUTFChars" ||
+ message_parts->at(4) == "GetToStringValue")
{
// first item is length, and it is radix 10
int length = strtol(message_parts->at(5).c_str(), NULL, 10);
@@ -83,30 +96,49 @@ JavaRequestProcessor::newMessageOnBus(co
IcedTeaPluginUtilities::getUTF16LEString(length, 6 /* start at */, message_parts, result->return_wstring);
result_ready = true;
- } else if (message_parts->at(4) == "FindClass")
+ } else if ((message_parts->at(4) == "FindClass") ||
+ (message_parts->at(4) == "GetClassName") ||
+ (message_parts->at(4) == "GetClassID") ||
+ (message_parts->at(4) == "GetMethodID") ||
+ (message_parts->at(4) == "GetStaticMethodID") ||
+ (message_parts->at(4) == "GetObjectClass") ||
+ (message_parts->at(4) == "NewObject") ||
+ (message_parts->at(4) == "NewStringUTF") ||
+ (message_parts->at(4) == "HasPackage") ||
+ (message_parts->at(4) == "HasMethod") ||
+ (message_parts->at(4) == "HasField") ||
+ (message_parts->at(4) == "GetStaticFieldID") ||
+ (message_parts->at(4) == "GetFieldID") ||
+ (message_parts->at(4) == "GetField") ||
+ (message_parts->at(4) == "GetStaticField") ||
+ (message_parts->at(4) == "GetJavaObject"))
{
result->return_identifier = atoi(message_parts->at(5).c_str());
result->return_string->append(message_parts->at(5)); // store it as a string as well, for easy access
result_ready = true;
- } else if (message_parts->at(4) == "GetClassName")
+ } else if ((message_parts->at(4) == "DeleteLocalRef") ||
+ (message_parts->at(4) == "NewGlobalRef"))
{
- result->return_identifier = atoi(message_parts->at(5).c_str());
- result->return_string->append(message_parts->at(5)); // store it as a string as well, for easy access
- result_ready = true;
- } else if (message_parts->at(4) == "GetMethodID")
+ result_ready = true; // nothing else to do
+ } else if ((message_parts->at(4) == "CallMethod") ||
+
+ (message_parts->at(4) == "CallStaticMethod"))
{
- result->return_identifier = atoi(message_parts->at(5).c_str());
- result->return_string->append(message_parts->at(5)); // store it as a string as well, for easy access
- result_ready = true;
- } else if (message_parts->at(4) == "NewObject")
- {
- result->return_identifier = atoi(message_parts->at(5).c_str());
- result->return_string->append(message_parts->at(5)); // store it as a string as well, for easy access
- result_ready = true;
- } else if (message_parts->at(4) == "NewStringUTF")
- {
- result->return_identifier = atoi(message_parts->at(5).c_str());
- result->return_string->append(message_parts->at(5)); // store it as a string as well, for easy access
+
+ if (message_parts->at(5) == "literalreturn")
+ {
+ // literal returns don't have a corresponding jni id
+ result->return_identifier = 0;
+ result->return_string->append(message_parts->at(6));
+
+ } else
+ {
+ // Else it is a complex object
+
+ result->return_identifier = atoi(message_parts->at(5).c_str());
+ result->return_string->append(message_parts->at(5)); // store it as a string as well, for easy access
+ }
+
result_ready = true;
}
@@ -130,9 +162,10 @@ JavaRequestProcessor::JavaRequestProcess
// caller frees this
result = new JavaResultData();
result->error_msg = new std::string();
+ result->return_identifier = 0;
result->return_string = new std::string();
result->return_wstring = new std::wstring();
- result->error_occured = false;
+ result->error_occurred = false;
result_ready = false;
}
@@ -162,6 +195,22 @@ JavaRequestProcessor::~JavaRequestProces
}
}
+/**
+ * Resets the results
+ */
+void
+JavaRequestProcessor::resetResult()
+{
+ // caller frees this
+ result->error_msg->clear();
+ result->return_identifier = 0;
+ result->return_string->clear();
+ result->return_wstring->clear();
+ result->error_occurred = false;
+
+ result_ready = false;
+}
+
void
JavaRequestProcessor::postAndWaitForResponse(std::string* message)
{
@@ -179,10 +228,14 @@ JavaRequestProcessor::postAndWaitForResp
do
{
clock_gettime(CLOCK_REALTIME, &curr_t);
- bool timedout = false;
if (!result_ready && (curr_t.tv_sec < t.tv_sec))
- usleep(2000);
+ {
+ if (g_main_context_pending(NULL))
+ g_main_context_iteration(NULL, false);
+ else
+ usleep(2000);
+ }
else
break;
@@ -190,6 +243,9 @@ JavaRequestProcessor::postAndWaitForResp
if (curr_t.tv_sec >= t.tv_sec)
{
+ result->error_occurred = true;
+ result->error_msg->append("Error: Timed out when waiting for response");
+
// Report error
PLUGIN_DEBUG_1ARG("Error: Timed out when waiting for response to %s\n", message->c_str());
}
@@ -253,6 +309,57 @@ JavaRequestProcessor::getString(std::str
return result;
}
+/**
+ * Decrements reference count by 1
+ *
+ * @param object_id The ID of the object
+ */
+
+void
+JavaRequestProcessor::deleteReference(std::string object_id)
+{
+ std::string* message;
+
+ this->instance = 0; // context is always 0 (needed for java-side backwards compat.)
+ this->reference = IcedTeaPluginUtilities::getReference();
+
+ message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference);
+
+ message->append(" DeleteLocalRef ");
+ message->append(object_id);
+
+ postAndWaitForResponse(message);
+
+ IcedTeaPluginUtilities::releaseReference();
+ delete message;
+}
+
+/**
+ * Increments reference count by 1
+ *
+ * @param object_id The ID of the object
+ */
+
+void
+JavaRequestProcessor::addReference(std::string object_id)
+{
+ std::string* message;
+
+ this->instance = 0; // context is always 0 (needed for java-side backwards compat.)
+ this->reference = IcedTeaPluginUtilities::getReference();
+
+ message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference);
+
+ message->append(" NewGlobalRef ");
+ message->append(object_id);
+
+ postAndWaitForResponse(message);
+
+ IcedTeaPluginUtilities::releaseReference();
+ delete message;
+
+}
+
JavaResultData*
JavaRequestProcessor::findClass(std::string name)
{
@@ -274,7 +381,7 @@ JavaRequestProcessor::findClass(std::str
}
JavaResultData*
-JavaRequestProcessor::getClassName(std::string ID)
+JavaRequestProcessor::getClassName(std::string objectID)
{
std::string* message;
@@ -284,7 +391,7 @@ JavaRequestProcessor::getClassName(std::
message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference);
message->append(" GetClassName ");
- message->append(ID);
+ message->append(objectID);
postAndWaitForResponse(message);
@@ -294,7 +401,139 @@ JavaRequestProcessor::getClassName(std::
}
JavaResultData*
-JavaRequestProcessor::getMethodID(std::string objectID, NPIdentifier methodName,
+JavaRequestProcessor::getClassID(std::string objectID)
+{
+ std::string* message;
+
+ this->instance = 0; // context is always 0 (needed for java-side backwards compat.)
+ this->reference = IcedTeaPluginUtilities::getReference();
+
+ message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference);
+
+ message->append(" GetClassID ");
+ message->append(objectID);
+
+ postAndWaitForResponse(message);
+
+ delete message;
+
+ return result;
+}
+
+JavaResultData*
+JavaRequestProcessor::getFieldID(std::string classID, std::string fieldName)
+{
+ JavaResultData* java_result;
+ JavaRequestProcessor* java_request = new JavaRequestProcessor();
+ std::string* message;
+
+ java_result = java_request->newString(fieldName);
+
+ this->instance = 0; // context is always 0 (needed for java-side backwards compat.)
+ this->reference = IcedTeaPluginUtilities::getReference();
+
+ message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference);
+ message->append(" GetFieldID ");
+ message->append(classID);
+ message->append(" ");
+ message->append(java_result->return_string->c_str());
+
+ postAndWaitForResponse(message);
+
+ IcedTeaPluginUtilities::releaseReference();
+
+ delete java_request;
+ delete message;
+
+ return result;
+}
+
+JavaResultData*
+JavaRequestProcessor::getStaticFieldID(std::string classID, std::string fieldName)
+{
+ JavaResultData* java_result;
+ JavaRequestProcessor* java_request = new JavaRequestProcessor();
+ std::string* message;
+
+ java_result = java_request->newString(fieldName);
+
+ this->instance = 0; // context is always 0 (needed for java-side backwards compat.)
+ this->reference = IcedTeaPluginUtilities::getReference();
+
+ message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference);
+ message->append(" GetStaticFieldID ");
+ message->append(classID);
+ message->append(" ");
+ message->append(java_result->return_string->c_str());
+
+ postAndWaitForResponse(message);
+
+ IcedTeaPluginUtilities::releaseReference();
+
+ delete java_request;
+ delete message;
+
+ return result;
+}
+
+JavaResultData*
+JavaRequestProcessor::getField(std::string classID, std::string fieldName)
+{
+ JavaResultData* java_result;
+ JavaRequestProcessor* java_request = new JavaRequestProcessor();
+ std::string* message;
+
+ java_result = java_request->getFieldID(classID, fieldName);
+
+ this->instance = 0; // context is always 0 (needed for java-side backwards compat.)
+ this->reference = IcedTeaPluginUtilities::getReference();
+
+ message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference);
+ message->append(" GetField ");
+ message->append(classID);
+ message->append(" ");
+ message->append(java_result->return_string->c_str());
+
+ postAndWaitForResponse(message);
+
+ IcedTeaPluginUtilities::releaseReference();
+
+ delete java_request;
+ delete message;
+
+ return result;
+}
+
+JavaResultData*
+JavaRequestProcessor::getStaticField(std::string classID, std::string fieldName)
+{
+ JavaResultData* java_result;
+ JavaRequestProcessor* java_request = new JavaRequestProcessor();
+ std::string* message;
+
+ java_result = java_request->getStaticFieldID(classID, fieldName);
+
+ this->instance = 0; // context is always 0 (needed for java-side backwards compat.)
+ this->reference = IcedTeaPluginUtilities::getReference();
+
+ message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference);
+ message->append(" GetStaticField ");
+ message->append(classID);
+ message->append(" ");
+ message->append(java_result->return_string->c_str());
+
+ postAndWaitForResponse(message);
+
+ IcedTeaPluginUtilities::releaseReference();
+
+ delete java_request;
+ delete message;
+
+ return result;
+}
+
+JavaResultData*
+JavaRequestProcessor::getMethodID(std::string classID, NPIdentifier methodName,
std::vector<std::string> args)
{
JavaRequestProcessor* java_request;
@@ -317,7 +556,7 @@ JavaRequestProcessor::getMethodID(std::s
message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference);
*message += " GetMethodID ";
- *message += objectID;
+ *message += classID;
*message += " ";
*message += browser_functions.utf8fromidentifier(methodName);
*message += " ";
@@ -330,6 +569,235 @@ JavaRequestProcessor::getMethodID(std::s
delete message;
return result;
+}
+
+JavaResultData*
+JavaRequestProcessor::getStaticMethodID(std::string classID, NPIdentifier methodName,
+ std::vector<std::string> args)
+{
+ JavaRequestProcessor* java_request;
+ std::string* message;
+ std::string* signature;
+
+ signature = new std::string();
+ *signature += "(";
+
+ // FIXME: Need to determine how to extract array types and complex java objects
+ for (int i=0; i < args.size(); i++)
+ {
+ *signature += args[i];
+ }
+
+ *signature += ")";
+
+ this->instance = 0; // context is always 0 (needed for java-side backwards compat.)
+ this->reference = IcedTeaPluginUtilities::getReference();
+
+ message = IcedTeaPluginUtilities::constructMessagePrefix(0, reference);
+ *message += " GetStaticMethodID ";
+ *message += classID;
+ *message += " ";
+ *message += browser_functions.utf8fromidentifier(methodName);
+ *message += " ";
+ *message += *signature;
+
+ postAndWaitForResponse(message);
+
+ IcedTeaPluginUtilities::releaseReference();
+ delete signature;
+ delete message;
+
+ return result;
+}
+
+int
+JavaRequestProcessor::createJavaObjectFromVariant(NPVariant variant)
+{
+ JavaResultData* java_result;
+
+ std::string className;
+ std::string jsObjectClassID = std::string();
+ std::string jsObjectConstructorID = std::string();
+
+ std::string stringArg = std::string();
+ std::vector<std::string> args = std::vector<std::string>();
+
+ JavaRequestProcessor java_request = JavaRequestProcessor();
+ bool alreadyCreated = false;
+
+ if (NPVARIANT_IS_VOID(variant))
+ {
+ PLUGIN_DEBUG_1ARG("VOID %d\n", variant);
+ }
+ else if (NPVARIANT_IS_NULL(variant))
+ {
+ PLUGIN_DEBUG_1ARG("NULL\n", variant);
+ }
+ else if (NPVARIANT_IS_BOOLEAN(variant))
+ {
+ className = "java.lang.Boolean";
+
+ if (NPVARIANT_TO_BOOLEAN(variant))
+ stringArg = "true";
+ else
+ stringArg = "false";
+
+ }
+ else if (NPVARIANT_IS_INT32(variant))
+ {
+ className = "java.lang.Integer";
More information about the distro-pkg-dev
mailing list