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