From 72cc555dc703aa3f6a7338b5c3ade9fee7e799e3 Mon Sep 17 00:00:00 2001 From: Andrew Azores Date: Thu, 17 Oct 2013 10:32:46 -0400 Subject: Back out changeset 420d72e5cee7 Back out changeset 420d72e5cee7 due to breaking LiveConnect feature. http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2013-October/024919.html * plugin/icedteanp/IcedTeaNPPlugin.cc: undo 420d72e5cee7 * plugin/icedteanp/IcedTeaPluginUtils.cc: undo 420d72e5cee7 * plugin/icedteanp/IcedTeaPluginUtils.h: undo 420d72e5cee7 * plugin/icedteanp/IcedTeaScriptablePluginObject.cc: undo 420d72e5cee7 * plugin/icedteanp/IcedTeaScriptablePluginObject.h: undo 420d72e5cee7 * tests/cpp-unit-tests/IcedTeaScriptablePluginObjectTest.cc: undo 420d72e5cee7 --- ChangeLog | 11 ++ plugin/icedteanp/IcedTeaNPPlugin.cc | 36 +++- plugin/icedteanp/IcedTeaPluginUtils.cc | 134 ++++--------- plugin/icedteanp/IcedTeaPluginUtils.h | 67 +------ plugin/icedteanp/IcedTeaScriptablePluginObject.cc | 208 ++++++--------------- plugin/icedteanp/IcedTeaScriptablePluginObject.h | 28 +-- .../IcedTeaScriptablePluginObjectTest.cc | 15 +- 7 files changed, 164 insertions(+), 335 deletions(-) diff --git a/ChangeLog b/ChangeLog index b2a20b8..7d069cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2013-10-17 Andrew Azores + + Back out changeset 420d72e5cee7 due to breaking LiveConnect feature. + http://mail.openjdk.java.net/pipermail/distro-pkg-dev/2013-October/024919.html + * plugin/icedteanp/IcedTeaNPPlugin.cc: undo 420d72e5cee7 + * plugin/icedteanp/IcedTeaPluginUtils.cc: undo 420d72e5cee7 + * plugin/icedteanp/IcedTeaPluginUtils.h: undo 420d72e5cee7 + * plugin/icedteanp/IcedTeaScriptablePluginObject.cc: undo 420d72e5cee7 + * plugin/icedteanp/IcedTeaScriptablePluginObject.h: undo 420d72e5cee7 + * tests/cpp-unit-tests/IcedTeaScriptablePluginObjectTest.cc: undo 420d72e5cee7 + 2013-10-16 Andrew Azores Resolve deadlock issue when multiple applets are loaded simultaneously diff --git a/plugin/icedteanp/IcedTeaNPPlugin.cc b/plugin/icedteanp/IcedTeaNPPlugin.cc index e806d29..bfce1ae 100644 --- a/plugin/icedteanp/IcedTeaNPPlugin.cc +++ b/plugin/icedteanp/IcedTeaNPPlugin.cc @@ -2101,6 +2101,14 @@ get_scriptable_object(NPP instance) if (data->is_applet_instance) // dummy instance/package? { + JavaRequestProcessor java_request = JavaRequestProcessor(); + JavaResultData* java_result; + std::string instance_id = std::string(); + std::string applet_class_id = std::string(); + + int id = get_id_from_instance(instance); + gchar* id_str = g_strdup_printf ("%d", id); + // Some browsers.. (e.g. chromium) don't call NPP_SetWindow // for 0x0 plugins and therefore require initialization with // a 0 handle @@ -2109,10 +2117,30 @@ get_scriptable_object(NPP instance) plugin_send_initialization_message(data->instance_id, 0, 0, 0, data->parameters_string); } - NPObjectRef applet_object = IcedTeaScriptableJavaObject::get_scriptable_applet_object(instance); - /* Retain because we are returning an NPObject* */ - applet_object.raw_retain(); - obj = applet_object.get(); + java_result = java_request.getAppletObjectInstance(id_str); + + g_free(id_str); + + if (java_result->error_occurred) + { + printf("Error: Unable to fetch applet instance id from Java side.\n"); + return NULL; + } + + instance_id.append(*(java_result->return_string)); + + java_result = java_request.getClassID(instance_id); + + if (java_result->error_occurred) + { + printf("Error: Unable to fetch applet instance id from Java side.\n"); + return NULL; + } + + applet_class_id.append(*(java_result->return_string)); + + obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(instance, applet_class_id, instance_id, false); + } else { obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object(instance, ""); diff --git a/plugin/icedteanp/IcedTeaPluginUtils.cc b/plugin/icedteanp/IcedTeaPluginUtils.cc index 6ce37e8..d8ae1ee 100644 --- a/plugin/icedteanp/IcedTeaPluginUtils.cc +++ b/plugin/icedteanp/IcedTeaPluginUtils.cc @@ -53,7 +53,7 @@ exception statement from your version. */ int IcedTeaPluginUtilities::reference = -1; pthread_mutex_t IcedTeaPluginUtilities::reference_mutex = PTHREAD_MUTEX_INITIALIZER; std::map* IcedTeaPluginUtilities::instance_map = new std::map(); -std::map IcedTeaPluginUtilities::object_map; +std::map* IcedTeaPluginUtilities::object_map = new std::map(); /* Plugin async call queue */ static std::vector< PluginThreadCall* >* pendingPluginThreadRequests = new std::vector< PluginThreadCall* >(); @@ -433,9 +433,9 @@ void IcedTeaPluginUtilities::printStringVector(const char* prefix, std::vector* str_vector) { - // This is a CPU intensive function. Run only if debugging - if (!plugin_debug) - return; + // This is a CPU intensive function. Run only if debugging + if (!plugin_debug) + return; std::string* str = new std::string(); *str += "{ "; @@ -561,25 +561,27 @@ IcedTeaPluginUtilities::getInstanceFromMemberPtr(void* member_ptr) * @return The associated active NPObject, NULL otherwise */ -NPObjectRef +NPObject* IcedTeaPluginUtilities::getNPObjectFromJavaKey(std::string key) { + + NPObject* object = NULL; PLUGIN_DEBUG("getNPObjectFromJavaKey looking for %s\n", key.c_str()); - std::map::iterator iterator = object_map.find(key); + std::map::iterator iterator = object_map->find(key); - if (iterator != object_map.end()) + if (iterator != object_map->end()) { - NPObjectRef object = object_map.find(key)->second; + NPObject* mapped_object = object_map->find(key)->second; - if (getInstanceFromMemberPtr(object.get()) != NULL) + if (getInstanceFromMemberPtr(mapped_object) != NULL) { - PLUGIN_DEBUG("getNPObjectFromJavaKey found %s. NPObject = %p\n", key.c_str(), object.get()); - return object; + object = mapped_object; + PLUGIN_DEBUG("getNPObjectFromJavaKey found %s. NPObject = %p\n", key.c_str(), object); } } - return NPObjectRef(NULL); + return object; } /** @@ -590,10 +592,10 @@ IcedTeaPluginUtilities::getNPObjectFromJavaKey(std::string key) */ void -IcedTeaPluginUtilities::storeObjectMapping(std::string key, NPObjectRef object) +IcedTeaPluginUtilities::storeObjectMapping(std::string key, NPObject* object) { - PLUGIN_DEBUG("Storing object %p with key %s\n", object.get(), key.c_str()); - object_map.insert(std::make_pair(key, object)); + PLUGIN_DEBUG("Storing object %p with key %s\n", object, key.c_str()); + object_map->insert(std::make_pair(key, object)); } /** @@ -606,14 +608,19 @@ void IcedTeaPluginUtilities::removeObjectMapping(std::string key) { PLUGIN_DEBUG("Removing key %s from object map\n", key.c_str()); - object_map.erase(key); + object_map->erase(key); } /* Clear object_map. Useful for tests. */ void IcedTeaPluginUtilities::clearObjectMapping() { - object_map = std::map(); + std::map::iterator iter = object_map->begin(); + for (; iter != object_map->end(); ++iter) { + browser_functions.releaseobject(iter->second); + } + delete object_map; + object_map = new std::map(); } /* @@ -626,9 +633,9 @@ IcedTeaPluginUtilities::clearObjectMapping() void IcedTeaPluginUtilities::printStringPtrVector(const char* prefix, std::vector* str_ptr_vector) { - // This is a CPU intensive function. Run only if debugging - if (!plugin_debug) - return; + // This is a CPU intensive function. Run only if debugging + if (!plugin_debug) + return; std::string* str = new std::string(); *str += "{ "; @@ -812,13 +819,18 @@ javaObjectResultToNPVariant(NPP instance, const std::string& jobject_id, NPVaria std::string jclass_id = *jclass_result->return_string; - bool is_array = (jclass_id.at(0) == '['); - NPObjectRef object = IcedTeaScriptableJavaObject::get_scriptable_java_object(instance, jclass_id, - jobject_id, is_array); + NPObject* obj; + if (jclass_id.at(0) == '[') // array + { + obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(instance, jclass_id, + jobject_id, true); + } else + { + obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(instance, jclass_id, + jobject_id, false); + } - OBJECT_TO_NPVARIANT(object.get(), *variant); - /* Retain because we are returning an NPObject* */ - object.raw_retain(); + OBJECT_TO_NPVARIANT(obj, *variant); return true; } @@ -862,12 +874,12 @@ IcedTeaPluginUtilities::javaResultToNPVariant(NPP instance, } bool -IcedTeaPluginUtilities::isObjectJSArray(NPP instance, NPObjectRef object) +IcedTeaPluginUtilities::isObjectJSArray(NPP instance, NPObject* object) { NPVariant constructor_v = NPVariant(); NPIdentifier constructor_id = browser_functions.getstringidentifier("constructor"); - browser_functions.getproperty(instance, object.get(), constructor_id, &constructor_v); + browser_functions.getproperty(instance, object, constructor_id, &constructor_v); IcedTeaPluginUtilities::printNPVariant(constructor_v); // void constructor => not an array @@ -1075,34 +1087,6 @@ void IcedTeaPluginUtilities::trim(std::string& str) { str = str.substr(start, end - start + 1); } -std::string -IcedTeaPluginUtilities::stringPrintf(const char* fmt, /*variable arguments*/ ...) -{ - /* Extract the variable arguments */ - va_list args; - va_start(args, fmt); - - gchar* result = NULL; - size_t size; - - /* Format the arguments into a new buffer, held in 'result' */ - size = g_vasprintf (&result, fmt, args); - - if (result == NULL) - { - // We are out of memory - throw std::bad_alloc(); - } - - /* Wrap as string and free buffer */ - std::string str(result, size); - g_free(result); - - va_end(args); /* Finish using variable arguments */ - - return str; -} - std::string IcedTeaPluginUtilities::NPIdentifierAsString(NPIdentifier id) { NPUTF8* cstr = browser_functions.utf8fromidentifier(id); if (cstr == NULL) { @@ -1258,41 +1242,3 @@ MessageBus::post(const char* message) PLUGIN_DEBUG("%p unlocked...\n", &msg_queue_mutex); } -void -NPObjectRef::set(NPObject* new_object) -{ - if (new_object != NULL) { - /* Increase the new object's reference count */ - browser_functions.retainobject(new_object); - } - if (current_object != NULL) { - /* Decrease the old object's reference count */ - browser_functions.releaseobject(current_object); - } - - this->current_object = new_object; -} - -NPObjectRef -NPObjectRef::create(NPP instance, NPClass* np_class) -{ - NPObjectRef ref; - /* Don't use set(), otherwise we'd double-retain */ - ref.current_object = browser_functions.createobject(instance, np_class); - return ref; -} - -/* Explicit reference counting operations, use only if needed for interoperating with NPObject* */ -void -NPObjectRef::raw_retain() { - if (current_object != NULL) { - browser_functions.retainobject(current_object); - } -} - -void -NPObjectRef::raw_release() { - if (current_object != NULL) { - browser_functions.releaseobject(current_object); - } -} diff --git a/plugin/icedteanp/IcedTeaPluginUtils.h b/plugin/icedteanp/IcedTeaPluginUtils.h index 56aeb94..29cc3ae 100644 --- a/plugin/icedteanp/IcedTeaPluginUtils.h +++ b/plugin/icedteanp/IcedTeaPluginUtils.h @@ -153,61 +153,6 @@ typedef struct async_call_thread_data /* Function to process all pending async calls */ void processAsyncCallQueue(void*); -/* Reference-counted 'smart pointer' to NPObject */ -class NPObjectRef { -public: - /* Create with browser_functions.createobject. - * This ensures the object is not double-retained. */ - static NPObjectRef create(NPP instance, NPClass* np_class); - - NPObjectRef(NPObject* obj = NULL) { - current_object = NULL; - set(obj); - } - - NPObjectRef(const NPObjectRef& ref) { - current_object = NULL; - set(ref.current_object); - } - - NPObjectRef& operator=(const NPObjectRef& ref) { - set(ref.current_object); - return *this; - } - - ~NPObjectRef() { - clear(); - } - - void set(NPObject* new_object); - - /* Get's the object pointer */ - NPObject* get() { - return current_object; - } - - /* Helper for getting object as different type. - * NOTE: This cast is unchecked. */ - template - T as() { - return (T)current_object; - } - - /* Explicit reference counting operations, use only if needed for interoperating with NPObject* */ - void raw_retain(); - void raw_release(); - - bool empty() { - return (current_object == NULL); - } - - void clear() { - set(NULL); - } -private: - NPObject* current_object; -}; - class IcedTeaPluginUtilities { @@ -220,8 +165,8 @@ class IcedTeaPluginUtilities /* Map holding window pointer<->instance relationships */ static std::map* instance_map; - /* Map holding java-side-obj-key->NPObject relationship. */ - static std::map object_map; + /* Map holding java-side-obj-key->NPObject relationship */ + static std::map* object_map; /* Posts a call in the async call queue */ static bool postPluginThreadAsyncCall(NPP instance, void (*func) (void *), void* data); @@ -257,8 +202,6 @@ class IcedTeaPluginUtilities /* Converts the given integer to a string */ static void itoa(int i, std::string* result); - static std::string stringPrintf(const char* fmt, ...); - /* Copies a variant data type into a C++ string */ static std::string NPVariantAsString(NPVariant variant); @@ -319,9 +262,9 @@ class IcedTeaPluginUtilities static NPP getInstanceFromMemberPtr(void* member_ptr); - static NPObjectRef getNPObjectFromJavaKey(std::string key); + static NPObject* getNPObjectFromJavaKey(std::string key); - static void storeObjectMapping(std::string key, NPObjectRef object); + static void storeObjectMapping(std::string key, NPObject* object); static void removeObjectMapping(std::string key); @@ -330,7 +273,7 @@ class IcedTeaPluginUtilities static void invalidateInstance(NPP instance); - static bool isObjectJSArray(NPP instance, NPObjectRef object); + static bool isObjectJSArray(NPP instance, NPObject* object); static void decodeURL(const char* url, char** decoded_url); diff --git a/plugin/icedteanp/IcedTeaScriptablePluginObject.cc b/plugin/icedteanp/IcedTeaScriptablePluginObject.cc index d594afa..51cbcd4 100644 --- a/plugin/icedteanp/IcedTeaScriptablePluginObject.cc +++ b/plugin/icedteanp/IcedTeaScriptablePluginObject.cc @@ -306,26 +306,24 @@ IcedTeaScriptableJavaPackageObject::getProperty(NPObject *npobj, NPIdentifier na //NPIdentifier property = browser_functions.getstringidentifier(property_name.c_str()); - NPObjectRef object; + NPObject* obj; if (isPropertyClass) { PLUGIN_DEBUG("Returning package object\n"); - object = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object( + obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_package_object( IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), property_name.c_str()); } else { PLUGIN_DEBUG("Returning Java object\n"); - object = IcedTeaScriptableJavaObject::get_scriptable_java_object( + obj = IcedTeaScriptableJavaObject::get_scriptable_java_object( IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), *(java_result->return_string), "0", false); } - OBJECT_TO_NPVARIANT(object.get(), *result); - /* Retain because we are returning an NPObject* */ - object.raw_retain(); + OBJECT_TO_NPVARIANT(obj, *result); return true; } @@ -386,33 +384,32 @@ scriptable_java_package_object_class() { return np_class; } -/* Creates a scriptable java object (intended to be called asynch.) */ -static void -create_scriptable_java_object_async(void* data) +NPObject* +IcedTeaScriptableJavaObject::get_scriptable_java_object(NPP instance, + std::string class_id, + std::string instance_id, + bool isArray) { - PLUGIN_DEBUG("Asynchronously creating object ...\n"); - - std::vector parameters = ((AsyncCallThreadData*) data)->parameters; - NPP instance = (NPP) parameters.at(0); - NPClass* np_class = (NPClass*) parameters.at(1); - NPObjectRef* object_ref = (NPObjectRef*) parameters.at(2); + /* Shared NPClass instance for IcedTeaScriptablePluginObject */ + static NPClass np_class = scriptable_java_package_object_class(); - *object_ref = browser_functions.createobject(instance, np_class); + std::string obj_key = class_id + ":" + instance_id; - ((AsyncCallThreadData*) data)->result_ready = true; -} + PLUGIN_DEBUG("get_scriptable_java_object searching for %s...\n", obj_key.c_str()); + IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) IcedTeaPluginUtilities::getNPObjectFromJavaKey(obj_key); -static NPObjectRef -create_scriptable_java_object(NPP instance) -{ - /* Shared NPClass instance for IcedTeaScriptablePluginObject */ - static NPClass np_class = scriptable_java_package_object_class(); + if (scriptable_object != NULL) + { + PLUGIN_DEBUG("Returning existing object %p\n", scriptable_object); + browser_functions.retainobject(scriptable_object); + return scriptable_object; + } // try to create normally - NPObjectRef np_object = NPObjectRef::create(instance, &np_class); + scriptable_object = (IcedTeaScriptableJavaObject*)browser_functions.createobject(instance, &np_class); // didn't work? try creating asynch - if (np_object.empty()) + if (!scriptable_object) { AsyncCallThreadData thread_data = AsyncCallThreadData(); thread_data.result_ready = false; @@ -421,104 +418,45 @@ create_scriptable_java_object(NPP instance) thread_data.parameters.push_back(instance); thread_data.parameters.push_back(&np_class); - thread_data.parameters.push_back(&np_object); + thread_data.parameters.push_back(&scriptable_object); - IcedTeaPluginUtilities::callAndWaitForResult(instance, &create_scriptable_java_object_async, &thread_data); - } - - return np_object; -} - -/* If we are uninitialized, make a Java request for the applet java class & instance ID for the plugin instance. - * Only objects representing an applet will begin uninitialized, to prevent blocking when the browser requests the object. - * Returns false on initialization error. */ -bool -IcedTeaScriptableJavaObject::tryToInitializeIfApplet() { - if (initialization_failed || initialized) - { - return !initialization_failed; - } - - JavaRequestProcessor java_request; - - std::string id = IcedTeaPluginUtilities::stringPrintf("%d", get_id_from_instance(instance)); - - /* Try to fetch the specific applet Java instance */ - JavaResultData* instance_result = java_request.getAppletObjectInstance(id); - if (instance_result->error_occurred) - { - printf("Error: Unable to fetch applet instance id from Java side.\n"); - initialization_failed = true; - return false; - } - this->instance_id = *instance_result->return_string; - - /* Try to fetch the applet Java class */ - JavaResultData* class_result = java_request.getClassID(id); - if (class_result->error_occurred) + IcedTeaPluginUtilities::callAndWaitForResult(instance, &_createAndRetainJavaObject, &thread_data); + } else { - printf("Error: Unable to fetch applet instance id from Java side.\n"); - initialization_failed = true; - return false; + // Else retain object and continue + browser_functions.retainobject(scriptable_object); } - this->class_id = *class_result->return_string; - std::string obj_key = getClassID() + ":" + getInstanceID(); - IcedTeaPluginUtilities::storeObjectMapping(obj_key, this); + PLUGIN_DEBUG("Constructed new Java Object with classid=%s, instanceid=%s, isArray=%d and scriptable_object=%p\n", class_id.c_str(), instance_id.c_str(), isArray, scriptable_object); - printf("Object was initialized at '%s'.\n", obj_key.c_str()); + scriptable_object->class_id = class_id; + scriptable_object->is_object_array = isArray; - initialized = true; + if (instance_id != "0") + scriptable_object->instance_id = instance_id; - return true; -} + IcedTeaPluginUtilities::storeInstanceID(scriptable_object, instance); + IcedTeaPluginUtilities::storeObjectMapping(obj_key, scriptable_object); -NPObjectRef -IcedTeaScriptableJavaObject::get_scriptable_applet_object(NPP instance) -{ - PLUGIN_DEBUG("get_scriptable_applet_object creating applet object for %p...\n", instance); - - /* Do not mark as initialized, object will lookup class & instance IDs before use */ - NPObjectRef object = create_scriptable_java_object(instance); - IcedTeaPluginUtilities::storeInstanceID(object.get(), instance); - return object; + PLUGIN_DEBUG("Inserting into object_map key %s->%p\n", obj_key.c_str(), scriptable_object); + return scriptable_object; } -NPObjectRef -IcedTeaScriptableJavaObject::get_scriptable_java_object(NPP instance, - std::string class_id, - std::string instance_id, - bool isArray) +/* Creates and retains a scriptable java object (intended to be called asynch.) */ +void +_createAndRetainJavaObject(void* data) { - std::string obj_key = class_id + ":" + instance_id; - - PLUGIN_DEBUG("get_scriptable_java_object searching for %s...\n", obj_key.c_str()); - NPObjectRef object = IcedTeaPluginUtilities::getNPObjectFromJavaKey(obj_key); - - if (!object.empty()) - { - PLUGIN_DEBUG("Returning existing object %p\n", object.get()); - return object; - } - - object = create_scriptable_java_object(instance); - PLUGIN_DEBUG("Constructed new Java Object with classid=%s, instanceid=%s, isArray=%d and scriptable_object=%p\n", class_id.c_str(), instance_id.c_str(), isArray, object.get()); - - IcedTeaScriptableJavaObject* scriptable_object = object.as(); - scriptable_object->class_id = class_id; - scriptable_object->is_object_array = isArray; - /* We know the class & instance already at this point, so we are initialized */ - scriptable_object->initialized = true; + PLUGIN_DEBUG("Asynchronously creating/retaining object ...\n"); - if (instance_id != "0") { - scriptable_object->instance_id = instance_id; - } + std::vector parameters = ((AsyncCallThreadData*) data)->parameters; + NPP instance = (NPP) parameters.at(0); + NPClass* np_class = (NPClass*) parameters.at(1); + NPObject** scriptable_object = (NPObject**) parameters.at(2); - IcedTeaPluginUtilities::storeInstanceID(object.get(), instance); - IcedTeaPluginUtilities::storeObjectMapping(obj_key, object.get()); + *scriptable_object = browser_functions.createobject(instance, np_class); + browser_functions.retainobject(*scriptable_object); - PLUGIN_DEBUG("Inserting into object_map key %s->%p\n", obj_key.c_str(), object.get()); - return object; + ((AsyncCallThreadData*) data)->result_ready = true; } bool @@ -529,13 +467,8 @@ IcedTeaScriptableJavaPackageObject::is_valid_java_object(NPObject* object_ptr) { bool IcedTeaScriptableJavaObject::hasMethod(NPObject *npobj, NPIdentifier name_id) { - IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; - /* If we are an applet object, we may not be initialized yet. */ - if (!scriptable_object->tryToInitializeIfApplet()) { - return false; - } - std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); + IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasMethod %s (ival=%d)\n", name.c_str(), browser_functions.intfromidentifier(name_id)); bool hasMethod = false; @@ -563,12 +496,6 @@ bool IcedTeaScriptableJavaObject::invoke(NPObject *npobj, NPIdentifier name_id, const NPVariant *args, uint32_t argCount, NPVariant *result) { - IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; - /* If we are an applet object, we may not be initialized yet. */ - if (!scriptable_object->tryToInitializeIfApplet()) { - return false; - } - std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); // Extract arg type array @@ -581,6 +508,8 @@ IcedTeaScriptableJavaObject::invoke(NPObject *npobj, NPIdentifier name_id, const JavaResultData* java_result; JavaRequestProcessor java_request = JavaRequestProcessor(); + IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj; + std::string instance_id = scriptable_object->instance_id; std::string class_id = scriptable_object->class_id; @@ -629,17 +558,12 @@ IcedTeaScriptableJavaObject::invoke(NPObject *npobj, NPIdentifier name_id, const bool IcedTeaScriptableJavaObject::hasProperty(NPObject *npobj, NPIdentifier name_id) { - IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; - /* If we are an applet object, we may not be initialized yet. */ - if (!scriptable_object->tryToInitializeIfApplet()) { - return false; - } - std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); PLUGIN_DEBUG("IcedTeaScriptableJavaObject::hasProperty %s (ival=%d)\n", name.c_str(), browser_functions.intfromidentifier(name_id)); bool hasProperty = false; + IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj; // If it is an array, only length and indexes are valid if (scriptable_object->is_object_array) { @@ -672,12 +596,6 @@ IcedTeaScriptableJavaObject::hasProperty(NPObject *npobj, NPIdentifier name_id) bool IcedTeaScriptableJavaObject::getProperty(NPObject *npobj, NPIdentifier name_id, NPVariant *result) { - IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; - /* If we are an applet object, we may not be initialized yet. */ - if (!scriptable_object->tryToInitializeIfApplet()) { - return false; - } - std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); bool is_string_id = browser_functions.identifierisstring(name_id); PLUGIN_DEBUG("IcedTeaScriptableJavaObject::getProperty %s (ival=%d)\n", name.c_str(), browser_functions.intfromidentifier(name_id)); @@ -685,11 +603,13 @@ IcedTeaScriptableJavaObject::getProperty(NPObject *npobj, NPIdentifier name_id, JavaResultData* java_result; JavaRequestProcessor java_request = JavaRequestProcessor(); + IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj; + std::string instance_id = scriptable_object->getInstanceID(); std::string class_id = scriptable_object->getClassID(); NPP instance = scriptable_object->instance; - if (!instance_id.empty()) // Could be an array or a simple object + if (instance_id.length() > 0) // Could be an array or a simple object { // If array and requesting length if ( scriptable_object->is_object_array && name == "length") @@ -760,18 +680,13 @@ IcedTeaScriptableJavaObject::getProperty(NPObject *npobj, NPIdentifier name_id, bool IcedTeaScriptableJavaObject::setProperty(NPObject *npobj, NPIdentifier name_id, const NPVariant *value) { - IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; - /* If we are an applet object, we may not be initialized yet. */ - if (!scriptable_object->tryToInitializeIfApplet()) { - return false; - } - std::string name = IcedTeaPluginUtilities::NPIdentifierAsString(name_id); PLUGIN_DEBUG("IcedTeaScriptableJavaObject::setProperty %s (ival=%d) to:\n", name.c_str(), browser_functions.intfromidentifier(name_id)); IcedTeaPluginUtilities::printNPVariant(*value); JavaResultData* java_result; JavaRequestProcessor java_request = JavaRequestProcessor(); + IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj; std::string instance_id = scriptable_object->getInstanceID(); std::string class_id = scriptable_object->getClassID(); @@ -845,12 +760,7 @@ bool IcedTeaScriptableJavaObject::construct(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result) { - IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; - /* If we are an applet object, we may not be initialized yet. */ - if (!scriptable_object->tryToInitializeIfApplet()) { - return false; - } - + IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*)npobj; // Extract arg type array PLUGIN_DEBUG("IcedTeaScriptableJavaObject::construct %s. Args follow.\n", scriptable_object->getClassID().c_str()); for (int i=0; i < argCount; i++) @@ -892,13 +802,11 @@ IcedTeaScriptableJavaObject::construct(NPObject *npobj, const NPVariant *args, u std::string return_obj_instance_id = *java_result->return_string; std::string return_obj_class_id = scriptable_object->class_id; - NPObjectRef object = IcedTeaScriptableJavaObject::get_scriptable_java_object( + NPObject* obj = IcedTeaScriptableJavaObject::get_scriptable_java_object( IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj), return_obj_class_id, return_obj_instance_id, false); - OBJECT_TO_NPVARIANT(object.get(), *result); - /* Retain because we are returning an NPObject* */ - object.raw_retain(); + OBJECT_TO_NPVARIANT(obj, *result); PLUGIN_DEBUG("IcedTeaScriptableJavaObject::construct returning.\n"); return true; diff --git a/plugin/icedteanp/IcedTeaScriptablePluginObject.h b/plugin/icedteanp/IcedTeaScriptablePluginObject.h index 99e89c2..a02df53 100644 --- a/plugin/icedteanp/IcedTeaScriptablePluginObject.h +++ b/plugin/icedteanp/IcedTeaScriptablePluginObject.h @@ -145,20 +145,13 @@ class IcedTeaScriptableJavaObject: public NPObject private: NPP instance; bool is_object_array; - /* These may be empty if 'initialized' is false */ + /* These may be empty if 'is_applet_instance' is true + * and the object has not yet been used */ std::string class_id, instance_id; - bool initialized, initialization_failed; - - /* If we are uninitialized, make a Java request for the applet java class & instance ID for the plugin instance. - * Only objects representing an applet will begin uninitialized, to prevent blocking when the browser requests the object. - * Returns false on initialization error. */ - bool tryToInitializeIfApplet(); public: IcedTeaScriptableJavaObject(NPP instance) { this->instance = instance; - this->is_object_array = false; - this->initialized = false; - this->initialization_failed = false; + is_object_array = false; } static void deAllocate(NPObject *npobj) { delete (IcedTeaScriptableJavaObject*)npobj; @@ -173,12 +166,8 @@ public: return getClassID() + ":" + getInstanceID(); } static void invalidate(NPObject *npobj) { - IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; - /* Nothing to do if we have not been initialized */ - if (!scriptable_object->initialized) { - return; - } IcedTeaPluginUtilities::removeInstanceID(npobj); + IcedTeaScriptableJavaObject* scriptable_object = (IcedTeaScriptableJavaObject*) npobj; IcedTeaPluginUtilities::removeObjectMapping(scriptable_object->objectKey()); } static bool hasMethod(NPObject *npobj, NPIdentifier name_id); @@ -206,12 +195,15 @@ public: } static bool construct(NPObject *npobj, const NPVariant *args, uint32_t argCount, NPVariant *result); - - static NPObjectRef get_scriptable_applet_object(NPP instance); - static NPObjectRef get_scriptable_java_object(NPP instance, + /* Creates and retains a scriptable java object (intended to be called asynch.) */ + static NPObject* get_scriptable_java_object(NPP instance, std::string class_id, std::string instance_id, bool isArray); }; +/* Creates and retains a scriptable java object (intended to be called asynch.) */ + +void _createAndRetainJavaObject(void* data); + #endif /* __ICEDTEASCRIPTABLEPLUGINOBJECT_H_ */ diff --git a/tests/cpp-unit-tests/IcedTeaScriptablePluginObjectTest.cc b/tests/cpp-unit-tests/IcedTeaScriptablePluginObjectTest.cc index b5c893c..bb2b376 100644 --- a/tests/cpp-unit-tests/IcedTeaScriptablePluginObjectTest.cc +++ b/tests/cpp-unit-tests/IcedTeaScriptablePluginObjectTest.cc @@ -66,15 +66,16 @@ SUITE(IcedTeaScriptableJavaObject) { TEST(get_scriptable_java_object) { MemoryLeakDetector leak_detector; - /* Ensure freeing*/ { - NPObjectRef first_obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(&dummy_npp, "DummyClass", "DummyInstance", false); + NPObject* first_obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(&dummy_npp, "DummyClass", "DummyInstance", false); + browser_functions.releaseobject(first_obj); - /* After the first call, the object should be cached in the object map */ - NPObjectRef second_obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(&dummy_npp, "DummyClass", "DummyInstance", false); + /* After the first call, the object should be cached in the object map */ + NPObject* second_obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(&dummy_npp, "DummyClass", "DummyInstance", false); - /* Objects should be the same, because of caching */ - CHECK(first_obj.get() == second_obj.get()); - } + /* Objects should be the same, because of caching */ + CHECK(first_obj == second_obj); + + browser_functions.releaseobject(second_obj); CHECK(leak_detector.memory_leaks() == 0); } -- cgit v1.2.3