diff options
author | Steve Block <steveblock@google.com> | 2010-01-26 12:49:16 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-01-26 12:49:16 +0000 |
commit | a96d9eff8bdc7ed33739f5779a8d40ab1b3ae24f (patch) | |
tree | 6182a1ceb1938a9afdf07e07b1b8c20cabd026bd | |
parent | f194ee8ea5e8e00930a6caddc3ef6f5031493c2b (diff) | |
download | external_webkit-a96d9eff8bdc7ed33739f5779a8d40ab1b3ae24f.zip external_webkit-a96d9eff8bdc7ed33739f5779a8d40ab1b3ae24f.tar.gz external_webkit-a96d9eff8bdc7ed33739f5779a8d40ab1b3ae24f.tar.bz2 |
Cherry-pick WebKit change 53849 to move JavaField and JavaArray from JNIBridge to JNIBridgeJSC
See http://trac.webkit.org/changeset/53849
This is required to sync the Android tree with webkit.org to allow unforking in WebCore/bridge.
Change-Id: Ic73bf8213ae677b69e763a6b04f8c94f7f1eaed1
-rw-r--r-- | WebCore/Android.jscbindings.mk | 1 | ||||
-rw-r--r-- | WebCore/ChangeLog | 25 | ||||
-rw-r--r-- | WebCore/GNUmakefile.am | 1 | ||||
-rw-r--r-- | WebCore/WebCore.xcodeproj/project.pbxproj | 8 | ||||
-rw-r--r-- | WebCore/bridge/jni/JNIBridge.cpp | 408 | ||||
-rw-r--r-- | WebCore/bridge/jni/JNIBridge.h | 46 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JNIBridgeJSC.cpp | 445 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JNIBridgeJSC.h | 89 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp | 2 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JavaClassJSC.h | 2 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp | 2 |
11 files changed, 577 insertions, 452 deletions
diff --git a/WebCore/Android.jscbindings.mk b/WebCore/Android.jscbindings.mk index 59daf8d..afe0787 100644 --- a/WebCore/Android.jscbindings.mk +++ b/WebCore/Android.jscbindings.mk @@ -191,6 +191,7 @@ LOCAL_SRC_FILES += \ bridge/c/c_utility.cpp \ bridge/jni/JNIBridge.cpp \ bridge/jni/JNIUtility.cpp \ + bridge/jni/jsc/JNIBridgeJSC.cpp \ bridge/jni/jsc/JNIUtilityPrivate.cpp \ bridge/jni/jsc/JavaClassJSC.cpp \ bridge/jni/jsc/JavaInstanceJSC.cpp \ diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog index 20bedf2..99241a4 100644 --- a/WebCore/ChangeLog +++ b/WebCore/ChangeLog @@ -1,3 +1,28 @@ +2010-01-26 Steve Block <steveblock@google.com> + + Reviewed by Adam Barth. + + Moves JSC-specific classes from bridge/jni/JNIBridge to bridge/jni/jsc/JNIBridgeJSC + https://bugs.webkit.org/show_bug.cgi?id=33958 + + This allows bridge/jni/JNIBridge to be used with both JSC and V8. + A later change will add the V8 equivalent of these JSC-specific classes. + + No new tests, refactoring only. + + * Android.jscbindings.mk: Modified. Added JNIBridgeJSC.cpp + * GNUmakefile.am: Modified. Added JNIBridgeJSC.h + * WebCore.xcodeproj/project.pbxproj: Modified. Added JNIBridgeJSC.[cpp|h] + * bridge/jni/JNIBridge.cpp: Modified. Moved JavaField and JavaArray to JNIBridgeJSC.cpp + (appendClassName): Modfied. Guard calls to JSLock + (JavaMethod::signature): Modfied. Guard calls to JSLock + * bridge/jni/JNIBridge.h: Modified. Moved JavaField and JavaArray to JNIBridgeJSC.h + * bridge/jni/jsc/JNIBridgeJSC.cpp: Copied from WebCore/bridge/jni/JNIBridge.cpp. + * bridge/jni/jsc/JNIBridgeJSC.h: Copied from WebCore/bridge/jni/JNIBridge.h. + * bridge/jni/jsc/JNIUtilityPrivate.cpp: Modified. Include JNIBridgeJSC.h + * bridge/jni/jsc/JavaClassJSC.h: Modified. Include JNIBridgeJSC.h + * bridge/jni/jsc/JavaInstanceJSC.cpp: Modified. Include JNIBridgeJSC.h + 2010-01-18 Steve Falkenburg <sfalken@apple.com> Reviewed by Sam Weinig. diff --git a/WebCore/GNUmakefile.am b/WebCore/GNUmakefile.am index 9c5f000..d35697e 100644 --- a/WebCore/GNUmakefile.am +++ b/WebCore/GNUmakefile.am @@ -500,6 +500,7 @@ webcore_sources += \ WebCore/bridge/jni/JNIBridge.h \ WebCore/bridge/jni/JNIUtility.h \ WebCore/bridge/jni/jni_jsobject.h \ + WebCore/bridge/jni/jsc/JNIBridgeJSC.h \ WebCore/bridge/jni/jsc/JavaClassJSC.h \ WebCore/bridge/jni/jsc/JavaInstanceJSC.h \ WebCore/bridge/jsc/BridgeJSC.h \ diff --git a/WebCore/WebCore.xcodeproj/project.pbxproj b/WebCore/WebCore.xcodeproj/project.pbxproj index 8c805ad..c690d63 100644 --- a/WebCore/WebCore.xcodeproj/project.pbxproj +++ b/WebCore/WebCore.xcodeproj/project.pbxproj @@ -1102,6 +1102,8 @@ 59C77F2B10545B3B00506104 /* GeolocationServiceMock.h in Headers */ = {isa = PBXBuildFile; fileRef = 59C77F2910545B3B00506104 /* GeolocationServiceMock.h */; settings = {ATTRIBUTES = (Private, ); }; }; 59E560A71105336600AA1258 /* JavaClassJSC.h in Headers */ = {isa = PBXBuildFile; fileRef = 59E560A61105336600AA1258 /* JavaClassJSC.h */; }; 59E560A91105336F00AA1258 /* JavaClassJSC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59E560A81105336F00AA1258 /* JavaClassJSC.cpp */; }; + 59E842661109E5A2000305AD /* JNIBridgeJSC.h in Headers */ = {isa = PBXBuildFile; fileRef = 59E842651109E5A2000305AD /* JNIBridgeJSC.h */; }; + 59E842681109E5AE000305AD /* JNIBridgeJSC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59E842671109E5AE000305AD /* JNIBridgeJSC.cpp */; }; 59EE122C1106080500885116 /* JNIUtilityPrivate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59EE122B1106080500885116 /* JNIUtilityPrivate.cpp */; }; 59EE122E1106080F00885116 /* JNIUtilityPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 59EE122D1106080F00885116 /* JNIUtilityPrivate.h */; }; 59EE12301106081F00885116 /* JNIUtility.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 59EE122F1106081F00885116 /* JNIUtility.cpp */; }; @@ -6432,6 +6434,8 @@ 59C77F2910545B3B00506104 /* GeolocationServiceMock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GeolocationServiceMock.h; path = mock/GeolocationServiceMock.h; sourceTree = "<group>"; }; 59E560A61105336600AA1258 /* JavaClassJSC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JavaClassJSC.h; path = jsc/JavaClassJSC.h; sourceTree = "<group>"; }; 59E560A81105336F00AA1258 /* JavaClassJSC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JavaClassJSC.cpp; path = jsc/JavaClassJSC.cpp; sourceTree = "<group>"; }; + 59E842651109E5A2000305AD /* JNIBridgeJSC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JNIBridgeJSC.h; path = jsc/JNIBridgeJSC.h; sourceTree = "<group>"; }; + 59E842671109E5AE000305AD /* JNIBridgeJSC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JNIBridgeJSC.cpp; path = jsc/JNIBridgeJSC.cpp; sourceTree = "<group>"; }; 59EE122B1106080500885116 /* JNIUtilityPrivate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JNIUtilityPrivate.cpp; path = jsc/JNIUtilityPrivate.cpp; sourceTree = "<group>"; }; 59EE122D1106080F00885116 /* JNIUtilityPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JNIUtilityPrivate.h; path = jsc/JNIUtilityPrivate.h; sourceTree = "<group>"; }; 59EE122F1106081F00885116 /* JNIUtility.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JNIUtility.cpp; sourceTree = "<group>"; }; @@ -10994,6 +10998,8 @@ 599D1E2F10C97D4C00E0EF12 /* jsc */ = { isa = PBXGroup; children = ( + 59E842671109E5AE000305AD /* JNIBridgeJSC.cpp */, + 59E842651109E5A2000305AD /* JNIBridgeJSC.h */, 59EE122D1106080F00885116 /* JNIUtilityPrivate.h */, 59EE122B1106080500885116 /* JNIUtilityPrivate.cpp */, 59BC393E11054A1300FD85DB /* JavaStringJSC.h */, @@ -18340,6 +18346,7 @@ 46D4F2490AF97E810035385A /* cellCursor.png in Resources */, 46D4F24A0AF97E810035385A /* contextMenuCursor.png in Resources */, 4614A1FE0B23A8D600446E1C /* copyCursor.png in Resources */, + 59E842661109E5A2000305AD /* JNIBridgeJSC.h in Headers */, 464EA2730B8A350B00A8E6E3 /* crossHairCursor.png in Resources */, 1C14E76C0AD8C81C00B6158B /* deleteButton.tiff in Resources */, 1C14E76B0AD8C81C00B6158B /* deleteButtonPressed.tiff in Resources */, @@ -20518,6 +20525,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 1CDD45E50BA9C84600F90147 /* WebCore.xcconfig */; buildSettings = { + 59E842681109E5AE000305AD /* JNIBridgeJSC.cpp in Sources */, PRODUCT_NAME = "Derived Sources"; }; name = Release; diff --git a/WebCore/bridge/jni/JNIBridge.cpp b/WebCore/bridge/jni/JNIBridge.cpp index 627d227..4810e5f 100644 --- a/WebCore/bridge/jni/JNIBridge.cpp +++ b/WebCore/bridge/jni/JNIBridge.cpp @@ -30,14 +30,8 @@ #if ENABLE(MAC_JAVA_BRIDGE) #include "CString.h" -#include "JNIUtility.h" -#include "JNIUtilityPrivate.h" #include "StringBuilder.h" -#include "runtime_array.h" -#include "runtime_object.h" -#include "runtime_root.h" -#include <runtime/Error.h> -#include <runtime/JSLock.h> + #ifdef NDEBUG #define JS_LOG(formatAndArgs...) ((void)0) @@ -59,206 +53,6 @@ JavaParameter::JavaParameter(JNIEnv* env, jstring type) m_JNIType = JNITypeFromClassName(m_type.UTF8String()); } -JavaField::JavaField(JNIEnv* env, jobject aField) -{ - // Get field type - jobject fieldType = callJNIMethod<jobject>(aField, "getType", "()Ljava/lang/Class;"); - jstring fieldTypeName = static_cast<jstring>(callJNIMethod<jobject>(fieldType, "getName", "()Ljava/lang/String;")); - m_type = JavaString(env, fieldTypeName); - m_JNIType = JNITypeFromClassName(m_type.UTF8String()); - - // Get field name - jstring fieldName = static_cast<jstring>(callJNIMethod<jobject>(aField, "getName", "()Ljava/lang/String;")); - m_name = JavaString(env, fieldName); - - m_field = new JObjectWrapper(aField); -} - -JSValue JavaArray::convertJObjectToArray(ExecState* exec, jobject anObject, const char* type, PassRefPtr<RootObject> rootObject) -{ - if (type[0] != '[') - return jsUndefined(); - - return new (exec) RuntimeArray(exec, new JavaArray(anObject, type, rootObject)); -} - -jvalue JavaField::dispatchValueFromInstance(ExecState* exec, const JavaInstance* instance, const char* name, const char* sig, JNIType returnType) const -{ - jobject jinstance = instance->javaInstance(); - jobject fieldJInstance = m_field->m_instance; - JNIEnv* env = getJNIEnv(); - jvalue result; - - bzero(&result, sizeof(jvalue)); - jclass cls = env->GetObjectClass(fieldJInstance); - if (cls) { - jmethodID mid = env->GetMethodID(cls, name, sig); - if (mid) { - RootObject* rootObject = instance->rootObject(); - if (rootObject && rootObject->nativeHandle()) { - JSValue exceptionDescription; - jvalue args[1]; - - args[0].l = jinstance; - dispatchJNICall(exec, rootObject->nativeHandle(), fieldJInstance, false, returnType, mid, args, result, 0, exceptionDescription); - if (exceptionDescription) - throwError(exec, GeneralError, exceptionDescription.toString(exec)); - } - } - } - return result; -} - -JSValue JavaField::valueFromInstance(ExecState* exec, const Instance* i) const -{ - const JavaInstance* instance = static_cast<const JavaInstance*>(i); - - JSValue jsresult = jsUndefined(); - - switch (m_JNIType) { - case array_type: - case object_type: - { - jvalue result = dispatchValueFromInstance(exec, instance, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", object_type); - jobject anObject = result.l; - - const char* arrayType = type(); - if (arrayType[0] == '[') - jsresult = JavaArray::convertJObjectToArray(exec, anObject, arrayType, instance->rootObject()); - else if (anObject) - jsresult = JavaInstance::create(anObject, instance->rootObject())->createRuntimeObject(exec); - } - break; - - case boolean_type: - jsresult = jsBoolean(dispatchValueFromInstance(exec, instance, "getBoolean", "(Ljava/lang/Object;)Z", boolean_type).z); - break; - - case byte_type: - case char_type: - case short_type: - - case int_type: - { - jint value; - jvalue result = dispatchValueFromInstance(exec, instance, "getInt", "(Ljava/lang/Object;)I", int_type); - value = result.i; - jsresult = jsNumber(exec, static_cast<int>(value)); - } - break; - - case long_type: - case float_type: - case double_type: - { - jdouble value; - jvalue result = dispatchValueFromInstance(exec, instance, "getDouble", "(Ljava/lang/Object;)D", double_type); - value = result.i; - jsresult = jsNumber(exec, static_cast<double>(value)); - } - break; - default: - break; - } - - JS_LOG("getting %s = %s\n", UString(name()).UTF8String().c_str(), jsresult.toString(exec).ascii()); - - return jsresult; -} - -void JavaField::dispatchSetValueToInstance(ExecState* exec, const JavaInstance* instance, jvalue javaValue, const char* name, const char* sig) const -{ - jobject jinstance = instance->javaInstance(); - jobject fieldJInstance = m_field->m_instance; - JNIEnv* env = getJNIEnv(); - - jclass cls = env->GetObjectClass(fieldJInstance); - if (cls) { - jmethodID mid = env->GetMethodID(cls, name, sig); - if (mid) { - RootObject* rootObject = instance->rootObject(); - if (rootObject && rootObject->nativeHandle()) { - JSValue exceptionDescription; - jvalue args[2]; - jvalue result; - - args[0].l = jinstance; - args[1] = javaValue; - dispatchJNICall(exec, rootObject->nativeHandle(), fieldJInstance, false, void_type, mid, args, result, 0, exceptionDescription); - if (exceptionDescription) - throwError(exec, GeneralError, exceptionDescription.toString(exec)); - } - } - } -} - -void JavaField::setValueToInstance(ExecState* exec, const Instance* i, JSValue aValue) const -{ - const JavaInstance* instance = static_cast<const JavaInstance*>(i); - jvalue javaValue = convertValueToJValue(exec, aValue, m_JNIType, type()); - - JS_LOG("setting value %s to %s\n", UString(name()).UTF8String().c_str(), aValue.toString(exec).ascii()); - - switch (m_JNIType) { - case array_type: - case object_type: - { - dispatchSetValueToInstance(exec, instance, javaValue, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V"); - } - break; - - case boolean_type: - { - dispatchSetValueToInstance(exec, instance, javaValue, "setBoolean", "(Ljava/lang/Object;Z)V"); - } - break; - - case byte_type: - { - dispatchSetValueToInstance(exec, instance, javaValue, "setByte", "(Ljava/lang/Object;B)V"); - } - break; - - case char_type: - { - dispatchSetValueToInstance(exec, instance, javaValue, "setChar", "(Ljava/lang/Object;C)V"); - } - break; - - case short_type: - { - dispatchSetValueToInstance(exec, instance, javaValue, "setShort", "(Ljava/lang/Object;S)V"); - } - break; - - case int_type: - { - dispatchSetValueToInstance(exec, instance, javaValue, "setInt", "(Ljava/lang/Object;I)V"); - } - break; - - case long_type: - { - dispatchSetValueToInstance(exec, instance, javaValue, "setLong", "(Ljava/lang/Object;J)V"); - } - break; - - case float_type: - { - dispatchSetValueToInstance(exec, instance, javaValue, "setFloat", "(Ljava/lang/Object;F)V"); - } - break; - - case double_type: - { - dispatchSetValueToInstance(exec, instance, javaValue, "setDouble", "(Ljava/lang/Object;D)V"); - } - break; - default: - break; - } -} - JavaMethod::JavaMethod(JNIEnv* env, jobject aMethod) { // Get return type @@ -309,7 +103,9 @@ JavaMethod::~JavaMethod() // we get '.' between components from the reflection API. static void appendClassName(StringBuilder& builder, const char* className) { +#if USE(JSC) ASSERT(JSLock::lockCount() > 0); +#endif char* c = strdup(className); @@ -328,7 +124,9 @@ static void appendClassName(StringBuilder& builder, const char* className) const char* JavaMethod::signature() const { if (!m_signature) { +#if USE(JSC) JSLock lock(SilenceAssertionsOnly); +#endif StringBuilder signatureBuilder; signatureBuilder.append("("); @@ -377,200 +175,4 @@ jmethodID JavaMethod::methodID(jobject obj) const return m_methodID; } - -JavaArray::JavaArray(jobject array, const char* type, PassRefPtr<RootObject> rootObject) - : Array(rootObject) -{ - m_array = new JObjectWrapper(array); - // Java array are fixed length, so we can cache length. - JNIEnv* env = getJNIEnv(); - m_length = env->GetArrayLength(static_cast<jarray>(m_array->m_instance)); - m_type = strdup(type); - m_rootObject = rootObject; -} - -JavaArray::~JavaArray() -{ - free(const_cast<char*>(m_type)); -} - -RootObject* JavaArray::rootObject() const -{ - return m_rootObject && m_rootObject->isValid() ? m_rootObject.get() : 0; -} - -void JavaArray::setValueAt(ExecState* exec, unsigned index, JSValue aValue) const -{ - JNIEnv* env = getJNIEnv(); - char* javaClassName = 0; - - JNIType arrayType = JNITypeFromPrimitiveType(m_type[1]); - if (m_type[1] == 'L') { - // The type of the array will be something like: - // "[Ljava.lang.string;". This is guaranteed, so no need - // for extra sanity checks. - javaClassName = strdup(&m_type[2]); - javaClassName[strchr(javaClassName, ';')-javaClassName] = 0; - } - jvalue aJValue = convertValueToJValue(exec, aValue, arrayType, javaClassName); - - switch (arrayType) { - case object_type: - { - env->SetObjectArrayElement(static_cast<jobjectArray>(javaArray()), index, aJValue.l); - break; - } - - case boolean_type: - { - env->SetBooleanArrayRegion(static_cast<jbooleanArray>(javaArray()), index, 1, &aJValue.z); - break; - } - - case byte_type: - { - env->SetByteArrayRegion(static_cast<jbyteArray>(javaArray()), index, 1, &aJValue.b); - break; - } - - case char_type: - { - env->SetCharArrayRegion(static_cast<jcharArray>(javaArray()), index, 1, &aJValue.c); - break; - } - - case short_type: - { - env->SetShortArrayRegion(static_cast<jshortArray>(javaArray()), index, 1, &aJValue.s); - break; - } - - case int_type: - { - env->SetIntArrayRegion(static_cast<jintArray>(javaArray()), index, 1, &aJValue.i); - break; - } - - case long_type: - { - env->SetLongArrayRegion(static_cast<jlongArray>(javaArray()), index, 1, &aJValue.j); - } - - case float_type: - { - env->SetFloatArrayRegion(static_cast<jfloatArray>(javaArray()), index, 1, &aJValue.f); - break; - } - - case double_type: - { - env->SetDoubleArrayRegion(static_cast<jdoubleArray>(javaArray()), index, 1, &aJValue.d); - break; - } - default: - break; - } - - if (javaClassName) - free(const_cast<char*>(javaClassName)); -} - - -JSValue JavaArray::valueAt(ExecState* exec, unsigned index) const -{ - JNIEnv* env = getJNIEnv(); - JNIType arrayType = JNITypeFromPrimitiveType(m_type[1]); - switch (arrayType) { - case object_type: - { - jobjectArray objectArray = static_cast<jobjectArray>(javaArray()); - jobject anObject; - anObject = env->GetObjectArrayElement(objectArray, index); - - // No object? - if (!anObject) - return jsNull(); - - // Nested array? - if (m_type[1] == '[') - return JavaArray::convertJObjectToArray(exec, anObject, m_type + 1, rootObject()); - // or array of other object type? - return JavaInstance::create(anObject, rootObject())->createRuntimeObject(exec); - } - - case boolean_type: - { - jbooleanArray booleanArray = static_cast<jbooleanArray>(javaArray()); - jboolean aBoolean; - env->GetBooleanArrayRegion(booleanArray, index, 1, &aBoolean); - return jsBoolean(aBoolean); - } - - case byte_type: - { - jbyteArray byteArray = static_cast<jbyteArray>(javaArray()); - jbyte aByte; - env->GetByteArrayRegion(byteArray, index, 1, &aByte); - return jsNumber(exec, aByte); - } - - case char_type: - { - jcharArray charArray = static_cast<jcharArray>(javaArray()); - jchar aChar; - env->GetCharArrayRegion(charArray, index, 1, &aChar); - return jsNumber(exec, aChar); - break; - } - - case short_type: - { - jshortArray shortArray = static_cast<jshortArray>(javaArray()); - jshort aShort; - env->GetShortArrayRegion(shortArray, index, 1, &aShort); - return jsNumber(exec, aShort); - } - - case int_type: - { - jintArray intArray = static_cast<jintArray>(javaArray()); - jint anInt; - env->GetIntArrayRegion(intArray, index, 1, &anInt); - return jsNumber(exec, anInt); - } - - case long_type: - { - jlongArray longArray = static_cast<jlongArray>(javaArray()); - jlong aLong; - env->GetLongArrayRegion(longArray, index, 1, &aLong); - return jsNumber(exec, aLong); - } - - case float_type: - { - jfloatArray floatArray = static_cast<jfloatArray>(javaArray()); - jfloat aFloat; - env->GetFloatArrayRegion(floatArray, index, 1, &aFloat); - return jsNumber(exec, aFloat); - } - - case double_type: - { - jdoubleArray doubleArray = static_cast<jdoubleArray>(javaArray()); - jdouble aDouble; - env->GetDoubleArrayRegion(doubleArray, index, 1, &aDouble); - return jsNumber(exec, aDouble); - } - default: - break; - } - return jsUndefined(); -} - -unsigned int JavaArray::getLength() const -{ - return m_length; -} - #endif // ENABLE(MAC_JAVA_BRIDGE) diff --git a/WebCore/bridge/jni/JNIBridge.h b/WebCore/bridge/jni/JNIBridge.h index ce129af..712ee7d 100644 --- a/WebCore/bridge/jni/JNIBridge.h +++ b/WebCore/bridge/jni/JNIBridge.h @@ -30,7 +30,6 @@ #if ENABLE(MAC_JAVA_BRIDGE) #include "JNIUtility.h" -#include "JavaInstanceJSC.h" #if USE(JSC) #include "JavaStringJSC.h" @@ -84,30 +83,6 @@ private: JNIType m_JNIType; }; - -class JavaField : public Field { -public: - JavaField(JNIEnv*, jobject aField); - - virtual JSValue valueFromInstance(ExecState*, const Instance*) const; - virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const; - - const JavaString& name() const { return m_name; } - virtual RuntimeType type() const { return m_type.UTF8String(); } - - JNIType getJNIType() const { return m_JNIType; } - -private: - void dispatchSetValueToInstance(ExecState*, const JavaInstance*, jvalue, const char* name, const char* sig) const; - jvalue dispatchValueFromInstance(ExecState*, const JavaInstance*, const char* name, const char* sig, JNIType returnType) const; - - JavaString m_name; - JavaString m_type; - JNIType m_JNIType; - RefPtr<JObjectWrapper> m_field; -}; - - class JavaMethod : public Method { public: JavaMethod(JNIEnv*, jobject aMethod); @@ -136,27 +111,6 @@ private: bool m_isStatic; }; -class JavaArray : public Array { -public: - JavaArray(jobject array, const char* type, PassRefPtr<RootObject>); - virtual ~JavaArray(); - - RootObject* rootObject() const; - - virtual void setValueAt(ExecState*, unsigned int index, JSValue) const; - virtual JSValue valueAt(ExecState*, unsigned int index) const; - virtual unsigned int getLength() const; - - jobject javaArray() const { return m_array->m_instance; } - - static JSValue convertJObjectToArray(ExecState*, jobject, const char* type, PassRefPtr<RootObject>); - -private: - RefPtr<JObjectWrapper> m_array; - unsigned int m_length; - const char* m_type; -}; - } // namespace Bindings } // namespace JSC diff --git a/WebCore/bridge/jni/jsc/JNIBridgeJSC.cpp b/WebCore/bridge/jni/jsc/JNIBridgeJSC.cpp new file mode 100644 index 0000000..4bc6c47 --- /dev/null +++ b/WebCore/bridge/jni/jsc/JNIBridgeJSC.cpp @@ -0,0 +1,445 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2007, 2009 Apple Inc. All rights reserved. + * Copyright 2010, 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 APPLE COMPUTER, INC. ``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 "JNIBridgeJSC.h" + +#if ENABLE(MAC_JAVA_BRIDGE) + +#include "JNIUtilityPrivate.h" +#include "runtime_array.h" +#include "runtime_object.h" +#include <runtime/Error.h> + +#ifdef NDEBUG +#define JS_LOG(formatAndArgs...) ((void)0) +#else +#define JS_LOG(formatAndArgs...) { \ + fprintf(stderr, "%s:%d -- %s: ", __FILE__, __LINE__, __FUNCTION__); \ + fprintf(stderr, formatAndArgs); \ +} +#endif + +using namespace JSC; +using namespace JSC::Bindings; + + +JavaField::JavaField(JNIEnv* env, jobject aField) +{ + // Get field type + jobject fieldType = callJNIMethod<jobject>(aField, "getType", "()Ljava/lang/Class;"); + jstring fieldTypeName = static_cast<jstring>(callJNIMethod<jobject>(fieldType, "getName", "()Ljava/lang/String;")); + m_type = JavaString(env, fieldTypeName); + m_JNIType = JNITypeFromClassName(m_type.UTF8String()); + + // Get field name + jstring fieldName = static_cast<jstring>(callJNIMethod<jobject>(aField, "getName", "()Ljava/lang/String;")); + m_name = JavaString(env, fieldName); + + m_field = new JObjectWrapper(aField); +} + +JSValue JavaArray::convertJObjectToArray(ExecState* exec, jobject anObject, const char* type, PassRefPtr<RootObject> rootObject) +{ + if (type[0] != '[') + return jsUndefined(); + + return new (exec) RuntimeArray(exec, new JavaArray(anObject, type, rootObject)); +} + +jvalue JavaField::dispatchValueFromInstance(ExecState* exec, const JavaInstance* instance, const char* name, const char* sig, JNIType returnType) const +{ + jobject jinstance = instance->javaInstance(); + jobject fieldJInstance = m_field->m_instance; + JNIEnv* env = getJNIEnv(); + jvalue result; + + bzero(&result, sizeof(jvalue)); + jclass cls = env->GetObjectClass(fieldJInstance); + if (cls) { + jmethodID mid = env->GetMethodID(cls, name, sig); + if (mid) { + RootObject* rootObject = instance->rootObject(); + if (rootObject && rootObject->nativeHandle()) { + JSValue exceptionDescription; + jvalue args[1]; + + args[0].l = jinstance; + dispatchJNICall(exec, rootObject->nativeHandle(), fieldJInstance, false, returnType, mid, args, result, 0, exceptionDescription); + if (exceptionDescription) + throwError(exec, GeneralError, exceptionDescription.toString(exec)); + } + } + } + return result; +} + +JSValue JavaField::valueFromInstance(ExecState* exec, const Instance* i) const +{ + const JavaInstance* instance = static_cast<const JavaInstance*>(i); + + JSValue jsresult = jsUndefined(); + + switch (m_JNIType) { + case array_type: + case object_type: + { + jvalue result = dispatchValueFromInstance(exec, instance, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", object_type); + jobject anObject = result.l; + + const char* arrayType = type(); + if (arrayType[0] == '[') + jsresult = JavaArray::convertJObjectToArray(exec, anObject, arrayType, instance->rootObject()); + else if (anObject) + jsresult = JavaInstance::create(anObject, instance->rootObject())->createRuntimeObject(exec); + } + break; + + case boolean_type: + jsresult = jsBoolean(dispatchValueFromInstance(exec, instance, "getBoolean", "(Ljava/lang/Object;)Z", boolean_type).z); + break; + + case byte_type: + case char_type: + case short_type: + + case int_type: + { + jint value; + jvalue result = dispatchValueFromInstance(exec, instance, "getInt", "(Ljava/lang/Object;)I", int_type); + value = result.i; + jsresult = jsNumber(exec, static_cast<int>(value)); + } + break; + + case long_type: + case float_type: + case double_type: + { + jdouble value; + jvalue result = dispatchValueFromInstance(exec, instance, "getDouble", "(Ljava/lang/Object;)D", double_type); + value = result.i; + jsresult = jsNumber(exec, static_cast<double>(value)); + } + break; + default: + break; + } + + JS_LOG("getting %s = %s\n", UString(name()).UTF8String().c_str(), jsresult.toString(exec).ascii()); + + return jsresult; +} + +void JavaField::dispatchSetValueToInstance(ExecState* exec, const JavaInstance* instance, jvalue javaValue, const char* name, const char* sig) const +{ + jobject jinstance = instance->javaInstance(); + jobject fieldJInstance = m_field->m_instance; + JNIEnv* env = getJNIEnv(); + + jclass cls = env->GetObjectClass(fieldJInstance); + if (cls) { + jmethodID mid = env->GetMethodID(cls, name, sig); + if (mid) { + RootObject* rootObject = instance->rootObject(); + if (rootObject && rootObject->nativeHandle()) { + JSValue exceptionDescription; + jvalue args[2]; + jvalue result; + + args[0].l = jinstance; + args[1] = javaValue; + dispatchJNICall(exec, rootObject->nativeHandle(), fieldJInstance, false, void_type, mid, args, result, 0, exceptionDescription); + if (exceptionDescription) + throwError(exec, GeneralError, exceptionDescription.toString(exec)); + } + } + } +} + +void JavaField::setValueToInstance(ExecState* exec, const Instance* i, JSValue aValue) const +{ + const JavaInstance* instance = static_cast<const JavaInstance*>(i); + jvalue javaValue = convertValueToJValue(exec, aValue, m_JNIType, type()); + + JS_LOG("setting value %s to %s\n", UString(name()).UTF8String().c_str(), aValue.toString(exec).ascii()); + + switch (m_JNIType) { + case array_type: + case object_type: + { + dispatchSetValueToInstance(exec, instance, javaValue, "set", "(Ljava/lang/Object;Ljava/lang/Object;)V"); + } + break; + + case boolean_type: + { + dispatchSetValueToInstance(exec, instance, javaValue, "setBoolean", "(Ljava/lang/Object;Z)V"); + } + break; + + case byte_type: + { + dispatchSetValueToInstance(exec, instance, javaValue, "setByte", "(Ljava/lang/Object;B)V"); + } + break; + + case char_type: + { + dispatchSetValueToInstance(exec, instance, javaValue, "setChar", "(Ljava/lang/Object;C)V"); + } + break; + + case short_type: + { + dispatchSetValueToInstance(exec, instance, javaValue, "setShort", "(Ljava/lang/Object;S)V"); + } + break; + + case int_type: + { + dispatchSetValueToInstance(exec, instance, javaValue, "setInt", "(Ljava/lang/Object;I)V"); + } + break; + + case long_type: + { + dispatchSetValueToInstance(exec, instance, javaValue, "setLong", "(Ljava/lang/Object;J)V"); + } + break; + + case float_type: + { + dispatchSetValueToInstance(exec, instance, javaValue, "setFloat", "(Ljava/lang/Object;F)V"); + } + break; + + case double_type: + { + dispatchSetValueToInstance(exec, instance, javaValue, "setDouble", "(Ljava/lang/Object;D)V"); + } + break; + default: + break; + } +} + +JavaArray::JavaArray(jobject array, const char* type, PassRefPtr<RootObject> rootObject) + : Array(rootObject) +{ + m_array = new JObjectWrapper(array); + // Java array are fixed length, so we can cache length. + JNIEnv* env = getJNIEnv(); + m_length = env->GetArrayLength(static_cast<jarray>(m_array->m_instance)); + m_type = strdup(type); + m_rootObject = rootObject; +} + +JavaArray::~JavaArray() +{ + free(const_cast<char*>(m_type)); +} + +RootObject* JavaArray::rootObject() const +{ + return m_rootObject && m_rootObject->isValid() ? m_rootObject.get() : 0; +} + +void JavaArray::setValueAt(ExecState* exec, unsigned index, JSValue aValue) const +{ + JNIEnv* env = getJNIEnv(); + char* javaClassName = 0; + + JNIType arrayType = JNITypeFromPrimitiveType(m_type[1]); + if (m_type[1] == 'L') { + // The type of the array will be something like: + // "[Ljava.lang.string;". This is guaranteed, so no need + // for extra sanity checks. + javaClassName = strdup(&m_type[2]); + javaClassName[strchr(javaClassName, ';')-javaClassName] = 0; + } + jvalue aJValue = convertValueToJValue(exec, aValue, arrayType, javaClassName); + + switch (arrayType) { + case object_type: + { + env->SetObjectArrayElement(static_cast<jobjectArray>(javaArray()), index, aJValue.l); + break; + } + + case boolean_type: + { + env->SetBooleanArrayRegion(static_cast<jbooleanArray>(javaArray()), index, 1, &aJValue.z); + break; + } + + case byte_type: + { + env->SetByteArrayRegion(static_cast<jbyteArray>(javaArray()), index, 1, &aJValue.b); + break; + } + + case char_type: + { + env->SetCharArrayRegion(static_cast<jcharArray>(javaArray()), index, 1, &aJValue.c); + break; + } + + case short_type: + { + env->SetShortArrayRegion(static_cast<jshortArray>(javaArray()), index, 1, &aJValue.s); + break; + } + + case int_type: + { + env->SetIntArrayRegion(static_cast<jintArray>(javaArray()), index, 1, &aJValue.i); + break; + } + + case long_type: + { + env->SetLongArrayRegion(static_cast<jlongArray>(javaArray()), index, 1, &aJValue.j); + } + + case float_type: + { + env->SetFloatArrayRegion(static_cast<jfloatArray>(javaArray()), index, 1, &aJValue.f); + break; + } + + case double_type: + { + env->SetDoubleArrayRegion(static_cast<jdoubleArray>(javaArray()), index, 1, &aJValue.d); + break; + } + default: + break; + } + + if (javaClassName) + free(const_cast<char*>(javaClassName)); +} + + +JSValue JavaArray::valueAt(ExecState* exec, unsigned index) const +{ + JNIEnv* env = getJNIEnv(); + JNIType arrayType = JNITypeFromPrimitiveType(m_type[1]); + switch (arrayType) { + case object_type: + { + jobjectArray objectArray = static_cast<jobjectArray>(javaArray()); + jobject anObject; + anObject = env->GetObjectArrayElement(objectArray, index); + + // No object? + if (!anObject) + return jsNull(); + + // Nested array? + if (m_type[1] == '[') + return JavaArray::convertJObjectToArray(exec, anObject, m_type + 1, rootObject()); + // or array of other object type? + return JavaInstance::create(anObject, rootObject())->createRuntimeObject(exec); + } + + case boolean_type: + { + jbooleanArray booleanArray = static_cast<jbooleanArray>(javaArray()); + jboolean aBoolean; + env->GetBooleanArrayRegion(booleanArray, index, 1, &aBoolean); + return jsBoolean(aBoolean); + } + + case byte_type: + { + jbyteArray byteArray = static_cast<jbyteArray>(javaArray()); + jbyte aByte; + env->GetByteArrayRegion(byteArray, index, 1, &aByte); + return jsNumber(exec, aByte); + } + + case char_type: + { + jcharArray charArray = static_cast<jcharArray>(javaArray()); + jchar aChar; + env->GetCharArrayRegion(charArray, index, 1, &aChar); + return jsNumber(exec, aChar); + break; + } + + case short_type: + { + jshortArray shortArray = static_cast<jshortArray>(javaArray()); + jshort aShort; + env->GetShortArrayRegion(shortArray, index, 1, &aShort); + return jsNumber(exec, aShort); + } + + case int_type: + { + jintArray intArray = static_cast<jintArray>(javaArray()); + jint anInt; + env->GetIntArrayRegion(intArray, index, 1, &anInt); + return jsNumber(exec, anInt); + } + + case long_type: + { + jlongArray longArray = static_cast<jlongArray>(javaArray()); + jlong aLong; + env->GetLongArrayRegion(longArray, index, 1, &aLong); + return jsNumber(exec, aLong); + } + + case float_type: + { + jfloatArray floatArray = static_cast<jfloatArray>(javaArray()); + jfloat aFloat; + env->GetFloatArrayRegion(floatArray, index, 1, &aFloat); + return jsNumber(exec, aFloat); + } + + case double_type: + { + jdoubleArray doubleArray = static_cast<jdoubleArray>(javaArray()); + jdouble aDouble; + env->GetDoubleArrayRegion(doubleArray, index, 1, &aDouble); + return jsNumber(exec, aDouble); + } + default: + break; + } + return jsUndefined(); +} + +unsigned int JavaArray::getLength() const +{ + return m_length; +} + +#endif // ENABLE(MAC_JAVA_BRIDGE) diff --git a/WebCore/bridge/jni/jsc/JNIBridgeJSC.h b/WebCore/bridge/jni/jsc/JNIBridgeJSC.h new file mode 100644 index 0000000..902bd4e --- /dev/null +++ b/WebCore/bridge/jni/jsc/JNIBridgeJSC.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2003, 2004, 2005, 2007, 2009, 2010 Apple Inc. All rights reserved. + * Copyright 2010, 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: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. 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 APPLE COMPUTER, INC. ``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 JNIBridgeJSC_h +#define JNIBridgeJSC_h + +#if ENABLE(MAC_JAVA_BRIDGE) + +#include "Bridge.h" +#include "JNIBridge.h" +#include <JavaVM/jni.h> + +namespace JSC { + +namespace Bindings { + +class JavaField : public Field { +public: + JavaField(JNIEnv*, jobject aField); + + virtual JSValue valueFromInstance(ExecState*, const Instance*) const; + virtual void setValueToInstance(ExecState*, const Instance*, JSValue) const; + + const JavaString& name() const { return m_name; } + virtual RuntimeType type() const { return m_type.UTF8String(); } + + JNIType getJNIType() const { return m_JNIType; } + +private: + void dispatchSetValueToInstance(ExecState*, const JavaInstance*, jvalue, const char* name, const char* sig) const; + jvalue dispatchValueFromInstance(ExecState*, const JavaInstance*, const char* name, const char* sig, JNIType returnType) const; + + JavaString m_name; + JavaString m_type; + JNIType m_JNIType; + RefPtr<JObjectWrapper> m_field; +}; + +class JavaArray : public Array { +public: + JavaArray(jobject array, const char* type, PassRefPtr<RootObject>); + virtual ~JavaArray(); + + RootObject* rootObject() const; + + virtual void setValueAt(ExecState*, unsigned int index, JSValue) const; + virtual JSValue valueAt(ExecState*, unsigned int index) const; + virtual unsigned int getLength() const; + + jobject javaArray() const { return m_array->m_instance; } + + static JSValue convertJObjectToArray(ExecState*, jobject, const char* type, PassRefPtr<RootObject>); + +private: + RefPtr<JObjectWrapper> m_array; + unsigned int m_length; + const char* m_type; +}; + +} // namespace Bindings + +} // namespace JSC + +#endif // ENABLE(MAC_JAVA_BRIDGE) + +#endif // JNIBridge_h diff --git a/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp b/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp index e89d0e0..e238ab8 100644 --- a/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp +++ b/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp @@ -29,7 +29,7 @@ #if ENABLE(MAC_JAVA_BRIDGE) -#include "JNIBridge.h" +#include "JNIBridgeJSC.h" #include "runtime_array.h" #include "runtime_object.h" #include <runtime/JSArray.h> diff --git a/WebCore/bridge/jni/jsc/JavaClassJSC.h b/WebCore/bridge/jni/jsc/JavaClassJSC.h index b20781b..09b93e9 100644 --- a/WebCore/bridge/jni/jsc/JavaClassJSC.h +++ b/WebCore/bridge/jni/jsc/JavaClassJSC.h @@ -28,7 +28,7 @@ #if ENABLE(MAC_JAVA_BRIDGE) -#include "JNIBridge.h" +#include "JNIBridgeJSC.h" #include <wtf/HashMap.h> namespace JSC { diff --git a/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp b/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp index d9e0f60..9fd37d2 100644 --- a/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp +++ b/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp @@ -28,7 +28,7 @@ #if ENABLE(MAC_JAVA_BRIDGE) -#include "JNIBridge.h" +#include "JNIBridgeJSC.h" #include "JNIUtility.h" #include "JNIUtilityPrivate.h" #include "JavaClassJSC.h" |