summaryrefslogtreecommitdiffstats
path: root/V8Binding/jni
diff options
context:
space:
mode:
authorFeng Qian <fqian@google.com>2009-04-30 20:00:54 -0700
committerFeng Qian <fqian@google.com>2009-04-30 20:00:54 -0700
commitb2318f335c407832166c7568f3e50afedad5b9db (patch)
treeeab734e32d524e57fe074d4790513bb7dc3ea431 /V8Binding/jni
parentffdfe220d2fa9a605c4f5ea060ceb90b80c919f0 (diff)
downloadexternal_webkit-b2318f335c407832166c7568f3e50afedad5b9db.zip
external_webkit-b2318f335c407832166c7568f3e50afedad5b9db.tar.gz
external_webkit-b2318f335c407832166c7568f3e50afedad5b9db.tar.bz2
Implement Java <-> JS bindings.
Implemented invoke Java methods and fecth Java fields from JavaScript. Java-side access native-JS objects is not supported. JavaScript-side modification of JS objects is not supported. The implementation uses NPAPI, which is simple, but less efficient. Java abstraction is very much copied from original WebCore/bridge/jni, except all JSC bindings are replaced by NPAPI.
Diffstat (limited to 'V8Binding/jni')
-rw-r--r--V8Binding/jni/jni_class.cpp43
-rw-r--r--V8Binding/jni/jni_class.h15
-rw-r--r--V8Binding/jni/jni_instance.cpp95
-rw-r--r--V8Binding/jni/jni_instance.h32
-rw-r--r--V8Binding/jni/jni_npobject.cpp137
-rw-r--r--V8Binding/jni/jni_npobject.h42
-rw-r--r--V8Binding/jni/jni_runtime.cpp117
-rw-r--r--V8Binding/jni/jni_runtime.h24
-rw-r--r--V8Binding/jni/jni_utility.cpp113
-rw-r--r--V8Binding/jni/jni_utility.h7
10 files changed, 419 insertions, 206 deletions
diff --git a/V8Binding/jni/jni_class.cpp b/V8Binding/jni/jni_class.cpp
index 4e3b5f9..1c68d66 100644
--- a/V8Binding/jni/jni_class.cpp
+++ b/V8Binding/jni/jni_class.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,13 +25,8 @@
*/
#include "config.h"
-#include "jni_class.h"
-
-#if ENABLE(MAC_JAVA_BRIDGE)
-#include "JSDOMWindow.h"
-#include <runtime/Identifier.h>
-#include <runtime/JSLock.h>
+#include "jni_class.h"
#include "jni_utility.h"
#include "jni_runtime.h"
@@ -60,7 +56,6 @@ JavaClass::JavaClass(jobject anInstance)
jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
JavaField *aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
{
- JSLock lock(false);
_fields.set(aField->name(), aField);
}
env->DeleteLocalRef(aJField);
@@ -74,8 +69,6 @@ JavaClass::JavaClass(jobject anInstance)
JavaMethod *aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor
MethodList* methodList;
{
- JSLock lock(false);
-
methodList = _methods.get(aMethod->name());
if (!methodList) {
methodList = new MethodList();
@@ -95,8 +88,6 @@ JavaClass::JavaClass(jobject anInstance)
JavaClass::~JavaClass() {
free((void *)_name);
- JSLock lock(false);
-
deleteAllValues(_fields);
_fields.clear();
@@ -109,38 +100,16 @@ JavaClass::~JavaClass() {
_methods.clear();
}
-MethodList JavaClass::methodsNamed(const Identifier& identifier, Instance*) const
+MethodList JavaClass::methodsNamed(const char* name) const
{
- MethodList *methodList = _methods.get(identifier.ustring().rep());
+ MethodList *methodList = _methods.get(name);
if (methodList)
return *methodList;
return MethodList();
}
-Field *JavaClass::fieldNamed(const Identifier& identifier, Instance*) const
-{
- return _fields.get(identifier.ustring().rep());
-}
-
-bool JavaClass::isNumberClass() const
+JavaField* JavaClass::fieldNamed(const char* name) const
{
- return ((strcmp(_name, "java.lang.Byte") == 0 ||
- strcmp(_name, "java.lang.Short") == 0 ||
- strcmp(_name, "java.lang.Integer") == 0 ||
- strcmp(_name, "java.lang.Long") == 0 ||
- strcmp(_name, "java.lang.Float") == 0 ||
- strcmp(_name, "java.lang.Double") == 0) );
+ return _fields.get(name);
}
-
-bool JavaClass::isBooleanClass() const
-{
- return strcmp(_name, "java.lang.Boolean") == 0;
-}
-
-bool JavaClass::isStringClass() const
-{
- return strcmp(_name, "java.lang.String") == 0;
-}
-
-#endif // ENABLE(MAC_JAVA_BRIDGE)
diff --git a/V8Binding/jni/jni_class.h b/V8Binding/jni/jni_class.h
index 2865be5..58787d3 100644
--- a/V8Binding/jni/jni_class.h
+++ b/V8Binding/jni/jni_class.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,22 +29,30 @@
#include <jni_runtime.h>
#include <wtf/HashMap.h>
+#include <wtf/Vector.h>
+#include "PlatformString.h"
+#include "StringHash.h"
namespace JSC {
namespace Bindings {
typedef Vector<JavaMethod*> MethodList;
-class JavaClass
+typedef HashMap<WebCore::String, MethodList*> MethodListMap;
+typedef HashMap<WebCore::String, JavaField*> FieldMap;
+
+class JavaClass {
public:
JavaClass (jobject anInstance);
~JavaClass ();
- MethodList methodsNamed(NPIdentifier name, Instance* instance) const;
-
+ MethodList methodsNamed(const char* name) const;
+ JavaField* fieldNamed(const char* name) const;
+
private:
const char *_name;
MethodListMap _methods;
+ FieldMap _fields;
};
} // namespace Bindings
diff --git a/V8Binding/jni/jni_instance.cpp b/V8Binding/jni/jni_instance.cpp
index 887886e..9204ba7 100644
--- a/V8Binding/jni/jni_instance.cpp
+++ b/V8Binding/jni/jni_instance.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003, 2008 Apple Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,6 +26,7 @@
#include "config.h"
+#include "jni_class.h"
#include "jni_instance.h"
#include "jni_runtime.h"
#include "jni_utility.h"
@@ -44,20 +46,32 @@ using namespace JSC::Bindings;
JavaInstance::JavaInstance (jobject instance)
{
- _instance = new JObjectWrapper (instance);
+ _instance = new JObjectWrapper(instance);
+ _class = 0;
}
JavaInstance::~JavaInstance ()
{
+ delete _class;
}
-#define NUM_LOCAL_REFS 64
+JavaClass* JavaInstance::getClass() const
+{
+ if (_class == 0)
+ _class = new JavaClass(_instance->_instance);
+ return _class;
+}
-bool JavaInstance::invokeMethod(NPIdentifier methodName, NPVariant* args, uint32_t count, NPVariant* resultValue)
+bool JavaInstance::invokeMethod(const char* methodName, const NPVariant* args, uint32_t count, NPVariant* resultValue)
{
int i;
jvalue *jArgs;
- Method *method = 0;
+ JavaMethod *method = 0;
+
+ VOID_TO_NPVARIANT(*resultValue);
+
+ MethodList methodList = getClass()->methodsNamed(methodName);
+
size_t numMethods = methodList.size();
// Try to find a good match for the overloaded method. The
@@ -65,7 +79,7 @@ bool JavaInstance::invokeMethod(NPIdentifier methodName, NPVariant* args, uint32
// notion of method overloading and Java does. We could
// get a bit more sophisticated and attempt to does some
// type checking as we as checking the number of parameters.
- Method *aMethod;
+ JavaMethod *aMethod;
for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) {
aMethod = methodList[methodIndex];
if (aMethod->numParameters() == count) {
@@ -75,7 +89,7 @@ bool JavaInstance::invokeMethod(NPIdentifier methodName, NPVariant* args, uint32
}
if (method == 0) {
JS_LOG ("unable to find an appropiate method\n");
- return jsUndefined();
+ return false;
}
const JavaMethod *jMethod = static_cast<const JavaMethod*>(method);
@@ -134,74 +148,11 @@ bool JavaInstance::invokeMethod(NPIdentifier methodName, NPVariant* args, uint32
break;
}
}
-
- switch (jMethod->JNIReturnType()){
- case void_type: {
- VOID_TO_NPVARIANT(*resultValue);
- }
- break;
-
- case object_type: {
- if (result.l != 0) {
- OBJECT_TO_NPVARIANT(JavaObjectToNPObject(JavaInstance::create(result.l)), *resultValue);
- }
- else {
- VOID_TO_NPVARIANT(*resultValue);
- }
- }
- break;
-
- case boolean_type: {
- BOOLEAN_TO_NPVARIANT(result.z, *resultValue);
- }
- break;
-
- case byte_type: {
- INT32_TO_NPVARIANT(result.b, *resultValue);
- }
- break;
-
- case char_type: {
- INT32_TO_NPVARIANT(result.c, *resultValue);
- }
- break;
-
- case short_type: {
- INT32_TO_NPVARIANT(result.s, *resultValue);
- }
- break;
-
- case int_type: {
- INT32_TO_NPVARIANT(result.i, *resultValue);
- }
- break;
-
- // TODO(fqian): check if cast to double is needed.
- case long_type: {
- DOUBLE_TO_NPVARIANT(result.j, *resultValue);
- }
- break;
-
- case float_type: {
- DOUBLE_TO_NPVARIANT(result.f, *resultValue);
- }
- break;
-
- case double_type: {
- DOUBLE_TO_NPVARIANT(result.d, *resultValue);
- }
- break;
-
- case invalid_type:
- default: {
- VOID_TO_NPVARIANT(*resultValue);
- }
- break;
- }
-
+
+ convertJValueToNPVariant(result, jMethod->JNIReturnType(), resultValue);
free (jArgs);
- return resultValue;
+ return true;
}
JObjectWrapper::JObjectWrapper(jobject instance)
diff --git a/V8Binding/jni/jni_instance.h b/V8Binding/jni/jni_instance.h
index 5fa4141..0ee487e 100644
--- a/V8Binding/jni/jni_instance.h
+++ b/V8Binding/jni/jni_instance.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,24 +28,24 @@
#define _JNI_INSTANCE_H_
#include <JavaVM/jni.h>
+#include <wtf/RefPtr.h>
namespace android {
class WeakJavaInstance;
}
+using namespace WTF;
+
namespace JSC {
namespace Bindings {
+class JavaClass;
+
class JObjectWrapper
{
-friend class RefPtr<JObjectWrapper>;
-friend class JavaArray;
friend class JavaInstance;
-friend class JavaMethod;
-friend class android::WeakJavaInstance;
-
-protected:
+public:
JObjectWrapper(jobject instance);
~JObjectWrapper();
@@ -55,31 +56,28 @@ protected:
delete this;
}
- jobject _instance;
-
private:
JNIEnv *_env;
unsigned int _refCount;
+ jobject _instance;
};
class JavaInstance
{
public:
- static PassRefPtr<JavaInstance> create(jobject instance)
- {
- return adoptRef(new JavaInstance(instance));
- }
-
+ JavaInstance(jobject instance);
~JavaInstance();
-
- NPVariant invokeMethod(NPIdentifier methodName, NPVariant* args, uint32_t argsCount);
+
+ JavaClass* getClass() const;
+
+ bool invokeMethod(const char* name, const NPVariant* args, uint32_t argsCount, NPVariant* result);
jobject javaInstance() const { return _instance->_instance; }
private:
- JavaInstance(jobject instance);
-
RefPtr<JObjectWrapper> _instance;
+ unsigned int _refCount;
+ mutable JavaClass* _class;
};
} // namespace Bindings
diff --git a/V8Binding/jni/jni_npobject.cpp b/V8Binding/jni/jni_npobject.cpp
index daa26a8..7b315ab 100644
--- a/V8Binding/jni/jni_npobject.cpp
+++ b/V8Binding/jni/jni_npobject.cpp
@@ -1,46 +1,149 @@
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include "config.h"
#include "jni_npobject.h"
+#include "jni_class.h"
+#include "jni_instance.h"
+#include "jni_runtime.h"
+#include "jni_utility.h"
-namespace V8 { namespace Binding {
+namespace JSC { namespace Bindings {
+static NPObject* AllocJavaNPObject(NPP, NPClass*)
+{
+ return static_cast<NPObject*>(malloc(sizeof(JavaNPObject)));
+}
+
+static void FreeJavaNPObject(NPObject* npobj)
+{
+ JavaNPObject* obj = reinterpret_cast<JavaNPObject*>(npobj);
+ free(obj);
+}
-static NPClass JavaNPClass = {
+static NPClass JavaNPObjectClass = {
NP_CLASS_STRUCT_VERSION,
- 0, // allocate,
- 0, // free,
+ AllocJavaNPObject, // allocate,
+ FreeJavaNPObject, // free,
0, // invalidate
JavaNPObject_HasMethod,
JavaNPObject_Invoke,
0, // invokeDefault,
JavaNPObject_HasProperty,
- JavaNPobject_GetProperty,
- JavaNPObject_SetProperty,
+ JavaNPObject_GetProperty,
+ 0, // setProperty
0, // removeProperty
0, // enumerate
0 // construct
};
-NPObject* JavaInstanceToNPObject(PassRefPtr<JavaInstance> instance) {
- JavaNPObject* object = new JavaNPObject(instance);
- return static_cast<NPObject*>(object);
+
+NPObject* JavaInstanceToNPObject(JavaInstance* instance) {
+ JavaNPObject* object = reinterpret_cast<JavaNPObject*>(NPN_CreateObject(0, &JavaNPObjectClass));
+ object->_instance = instance;
+ return reinterpret_cast<NPObject*>(object);
}
-bool JavaNPObject_HasMethod(NPObject* obj, NPIdentifier name) {
- // FIXME: for now, always pretend the object has the named method.
- return true;
+
+// Returns null if obj is not a wrapper of JavaInstance
+JavaInstance* ExtractJavaInstance(NPObject* obj) {
+ if (obj->_class == &JavaNPObjectClass) {
+ return reinterpret_cast<JavaNPObject*>(obj)->_instance;
+ }
+ return 0;
}
-bool JavaNPObject_Invoke(NPobject* obj, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result) {
+bool JavaNPObject_HasMethod(NPObject* obj, NPIdentifier identifier) {
+ JavaInstance* instance = ExtractJavaInstance(obj);
+ if (instance == 0)
+ return false;
+ NPUTF8* name = NPN_UTF8FromIdentifier(identifier);
+ if (name == 0)
+ return false;
+
+ bool result = (instance->getClass()->methodsNamed(name).size() > 0);
+ // TODO: use NPN_MemFree
+ free(name);
+
+ return result;
}
-bool JavaNPObject_HasProperty(NPObject* obj, NPIdentifier name) {
+bool JavaNPObject_Invoke(NPObject* obj, NPIdentifier identifier,
+ const NPVariant* args, uint32_t argCount, NPVariant* result) {
+ JavaInstance* instance = ExtractJavaInstance(obj);
+ if (instance == 0)
+ return false;
+ NPUTF8* name = NPN_UTF8FromIdentifier(identifier);
+ if (name == 0)
+ return false;
+
+ bool r = instance->invokeMethod(name, args, argCount, result);
+
+ // TODO: use NPN_MemFree
+ free(name);
+ return r;
+
}
-bool JavaNPObject_GetProperty(NPObject* obj, NPIdentifier name, NPVariant* ressult) {
+bool JavaNPObject_HasProperty(NPObject* obj, NPIdentifier identifier) {
+ JavaInstance* instance = ExtractJavaInstance(obj);
+ if (instance == 0)
+ return false;
+ NPUTF8* name = NPN_UTF8FromIdentifier(identifier);
+ if (name == 0)
+ return false;
+ bool result = instance->getClass()->fieldNamed(name) != 0;
+ free(name);
+ return result;
}
-bool JavaNPObject_SetProperty(NPObject* obj, NPIdentifier name, const NPVariant* value) {
+bool JavaNPObject_GetProperty(NPObject* obj, NPIdentifier identifier, NPVariant* result) {
+ VOID_TO_NPVARIANT(*result);
+ JavaInstance* instance = ExtractJavaInstance(obj);
+ if (instance == 0)
+ return false;
+ NPUTF8* name = NPN_UTF8FromIdentifier(identifier);
+ if (name == 0)
+ return false;
+ JavaField* field = instance->getClass()->fieldNamed(name);
+ free(name); // TODO: use NPN_MemFree
+
+ if (field == 0) {
+ return false;
+ }
+
+ jvalue value = getJNIField(instance->javaInstance(),
+ field->getJNIType(),
+ field->name(),
+ field->type());
+ convertJValueToNPVariant(value, field->getJNIType(), result);
+
+ return true;
}
-} } // namespace V8::Binding
+}} // namespace
diff --git a/V8Binding/jni/jni_npobject.h b/V8Binding/jni/jni_npobject.h
index 99fe368..9ba8ced 100644
--- a/V8Binding/jni/jni_npobject.h
+++ b/V8Binding/jni/jni_npobject.h
@@ -1,26 +1,52 @@
-// A wrapper of a JNI value as an NPObject
-
+/*
+ * Copyright 2009, The Android Open Source Project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
#ifndef JNI_NPOBJECT_H_
#define JNI_NPOBJECT_H_
-#include "npapi.h"
+#include "npruntime.h"
+#include "jni_runtime.h"
+
#include <JavaVM/jni.h>
-namespace V8 { namespace V8Binding {
+namespace JSC { namespace Bindings {
struct JavaNPObject {
NPObject _object;
- RefPtr<JavaInstance> _instance;
+ JavaInstance* _instance;
+
+ ~JavaNPObject() { delete _instance; }
};
-NPObject* JavaInstanceToNPObject(PassRefPtr<JavaInstance> instance);
+NPObject* JavaInstanceToNPObject(JavaInstance* instance);
+JavaInstance* ExtractJavaInstance(NPObject* obj);
bool JavaNPObject_HasMethod(NPObject* obj, NPIdentifier name);
-bool JavaNPObject_Invoke(NPobject* obj, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result);
+bool JavaNPObject_Invoke(NPObject* obj, NPIdentifier methodName, const NPVariant* args, uint32_t argCount, NPVariant* result);
bool JavaNPObject_HasProperty(NPObject* obj, NPIdentifier name);
bool JavaNPObject_GetProperty(NPObject* obj, NPIdentifier name, NPVariant* ressult);
-bool JavaNPObject_SetProperty(NPObject* obj, NPIdentifier name, const NPVariant* value);
} }
diff --git a/V8Binding/jni/jni_runtime.cpp b/V8Binding/jni/jni_runtime.cpp
index 1ff640a..9c87c54 100644
--- a/V8Binding/jni/jni_runtime.cpp
+++ b/V8Binding/jni/jni_runtime.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -46,6 +47,22 @@ JavaParameter::JavaParameter (JNIEnv *env, jstring type)
}
+JavaField::JavaField (JNIEnv *env, jobject aField)
+{
+ // Get field type
+ jobject fieldType = callJNIMethod<jobject>(aField, "getType", "()Ljava/lang/Class;");
+ jstring fieldTypeName = (jstring)callJNIMethod<jobject>(fieldType, "getName", "()Ljava/lang/String;");
+ _type = JavaString(env, fieldTypeName);
+ _JNIType = JNITypeFromClassName (_type.UTF8String());
+
+ // Get field name
+ jstring fieldName = (jstring)callJNIMethod<jobject>(aField, "getName", "()Ljava/lang/String;");
+ _name = JavaString(env, fieldName);
+
+ _field = new JObjectWrapper(aField);
+}
+
+
JavaMethod::JavaMethod (JNIEnv *env, jobject aMethod)
{
// Get return type
@@ -95,41 +112,93 @@ JavaMethod::~JavaMethod()
delete [] _parameters;
};
-// JNI method signatures use '/' between components of a class name, but
-// we get '.' between components from the reflection API.
-static void appendClassName(UString& aString, const char* className)
-{
- ASSERT(JSLock::lockCount() > 0);
-
- char *result, *cp = strdup(className);
+
+class SignatureBuilder {
+public:
+ explicit SignatureBuilder(int init_size) {
+ if (init_size <= 0)
+ init_size = 16;
+ size_ = init_size;
+ length_ = 0;
+ storage_ = (char*)malloc(size_ * sizeof(char));
+ }
+
+ ~SignatureBuilder() {
+ free(storage_);
+ }
+
+ void append(const char* s) {
+ int l = strlen(s);
+ expandIfNeeded(l);
+ memcpy(storage_ + length_, s, l);
+ length_ += l;
+ }
+
+ // JNI method signatures use '/' between components of a class name, but
+ // we get '.' between components from the reflection API.
+ void appendClassName(const char* className) {
+ int l = strlen(className);
+ expandIfNeeded(l);
+
+ char* sp = storage_ + length_;
+ const char* cp = className;
- result = cp;
- while (*cp) {
- if (*cp == '.')
- *cp = '/';
- cp++;
+ while (*cp) {
+ if (*cp == '.')
+ *sp = '/';
+ else
+ *sp = *cp;
+
+ cp++;
+ sp++;
+ }
+
+ length_ += l;
}
-
- aString.append(result);
- free (result);
-}
+ // make a duplicated copy of the content.
+ char* ascii() {
+ if (length_ == 0)
+ return NULL;
+ storage_[length_] = '\0';
+ return strndup(storage_, length_);
+ }
+
+private:
+ void expandIfNeeded(int l) {
+ // expand storage if needed
+ if (l + length_ >= size_) {
+ int new_size = 2 * size_;
+ if (l + length_ >= new_size)
+ new_size = l + length_ + 1;
+
+ char* new_storage = (char*)malloc(new_size * sizeof(char));
+ memcpy(new_storage, storage_, length_);
+ size_ = new_size;
+ free(storage_);
+ storage_ = new_storage;
+ }
+ }
+
+ int size_;
+ int length_;
+ char* storage_;
+};
const char *JavaMethod::signature() const
{
if (!_signature) {
- JSLock lock(false);
-
- UString signatureBuilder("(");
+ SignatureBuilder signatureBuilder(64);
+ signatureBuilder.append("(");
for (int i = 0; i < _numParameters; i++) {
JavaParameter* aParameter = parameterAt(i);
JNIType _JNIType = aParameter->getJNIType();
if (_JNIType == array_type)
- appendClassName(signatureBuilder, aParameter->type());
+ signatureBuilder.appendClassName(aParameter->type());
else {
signatureBuilder.append(signatureFromPrimitiveType(_JNIType));
if (_JNIType == object_type) {
- appendClassName(signatureBuilder, aParameter->type());
+ signatureBuilder.appendClassName(aParameter->type());
signatureBuilder.append(";");
}
}
@@ -138,16 +207,16 @@ const char *JavaMethod::signature() const
const char *returnType = _returnType.UTF8String();
if (_JNIReturnType == array_type) {
- appendClassName(signatureBuilder, returnType);
+ signatureBuilder.appendClassName(returnType);
} else {
signatureBuilder.append(signatureFromPrimitiveType(_JNIReturnType));
if (_JNIReturnType == object_type) {
- appendClassName(signatureBuilder, returnType);
+ signatureBuilder.appendClassName(returnType);
signatureBuilder.append(";");
}
}
- _signature = strdup(signatureBuilder.ascii());
+ _signature = signatureBuilder.ascii();
}
return _signature;
diff --git a/V8Binding/jni/jni_runtime.h b/V8Binding/jni/jni_runtime.h
index 932f26b..0e3f98f 100644
--- a/V8Binding/jni/jni_runtime.h
+++ b/V8Binding/jni/jni_runtime.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -62,16 +63,17 @@ public:
~JavaString() { }
- int length() const { return _utf8String->length(); }
+ int length() const { return _utf8String.length(); }
const char* UTF8String() const {
- return _utf8String.c_str();
+ return _utf8String.data();
}
private:
WebCore::CString _utf8String;
};
+
class JavaParameter
{
public:
@@ -88,6 +90,24 @@ private:
};
+class JavaField
+{
+public:
+ JavaField (JNIEnv *env, jobject aField);
+
+ const char* name() const { return _name.UTF8String(); }
+ const char* type() const { return _type.UTF8String(); }
+
+ JNIType getJNIType() const { return _JNIType; }
+
+private:
+ JavaString _name;
+ JavaString _type;
+ JNIType _JNIType;
+ RefPtr<JObjectWrapper> _field;
+};
+
+
class JavaMethod
{
public:
diff --git a/V8Binding/jni/jni_utility.cpp b/V8Binding/jni/jni_utility.cpp
index d86dd7b..5ab2041 100644
--- a/V8Binding/jni/jni_utility.cpp
+++ b/V8Binding/jni/jni_utility.cpp
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -24,8 +25,10 @@
*/
#include "config.h"
+#include "npruntime.h"
#include "jni_utility.h"
#include "jni_runtime.h"
+#include "jni_npobject.h"
#include <dlfcn.h>
@@ -342,10 +345,10 @@ jvalue getJNIField( jobject obj, JNIType type, const char *name, const char *sig
}
-jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char* javaClassName)
+jvalue convertNPVariantToJValue(NPVariant value, JNIType _JNIType, const char* javaClassName)
{
jvalue result;
- NPVariantType type = value->type;
+ NPVariantType type = value.type;
switch (_JNIType){
case array_type:
@@ -354,13 +357,9 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
// First see if we have a Java instance.
if (type == NPVariantType_Object) {
- NPObject* objectImp = NPVARIANT_TO_OBJECT(*value);
- if (objectImp->_class == &JavaNPClass) {
- JavaNPObject* imp = static_cast<JavaNPObject*>(objectImp);
- JavaInstance *instance = imp->_instance;
- if (instance)
- result.l = instance->javaInstance();
- }
+ NPObject* objectImp = NPVARIANT_TO_OBJECT(value);
+ if (JavaInstance* instance = ExtractJavaInstance(objectImp))
+ result.l = instance->javaInstance();
}
// Now convert value to a string if the target type is a java.lang.string, and we're not
@@ -377,9 +376,9 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
#else
if (type == NPVariantType_String) {
#endif
- NPString src = NPVARIANT_TO_STRING(*variant);
+ NPString src = NPVARIANT_TO_STRING(value);
JNIEnv *env = getJNIEnv();
- jobject javaString = env->functions->NewStringUTF(env, src.UTF8Characters, src.UTF8Length);
+ jobject javaString = env->NewStringUTF(src.UTF8Characters);
result.l = javaString;
}
} else if (result.l == 0)
@@ -388,8 +387,8 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
break;
case boolean_type: {
- if (type == NPVariantType_Boolean)
- result.z = NPVARIANT_TO_BOOLEAN(*value);
+ if (type == NPVariantType_Bool)
+ result.z = NPVARIANT_TO_BOOLEAN(value);
else
bzero(&result, sizeof(jvalue)); // as void case
}
@@ -397,7 +396,7 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
case byte_type: {
if (type == NPVariantType_Int32)
- result.b = (byte)NPVARIANT_TO_INT32(*value);
+ result.b = (char)NPVARIANT_TO_INT32(value);
else
bzero(&result, sizeof(jvalue));
}
@@ -405,7 +404,7 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
case char_type: {
if (type == NPVariantType_Int32)
- result.c = (char)NPVARIANT_TO_INT32(*value);
+ result.c = (char)NPVARIANT_TO_INT32(value);
else
bzero(&result, sizeof(jvalue));
}
@@ -413,7 +412,7 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
case short_type: {
if (type == NPVariantType_Int32)
- result.s = (jshort)NPVARIANT_TO_INT32(*value);
+ result.s = (jshort)NPVARIANT_TO_INT32(value);
else
bzero(&result, sizeof(jvalue));
}
@@ -421,7 +420,7 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
case int_type: {
if (type == NPVariantType_Int32)
- result.i = (jint)NPVARIANT_TO_INT32(*value);
+ result.i = (jint)NPVARIANT_TO_INT32(value);
else
bzero(&result, sizeof(jvalue));
}
@@ -429,9 +428,9 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
case long_type: {
if (type == NPVariantType_Int32)
- result.j = (jlong)NPVARIANT_TO_INT32(*value);
+ result.j = (jlong)NPVARIANT_TO_INT32(value);
else if (type == NPVariantType_Double)
- result.j = (jlong)NPVARIANT_TO_DOUBLE(*value);
+ result.j = (jlong)NPVARIANT_TO_DOUBLE(value);
else
bzero(&result, sizeof(jvalue));
}
@@ -439,9 +438,9 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
case float_type: {
if (type == NPVariantType_Int32)
- result.j = (jfloat)NPVARIANT_TO_INT32(*value);
+ result.j = (jfloat)NPVARIANT_TO_INT32(value);
else if (type == NPVariantType_Double)
- result.j = (jfloat)NPVARIANT_TO_DOUBLE(*value);
+ result.j = (jfloat)NPVARIANT_TO_DOUBLE(value);
else
bzero(&result, sizeof(jvalue));
}
@@ -449,9 +448,9 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
case double_type: {
if (type == NPVariantType_Int32)
- result.j = (jdouble)NPVARIANT_TO_INT32(*value);
+ result.j = (jdouble)NPVARIANT_TO_INT32(value);
else if (type == NPVariantType_Double)
- result.j = (jdouble)NPVARIANT_TO_DOUBLE(*value);
+ result.j = (jdouble)NPVARIANT_TO_DOUBLE(value);
else
bzero(&result, sizeof(jvalue));
}
@@ -469,6 +468,74 @@ jvalue convertNPVariantToJValue(NPVariant* value, JNIType _JNIType, const char*
return result;
}
+
+void convertJValueToNPVariant(jvalue value, JNIType _JNIType, NPVariant* result)
+{
+ switch (_JNIType){
+ case void_type: {
+ VOID_TO_NPVARIANT(*result);
+ }
+ break;
+
+ case object_type: {
+ if (value.l != 0) {
+ OBJECT_TO_NPVARIANT(JavaInstanceToNPObject(new JavaInstance(value.l)), *result);
+ }
+ else {
+ VOID_TO_NPVARIANT(*result);
+ }
+ }
+ break;
+
+ case boolean_type: {
+ BOOLEAN_TO_NPVARIANT(value.z, *result);
+ }
+ break;
+
+ case byte_type: {
+ INT32_TO_NPVARIANT(value.b, *result);
+ }
+ break;
+
+ case char_type: {
+ INT32_TO_NPVARIANT(value.c, *result);
+ }
+ break;
+
+ case short_type: {
+ INT32_TO_NPVARIANT(value.s, *result);
+ }
+ break;
+
+ case int_type: {
+ INT32_TO_NPVARIANT(value.i, *result);
+ }
+ break;
+
+ // TODO(fqian): check if cast to double is needed.
+ case long_type: {
+ DOUBLE_TO_NPVARIANT(value.j, *result);
+ }
+ break;
+
+ case float_type: {
+ DOUBLE_TO_NPVARIANT(value.f, *result);
+ }
+ break;
+
+ case double_type: {
+ DOUBLE_TO_NPVARIANT(value.d, *result);
+ }
+ break;
+
+ case invalid_type:
+ default: {
+ VOID_TO_NPVARIANT(*result);
+ }
+ break;
+ }
+}
+
} // end of namespace Bindings
} // end of namespace JSC
diff --git a/V8Binding/jni/jni_utility.h b/V8Binding/jni/jni_utility.h
index 28b0763..dfa97ef 100644
--- a/V8Binding/jni/jni_utility.h
+++ b/V8Binding/jni/jni_utility.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003 Apple Computer, Inc. All rights reserved.
+ * Copyright 2009, The Android Open Source Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +28,7 @@
#define _JNI_UTILITY_H_
#include <JavaVM/jni.h>
+#include "npruntime.h"
// The order of these items can not be modified as they are tightly
// bound with the JVM on Mac OSX. If new types need to be added, they
@@ -52,8 +54,6 @@ namespace JSC {
namespace Bindings {
-class JavaParameter;
-
const char *getCharactersFromJString(jstring aJString);
void releaseCharactersForJString(jstring aJString, const char *s);
@@ -66,7 +66,8 @@ JNIType JNITypeFromClassName(const char *name);
JNIType JNITypeFromPrimitiveType(char type);
const char *signatureFromPrimitiveType(JNIType type);
-jvalue convertNPVariantToJValue(NPVariant*, JNIType, const char* javaClassName);
+jvalue convertNPVariantToJValue(NPVariant, JNIType, const char* javaClassName);
+void convertJValueToNPVariant(jvalue, JNIType, NPVariant*);
jvalue getJNIField(jobject obj, JNIType type, const char *name, const char *signature);