1b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian/* 209e3a0d3e5e0725e32330137c505146270a2fc84Steve Block * Copyright 2010, The Android Open Source Project 3b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * 4b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * Redistribution and use in source and binary forms, with or without 5b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * modification, are permitted provided that the following conditions 6b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * are met: 7b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * * Redistributions of source code must retain the above copyright 8b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * notice, this list of conditions and the following disclaimer. 9b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * * Redistributions in binary form must reproduce the above copyright 10b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * notice, this list of conditions and the following disclaimer in the 11b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * documentation and/or other materials provided with the distribution. 12b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * 13b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1609e3a0d3e5e0725e32330137c505146270a2fc84Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian */ 25b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian 26b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian 27b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian#include "config.h" 2854dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block#include "JavaNPObjectV8.h" 2920ab751acc0d49d74648373f701f3d0c4ff187c0Steve Block 3081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if ENABLE(JAVA_BRIDGE) 3181bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 3209e3a0d3e5e0725e32330137c505146270a2fc84Steve Block#include "JNIUtilityPrivate.h" 3378023b8120c8cd0aba398f04bf5aacb8d3fd05c7Steve Block#include "JavaClassV8.h" 3481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "JavaFieldV8.h" 3540c8c4abfc2d689e4aa21c5dfab61ce45e45b38bSteve Block#include "JavaInstanceV8.h" 362bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "JavaMethod.h" 372bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "JavaValueV8.h" 38b999781071d8167a543e0e48ad25d51178d713d1Steve Block#include "npruntime_impl.h" 397fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 4054dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Blocknamespace JSC { 4154dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block 4254dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Blocknamespace Bindings { 4354dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block 44b2318f335c407832166c7568f3e50afedad5b9dbFeng Qianstatic NPObject* AllocJavaNPObject(NPP, NPClass*) 45b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian{ 4654dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block JavaNPObject* obj = static_cast<JavaNPObject*>(malloc(sizeof(JavaNPObject))); 4754dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block if (!obj) 48e8f342c7034cddf274ba5b9e18c51dd3e29c7db9Feng Qian return 0; 49e72218e36405a28fa142afc38ef1fff50797cc45Steve Block memset(obj, 0, sizeof(JavaNPObject)); 50e8f342c7034cddf274ba5b9e18c51dd3e29c7db9Feng Qian return reinterpret_cast<NPObject*>(obj); 51b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian} 52b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian 53b2318f335c407832166c7568f3e50afedad5b9dbFeng Qianstatic void FreeJavaNPObject(NPObject* npobj) 54b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian{ 55b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian JavaNPObject* obj = reinterpret_cast<JavaNPObject*>(npobj); 5609e3a0d3e5e0725e32330137c505146270a2fc84Steve Block obj->m_instance = 0; // free does not call the destructor 57b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian free(obj); 58b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian} 597fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 60b2318f335c407832166c7568f3e50afedad5b9dbFeng Qianstatic NPClass JavaNPObjectClass = { 617fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian NP_CLASS_STRUCT_VERSION, 6209e3a0d3e5e0725e32330137c505146270a2fc84Steve Block AllocJavaNPObject, // allocate, 6309e3a0d3e5e0725e32330137c505146270a2fc84Steve Block FreeJavaNPObject, // free, 6409e3a0d3e5e0725e32330137c505146270a2fc84Steve Block 0, // invalidate 6509e3a0d3e5e0725e32330137c505146270a2fc84Steve Block JavaNPObjectHasMethod, 6609e3a0d3e5e0725e32330137c505146270a2fc84Steve Block JavaNPObjectInvoke, 6709e3a0d3e5e0725e32330137c505146270a2fc84Steve Block 0, // invokeDefault, 6809e3a0d3e5e0725e32330137c505146270a2fc84Steve Block JavaNPObjectHasProperty, 6909e3a0d3e5e0725e32330137c505146270a2fc84Steve Block JavaNPObjectGetProperty, 7009e3a0d3e5e0725e32330137c505146270a2fc84Steve Block 0, // setProperty 7109e3a0d3e5e0725e32330137c505146270a2fc84Steve Block 0, // removeProperty 7209e3a0d3e5e0725e32330137c505146270a2fc84Steve Block 0, // enumerate 7309e3a0d3e5e0725e32330137c505146270a2fc84Steve Block 0 // construct 747fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian}; 757fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 7649a6d4f2c272010e14806805cb2ca55e6fe8a782Steve BlockNPObject* JavaInstanceToNPObject(JavaInstance* instance) 7709e3a0d3e5e0725e32330137c505146270a2fc84Steve Block{ 78ab4f4d6e9dcd2465524619737cd0bbd7386fa14eBen Murdoch JavaNPObject* object = reinterpret_cast<JavaNPObject*>(_NPN_CreateObject(0, &JavaNPObjectClass)); 7954dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block object->m_instance = instance; 80b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return reinterpret_cast<NPObject*>(object); 817fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian} 827fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 83b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian// Returns null if obj is not a wrapper of JavaInstance 8409e3a0d3e5e0725e32330137c505146270a2fc84Steve BlockJavaInstance* ExtractJavaInstance(NPObject* obj) 8509e3a0d3e5e0725e32330137c505146270a2fc84Steve Block{ 8609e3a0d3e5e0725e32330137c505146270a2fc84Steve Block if (obj->_class == &JavaNPObjectClass) 8754dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block return reinterpret_cast<JavaNPObject*>(obj)->m_instance.get(); 88b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return 0; 897fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian} 907fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 9109e3a0d3e5e0725e32330137c505146270a2fc84Steve Blockbool JavaNPObjectHasMethod(NPObject* obj, NPIdentifier identifier) 9209e3a0d3e5e0725e32330137c505146270a2fc84Steve Block{ 93b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian JavaInstance* instance = ExtractJavaInstance(obj); 9454dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block if (!instance) 95b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return false; 9602a23642eaae7e2fdd441eddffd2c085fbee3b49Ben Murdoch NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); 9754dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block if (!name) 98b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return false; 99b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian 10088d4517612dafdcaff7a98f2a68ff071e2734ea6Steve Block instance->begin(); 101b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian bool result = (instance->getClass()->methodsNamed(name).size() > 0); 10288d4517612dafdcaff7a98f2a68ff071e2734ea6Steve Block instance->end(); 1037fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 104b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian // TODO: use NPN_MemFree 105b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian free(name); 106b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian 107b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return result; 1087fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian} 1097fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 11009e3a0d3e5e0725e32330137c505146270a2fc84Steve Blockbool JavaNPObjectInvoke(NPObject* obj, NPIdentifier identifier, const NPVariant* args, uint32_t argCount, NPVariant* result) 11109e3a0d3e5e0725e32330137c505146270a2fc84Steve Block{ 112b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian JavaInstance* instance = ExtractJavaInstance(obj); 11354dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block if (!instance) 114b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return false; 11502a23642eaae7e2fdd441eddffd2c085fbee3b49Ben Murdoch NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); 11654dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block if (!name) 117b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return false; 118b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian 11988d4517612dafdcaff7a98f2a68ff071e2734ea6Steve Block instance->begin(); 120b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian 1212bde8e466a4451c7319e3a072d118917957d6554Steve Block MethodList methodList = instance->getClass()->methodsNamed(name); 122b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian // TODO: use NPN_MemFree 123b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian free(name); 1242bde8e466a4451c7319e3a072d118917957d6554Steve Block 1252bde8e466a4451c7319e3a072d118917957d6554Steve Block // Try to find a good match for the overloaded method. The 1262bde8e466a4451c7319e3a072d118917957d6554Steve Block // fundamental problem is that JavaScript doesn't have the 1272bde8e466a4451c7319e3a072d118917957d6554Steve Block // notion of method overloading and Java does. We could 1282bde8e466a4451c7319e3a072d118917957d6554Steve Block // get a bit more sophisticated and attempt to do some 1292bde8e466a4451c7319e3a072d118917957d6554Steve Block // type checking as well as checking the number of parameters. 1302bde8e466a4451c7319e3a072d118917957d6554Steve Block size_t numMethods = methodList.size(); 1312bde8e466a4451c7319e3a072d118917957d6554Steve Block JavaMethod* aMethod; 1322bde8e466a4451c7319e3a072d118917957d6554Steve Block JavaMethod* jMethod = 0; 1332bde8e466a4451c7319e3a072d118917957d6554Steve Block for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) { 1342bde8e466a4451c7319e3a072d118917957d6554Steve Block aMethod = methodList[methodIndex]; 1352bde8e466a4451c7319e3a072d118917957d6554Steve Block if (aMethod->numParameters() == static_cast<int>(argCount)) { 1362bde8e466a4451c7319e3a072d118917957d6554Steve Block jMethod = aMethod; 1372bde8e466a4451c7319e3a072d118917957d6554Steve Block break; 1382bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1392bde8e466a4451c7319e3a072d118917957d6554Steve Block } 1401b90d74d66fbb55d40e5e87a84423acd81ab062aSteve Block if (!jMethod) { 1411b90d74d66fbb55d40e5e87a84423acd81ab062aSteve Block instance->end(); 1422bde8e466a4451c7319e3a072d118917957d6554Steve Block return false; 1431b90d74d66fbb55d40e5e87a84423acd81ab062aSteve Block } 1442bde8e466a4451c7319e3a072d118917957d6554Steve Block 1452bde8e466a4451c7319e3a072d118917957d6554Steve Block JavaValue* jArgs = new JavaValue[argCount]; 1462bde8e466a4451c7319e3a072d118917957d6554Steve Block for (unsigned int i = 0; i < argCount; i++) 1472bde8e466a4451c7319e3a072d118917957d6554Steve Block jArgs[i] = convertNPVariantToJavaValue(args[i], jMethod->parameterAt(i)); 1482bde8e466a4451c7319e3a072d118917957d6554Steve Block 149cb3fc20cd59c3956ace2b6b9966da170b92b9162Steve Block// ANDROID 150cb3fc20cd59c3956ace2b6b9966da170b92b9162Steve Block bool exceptionOccurred; 151cb3fc20cd59c3956ace2b6b9966da170b92b9162Steve Block JavaValue jResult = instance->invokeMethod(jMethod, jArgs, exceptionOccurred); 1522bde8e466a4451c7319e3a072d118917957d6554Steve Block instance->end(); 1532bde8e466a4451c7319e3a072d118917957d6554Steve Block delete[] jArgs; 1542bde8e466a4451c7319e3a072d118917957d6554Steve Block 155cb3fc20cd59c3956ace2b6b9966da170b92b9162Steve Block if (exceptionOccurred) 156cb3fc20cd59c3956ace2b6b9966da170b92b9162Steve Block return false; 157cb3fc20cd59c3956ace2b6b9966da170b92b9162Steve Block// END ANDROID 158cb3fc20cd59c3956ace2b6b9966da170b92b9162Steve Block 1592bde8e466a4451c7319e3a072d118917957d6554Steve Block VOID_TO_NPVARIANT(*result); 1602bde8e466a4451c7319e3a072d118917957d6554Steve Block convertJavaValueToNPVariant(jResult, result); 1612bde8e466a4451c7319e3a072d118917957d6554Steve Block return true; 1627fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian} 1637fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 16409e3a0d3e5e0725e32330137c505146270a2fc84Steve Blockbool JavaNPObjectHasProperty(NPObject* obj, NPIdentifier identifier) 16509e3a0d3e5e0725e32330137c505146270a2fc84Steve Block{ 166b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian JavaInstance* instance = ExtractJavaInstance(obj); 16754dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block if (!instance) 168b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return false; 16902a23642eaae7e2fdd441eddffd2c085fbee3b49Ben Murdoch NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); 17054dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block if (!name) 171b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return false; 17288d4517612dafdcaff7a98f2a68ff071e2734ea6Steve Block instance->begin(); 17354dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block bool result = instance->getClass()->fieldNamed(name); 17488d4517612dafdcaff7a98f2a68ff071e2734ea6Steve Block instance->end(); 175b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian free(name); 176b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return result; 1777fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian} 1787fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 17909e3a0d3e5e0725e32330137c505146270a2fc84Steve Blockbool JavaNPObjectGetProperty(NPObject* obj, NPIdentifier identifier, NPVariant* result) 18009e3a0d3e5e0725e32330137c505146270a2fc84Steve Block{ 181b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian VOID_TO_NPVARIANT(*result); 182b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian JavaInstance* instance = ExtractJavaInstance(obj); 18354dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block if (!instance) 184b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return false; 18502a23642eaae7e2fdd441eddffd2c085fbee3b49Ben Murdoch NPUTF8* name = _NPN_UTF8FromIdentifier(identifier); 18654dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block if (!name) 187b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return false; 1887fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 18988d4517612dafdcaff7a98f2a68ff071e2734ea6Steve Block instance->begin(); 190b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian JavaField* field = instance->getClass()->fieldNamed(name); 19109e3a0d3e5e0725e32330137c505146270a2fc84Steve Block free(name); // TODO: use NPN_MemFree 1921b90d74d66fbb55d40e5e87a84423acd81ab062aSteve Block if (!field) { 1931b90d74d66fbb55d40e5e87a84423acd81ab062aSteve Block instance->end(); 194b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return false; 1951b90d74d66fbb55d40e5e87a84423acd81ab062aSteve Block } 196b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian 1972d44f555f1b58dea94258c21592a95e78fe5bc21Steve Block#if PLATFORM(ANDROID) 198ee6ca70ca284d2333863f121123b1812043deb33Ben Murdoch // JSC does not seem to support returning object properties so we emulate that 199ee6ca70ca284d2333863f121123b1812043deb33Ben Murdoch // behaviour here. 2009c8e65377a8462e90abc85e3d888365f7fecf9e3Steve Block JavaValue value; 201ee6ca70ca284d2333863f121123b1812043deb33Ben Murdoch#else 2022bde8e466a4451c7319e3a072d118917957d6554Steve Block JavaValue value = instance->getField(field); 2039c8e65377a8462e90abc85e3d888365f7fecf9e3Steve Block#endif // PLATFORM(ANDROID) 2042bde8e466a4451c7319e3a072d118917957d6554Steve Block instance->end(); 2052bde8e466a4451c7319e3a072d118917957d6554Steve Block 2062bde8e466a4451c7319e3a072d118917957d6554Steve Block convertJavaValueToNPVariant(value, result); 207b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian 208b2318f335c407832166c7568f3e50afedad5b9dbFeng Qian return true; 2097fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian} 2107fa30a60f66c19c8e6fb91ef799bca4d8d6f57f2Feng Qian 21109e3a0d3e5e0725e32330137c505146270a2fc84Steve Block} // namespace Bindings 21254dec9637e20bfba1857f3d54df3c43ce94ff97bSteve Block 21309e3a0d3e5e0725e32330137c505146270a2fc84Steve Block} // namespace JSC 21481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch 21581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif // ENABLE(JAVA_BRIDGE) 216