diff options
author | Steve Block <steveblock@google.com> | 2010-04-27 16:31:00 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2010-05-11 14:42:12 +0100 |
commit | dcc8cf2e65d1aa555cce12431a16547e66b469ee (patch) | |
tree | 92a8d65cd5383bca9749f5327fb5e440563926e6 /WebCore/bridge/jni | |
parent | ccac38a6b48843126402088a309597e682f40fe6 (diff) | |
download | external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.zip external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.gz external_webkit-dcc8cf2e65d1aa555cce12431a16547e66b469ee.tar.bz2 |
Merge webkit.org at r58033 : Initial merge by git
Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1
Diffstat (limited to 'WebCore/bridge/jni')
-rw-r--r-- | WebCore/bridge/jni/JNIBridge.cpp | 11 | ||||
-rw-r--r-- | WebCore/bridge/jni/JNIUtility.cpp | 10 | ||||
-rw-r--r-- | WebCore/bridge/jni/JNIUtility.h | 6 | ||||
-rw-r--r-- | WebCore/bridge/jni/jni_jsobject.mm | 71 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JNIBridgeJSC.cpp | 24 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp | 90 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JNIUtilityPrivate.h | 4 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JavaClassJSC.cpp | 2 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp | 134 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JavaInstanceJSC.h | 6 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JavaRuntimeObject.cpp | 53 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JavaRuntimeObject.h | 52 | ||||
-rw-r--r-- | WebCore/bridge/jni/jsc/JavaStringJSC.h | 6 | ||||
-rw-r--r-- | WebCore/bridge/jni/v8/JavaStringV8.h | 6 |
14 files changed, 325 insertions, 150 deletions
diff --git a/WebCore/bridge/jni/JNIBridge.cpp b/WebCore/bridge/jni/JNIBridge.cpp index f8a3979..28e8698 100644 --- a/WebCore/bridge/jni/JNIBridge.cpp +++ b/WebCore/bridge/jni/JNIBridge.cpp @@ -29,19 +29,10 @@ #if ENABLE(MAC_JAVA_BRIDGE) -#include "CString.h" #include "StringBuilder.h" +#include <wtf/text/CString.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; using namespace WebCore; diff --git a/WebCore/bridge/jni/JNIUtility.cpp b/WebCore/bridge/jni/JNIUtility.cpp index e558955..ece39ed 100644 --- a/WebCore/bridge/jni/JNIUtility.cpp +++ b/WebCore/bridge/jni/JNIUtility.cpp @@ -77,7 +77,7 @@ JavaVM* getJavaVM() if (jniError == JNI_OK && nJVMs > 0) jvm = jvmArray[0]; else - fprintf(stderr, "%s: JNI_GetCreatedJavaVMs failed, returned %ld\n", __PRETTY_FUNCTION__, static_cast<long>(jniError)); + LOG_ERROR("JNI_GetCreatedJavaVMs failed, returned %ld", static_cast<long>(jniError)); return jvm; } @@ -93,7 +93,7 @@ JNIEnv* getJNIEnv() jniError = getJavaVM()->AttachCurrentThread(&u.dummy, 0); if (jniError == JNI_OK) return u.env; - fprintf(stderr, "%s: AttachCurrentThread failed, returned %ld\n", __PRETTY_FUNCTION__, static_cast<long>(jniError)); + LOG_ERROR("AttachCurrentThread failed, returned %ld", static_cast<long>(jniError)); return 0; } @@ -319,10 +319,10 @@ jvalue getJNIField(jobject obj, JNIType type, const char* name, const char* sign result.d = env->functions->GetDoubleField(env, obj, field); break; default: - fprintf(stderr, "%s: invalid field type (%d)\n", __PRETTY_FUNCTION__, static_cast<int>(type)); + LOG_ERROR("Invalid field type (%d)", static_cast<int>(type)); } } else { - fprintf(stderr, "%s: Could not find field: %s\n", __PRETTY_FUNCTION__, name); + LOG_ERROR("Could not find field: %s", name); env->ExceptionDescribe(); env->ExceptionClear(); fprintf(stderr, "\n"); @@ -330,7 +330,7 @@ jvalue getJNIField(jobject obj, JNIType type, const char* name, const char* sign env->DeleteLocalRef(cls); } else - fprintf(stderr, "%s: Could not find class for object\n", __PRETTY_FUNCTION__); + LOG_ERROR("Could not find class for object"); } return result; diff --git a/WebCore/bridge/jni/JNIUtility.h b/WebCore/bridge/jni/JNIUtility.h index c832ef3..0eb889c 100644 --- a/WebCore/bridge/jni/JNIUtility.h +++ b/WebCore/bridge/jni/JNIUtility.h @@ -212,14 +212,14 @@ static T callJNIMethodV(jobject obj, const char* name, const char* sig, va_list env->DeleteLocalRef(cls); return JNICaller<T>::callV(obj, mid, args); } - fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, name, obj); + LOG_ERROR("Could not find method: %s for %p", name, obj); env->ExceptionDescribe(); env->ExceptionClear(); fprintf(stderr, "\n"); env->DeleteLocalRef(cls); } else - fprintf(stderr, "%s: Could not find class for %p\n", __PRETTY_FUNCTION__, obj); + LOG_ERROR("Could not find class for %p", obj); } return 0; @@ -254,7 +254,7 @@ T callJNIStaticMethod(jclass cls, const char* methodName, const char* methodSign if (mid) result = JNICaller<T>::callStaticV(cls, mid, args); else { - fprintf(stderr, "%s: Could not find method: %s for %p\n", __PRETTY_FUNCTION__, methodName, cls); + LOG_ERROR("Could not find method: %s for %p", methodName, cls); env->ExceptionDescribe(); env->ExceptionClear(); fprintf(stderr, "\n"); diff --git a/WebCore/bridge/jni/jni_jsobject.mm b/WebCore/bridge/jni/jni_jsobject.mm index 603624f..5e036ab 100644 --- a/WebCore/bridge/jni/jni_jsobject.mm +++ b/WebCore/bridge/jni/jni_jsobject.mm @@ -29,10 +29,12 @@ #if ENABLE(MAC_JAVA_BRIDGE) #include "Frame.h" +#include "JavaRuntimeObject.h" #include "JNIBridge.h" #include "JNIUtility.h" #include "JNIUtilityPrivate.h" #include "JSDOMBinding.h" +#include "Logging.h" #include "ScriptController.h" #include "StringSourceProvider.h" #include "WebCoreFrameView.h" @@ -42,21 +44,12 @@ #include <runtime/Completion.h> #include <runtime/JSGlobalObject.h> #include <runtime/JSLock.h> -#include <wtf/Assertions.h> using WebCore::Frame; using namespace JSC::Bindings; using namespace JSC; - -#ifdef NDEBUG -#define JS_LOG(formatAndArgs...) ((void)0) -#else -#define JS_LOG(formatAndArgs...) { \ - fprintf (stderr, "%s(%p,%p): ", __PRETTY_FUNCTION__, _performJavaScriptRunLoop, CFRunLoopGetCurrent()); \ - fprintf(stderr, formatAndArgs); \ -} -#endif +using namespace WebCore; #define UndefinedHandle 1 @@ -68,12 +61,12 @@ static CFRunLoopSourceRef completionSource; static void completedJavaScriptAccess (void *i) { - assert (CFRunLoopGetCurrent() != _performJavaScriptRunLoop); + ASSERT(CFRunLoopGetCurrent() != _performJavaScriptRunLoop); JSObjectCallContext *callContext = (JSObjectCallContext *)i; CFRunLoopRef runLoop = (CFRunLoopRef)callContext->originatingLoop; - assert (CFRunLoopGetCurrent() == runLoop); + ASSERT(CFRunLoopGetCurrent() == runLoop); CFRunLoopStop(runLoop); } @@ -115,7 +108,7 @@ static void dispatchToJavaScriptThread(JSObjectCallContext *context) CFRunLoopRef currentRunLoop = CFRunLoopGetCurrent(); - assert (currentRunLoop != _performJavaScriptRunLoop); + ASSERT(currentRunLoop != _performJavaScriptRunLoop); // Setup a source to signal once the invocation of the JavaScript // call completes. @@ -144,7 +137,7 @@ static void dispatchToJavaScriptThread(JSObjectCallContext *context) static void performJavaScriptAccess(void*) { - assert (CFRunLoopGetCurrent() == _performJavaScriptRunLoop); + ASSERT(CFRunLoopGetCurrent() == _performJavaScriptRunLoop); // Dispatch JavaScript calls here. CFRunLoopSourceContext sourceContext; @@ -205,7 +198,7 @@ jvalue JavaJSObject::invoke(JSObjectCallContext *context) else { JSObject *imp = jlong_to_impptr(nativeHandle); if (!findProtectingRootObject(imp)) { - fprintf (stderr, "%s:%d: Attempt to access JavaScript from destroyed applet, type %d.\n", __FILE__, __LINE__, context->type); + LOG_ERROR("Attempt to access JavaScript from destroyed applet, type %d.", context->type); return result; } @@ -256,7 +249,7 @@ jvalue JavaJSObject::invoke(JSObjectCallContext *context) } default: { - fprintf (stderr, "%s: invalid JavaScript call\n", __PRETTY_FUNCTION__); + LOG_ERROR("invalid JavaScript call"); } } } @@ -283,7 +276,7 @@ RootObject* JavaJSObject::rootObject() const jobject JavaJSObject::call(jstring methodName, jobjectArray args) const { - JS_LOG ("methodName = %s\n", JavaString(methodName).UTF8String()); + LOG(LiveConnect, "JavaJSObject::call methodName = %s", JavaString(methodName).UTF8String()); RootObject* rootObject = this->rootObject(); if (!rootObject) @@ -312,7 +305,7 @@ jobject JavaJSObject::call(jstring methodName, jobjectArray args) const jobject JavaJSObject::eval(jstring script) const { - JS_LOG ("script = %s\n", JavaString(script).UTF8String()); + LOG(LiveConnect, "JavaJSObject::eval script = %s", JavaString(script).UTF8String()); JSValue result; @@ -339,7 +332,7 @@ jobject JavaJSObject::eval(jstring script) const jobject JavaJSObject::getMember(jstring memberName) const { - JS_LOG ("(%p) memberName = %s\n", _imp, JavaString(memberName).UTF8String()); + LOG(LiveConnect, "JavaJSObject::getMember (%p) memberName = %s", _imp, JavaString(memberName).UTF8String()); RootObject* rootObject = this->rootObject(); if (!rootObject) @@ -355,7 +348,7 @@ jobject JavaJSObject::getMember(jstring memberName) const void JavaJSObject::setMember(jstring memberName, jobject value) const { - JS_LOG ("memberName = %s, value = %p\n", JavaString(memberName).UTF8String(), value); + LOG(LiveConnect, "JavaJSObject::setMember memberName = %s, value = %p", JavaString(memberName).UTF8String(), value); RootObject* rootObject = this->rootObject(); if (!rootObject) @@ -371,7 +364,7 @@ void JavaJSObject::setMember(jstring memberName, jobject value) const void JavaJSObject::removeMember(jstring memberName) const { - JS_LOG ("memberName = %s\n", JavaString(memberName).UTF8String()); + LOG(LiveConnect, "JavaJSObject::removeMember memberName = %s", JavaString(memberName).UTF8String()); RootObject* rootObject = this->rootObject(); if (!rootObject) @@ -385,11 +378,7 @@ void JavaJSObject::removeMember(jstring memberName) const jobject JavaJSObject::getSlot(jint index) const { -#ifdef __LP64__ - JS_LOG ("index = %d\n", index); -#else - JS_LOG ("index = %ld\n", index); -#endif + LOG(LiveConnect, "JavaJSObject::getSlot index = %ld", static_cast<long>(index)); RootObject* rootObject = this->rootObject(); if (!rootObject) @@ -406,11 +395,7 @@ jobject JavaJSObject::getSlot(jint index) const void JavaJSObject::setSlot(jint index, jobject value) const { -#ifdef __LP64__ - JS_LOG ("index = %d, value = %p\n", index, value); -#else - JS_LOG ("index = %ld, value = %p\n", index, value); -#endif + LOG(LiveConnect, "JavaJSObject::setSlot index = %ld, value = %p", static_cast<long>(index), value); RootObject* rootObject = this->rootObject(); if (!rootObject) @@ -424,7 +409,7 @@ void JavaJSObject::setSlot(jint index, jobject value) const jstring JavaJSObject::toString() const { - JS_LOG ("\n"); + LOG(LiveConnect, "JavaJSObject::toString"); RootObject* rootObject = this->rootObject(); if (!rootObject) @@ -434,7 +419,7 @@ jstring JavaJSObject::toString() const JSObject *thisObj = const_cast<JSObject*>(_imp); ExecState* exec = rootObject->globalObject()->globalExec(); - return (jstring)convertValueToJValue (exec, thisObj, object_type, "java.lang.String").l; + return static_cast<jstring>(convertValueToJValue(exec, rootObject, thisObj, object_type, "java.lang.String").l); } void JavaJSObject::finalize() const @@ -462,7 +447,7 @@ static PassRefPtr<RootObject> createRootObject(void* nativeHandle) // another JavaJSObject. jlong JavaJSObject::createNative(jlong nativeHandle) { - JS_LOG ("nativeHandle = %d\n", (int)nativeHandle); + LOG(LiveConnect, "JavaJSObject::createNative nativeHandle = %d", static_cast<int>(nativeHandle)); if (nativeHandle == UndefinedHandle) return nativeHandle; @@ -528,27 +513,25 @@ jobject JavaJSObject::convertValueToJObject(JSValue value) const jlong nativeHandle; if (value.isObject()) { - JSObject* imp = asObject(value); + JSObject* object = asObject(value); // We either have a wrapper around a Java instance or a JavaScript // object. If we have a wrapper around a Java instance, return that // instance, otherwise create a new Java JavaJSObject with the JSObject* // as its nativeHandle. - if (imp->classInfo() && strcmp(imp->classInfo()->className, "RuntimeObject") == 0) { - RuntimeObjectImp* runtimeImp = static_cast<RuntimeObjectImp*>(imp); - JavaInstance *runtimeInstance = static_cast<JavaInstance *>(runtimeImp->getInternalInstance()); + if (object->inherits(&JavaRuntimeObject::s_info)) { + JavaRuntimeObject* runtimeObject = static_cast<JavaRuntimeObject*>(object); + JavaInstance* runtimeInstance = runtimeObject->getInternalJavaInstance(); if (!runtimeInstance) return 0; return runtimeInstance->javaInstance(); + } else { + nativeHandle = ptr_to_jlong(object); + rootObject->gcProtect(object); } - else { - nativeHandle = ptr_to_jlong(imp); - rootObject->gcProtect(imp); - } - } + } else { // All other types will result in an undefined object. - else { nativeHandle = UndefinedHandle; } diff --git a/WebCore/bridge/jni/jsc/JNIBridgeJSC.cpp b/WebCore/bridge/jni/jsc/JNIBridgeJSC.cpp index 8776cd2..6de1011 100644 --- a/WebCore/bridge/jni/jsc/JNIBridgeJSC.cpp +++ b/WebCore/bridge/jni/jsc/JNIBridgeJSC.cpp @@ -30,22 +30,14 @@ #if ENABLE(MAC_JAVA_BRIDGE) #include "JNIUtilityPrivate.h" +#include "Logging.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; - +using namespace WebCore; JavaField::JavaField(JNIEnv* env, jobject aField) { @@ -116,6 +108,9 @@ JSValue JavaField::valueFromInstance(ExecState* exec, const Instance* i) const jvalue result = dispatchValueFromInstance(exec, instance, "get", "(Ljava/lang/Object;)Ljava/lang/Object;", object_type); jobject anObject = result.l; + if (!anObject) + return jsNull(); + const char* arrayType = type(); if (arrayType[0] == '[') jsresult = JavaArray::convertJObjectToArray(exec, anObject, arrayType, instance->rootObject()); @@ -155,7 +150,7 @@ JSValue JavaField::valueFromInstance(ExecState* exec, const Instance* i) const break; } - JS_LOG("getting %s = %s\n", UString(name()).UTF8String().c_str(), jsresult.toString(exec).ascii()); + LOG(LiveConnect, "JavaField::valueFromInstance getting %s = %s", UString(name()).UTF8String().data(), jsresult.toString(exec).ascii()); return jsresult; } @@ -189,9 +184,9 @@ void JavaField::dispatchSetValueToInstance(ExecState* exec, const JavaInstance* 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()); + jvalue javaValue = convertValueToJValue(exec, i->rootObject(), aValue, m_JNIType, type()); - JS_LOG("setting value %s to %s\n", UString(name()).UTF8String().c_str(), aValue.toString(exec).ascii()); + LOG(LiveConnect, "JavaField::setValueToInstance setting value %s to %s", UString(name()).UTF8String().data(), aValue.toString(exec).ascii()); switch (m_JNIType) { case array_type: @@ -261,7 +256,6 @@ JavaArray::JavaArray(jobject array, const char* type, PassRefPtr<RootObject> roo JNIEnv* env = getJNIEnv(); m_length = env->GetArrayLength(static_cast<jarray>(m_array->m_instance)); m_type = strdup(type); - m_rootObject = rootObject; } JavaArray::~JavaArray() @@ -287,7 +281,7 @@ void JavaArray::setValueAt(ExecState* exec, unsigned index, JSValue aValue) cons javaClassName = strdup(&m_type[2]); javaClassName[strchr(javaClassName, ';')-javaClassName] = 0; } - jvalue aJValue = convertValueToJValue(exec, aValue, arrayType, javaClassName); + jvalue aJValue = convertValueToJValue(exec, m_rootObject.get(), aValue, arrayType, javaClassName); switch (arrayType) { case object_type: diff --git a/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp b/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp index 8ce150f..69782f3 100644 --- a/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp +++ b/WebCore/bridge/jni/jsc/JNIUtilityPrivate.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2003, 2010 Apple, Inc. All rights reserved. * Copyright 2009, The Android Open Source Project * * Redistribution and use in source and binary forms, with or without @@ -29,6 +29,7 @@ #if ENABLE(MAC_JAVA_BRIDGE) +#include "JavaRuntimeObject.h" #include "JNIBridgeJSC.h" #include "runtime_array.h" #include "runtime_object.h" @@ -168,59 +169,94 @@ static jobject convertArrayInstanceToJavaArray(ExecState* exec, JSArray* jsArray return jarray; } -jvalue convertValueToJValue(ExecState* exec, JSValue value, JNIType jniType, const char* javaClassName) +jvalue convertValueToJValue(ExecState* exec, RootObject* rootObject, JSValue value, JNIType jniType, const char* javaClassName) { JSLock lock(SilenceAssertionsOnly); jvalue result; + memset(&result, 0, sizeof(jvalue)); switch (jniType) { case array_type: case object_type: { - result.l = (jobject)0; + // FIXME: JavaJSObject::convertValueToJObject functionality is almost exactly the same, + // these functions should use common code. - // First see if we have a Java instance. if (value.isObject()) { - JSObject* objectImp = asObject(value); - if (objectImp->classInfo() == &RuntimeObjectImp::s_info) { - RuntimeObjectImp* imp = static_cast<RuntimeObjectImp*>(objectImp); - JavaInstance* instance = static_cast<JavaInstance*>(imp->getInternalInstance()); + JSObject* object = asObject(value); + if (object->inherits(&JavaRuntimeObject::s_info)) { + // Unwrap a Java instance. + JavaRuntimeObject* runtimeObject = static_cast<JavaRuntimeObject*>(object); + JavaInstance* instance = runtimeObject->getInternalJavaInstance(); if (instance) result.l = instance->javaInstance(); - } else if (objectImp->classInfo() == &RuntimeArray::s_info) { + } else if (object->classInfo() == &RuntimeArray::s_info) { // Input is a JavaScript Array that was originally created from a Java Array - RuntimeArray* imp = static_cast<RuntimeArray*>(objectImp); + RuntimeArray* imp = static_cast<RuntimeArray*>(object); JavaArray* array = static_cast<JavaArray*>(imp->getConcreteArray()); result.l = array->javaArray(); - } else if (objectImp->classInfo() == &JSArray::info) { + } else if (object->classInfo() == &JSArray::info) { // Input is a Javascript Array. We need to create it to a Java Array. result.l = convertArrayInstanceToJavaArray(exec, asArray(value), javaClassName); + } else if (!result.l && (!strcmp(javaClassName, "java.lang.Object")) || (!strcmp(javaClassName, "netscape.javascript.JSObject"))) { + // Wrap objects in JSObject instances. + JNIEnv* env = getJNIEnv(); + jclass jsObjectClass = env->FindClass("sun/plugin/javascript/webkit/JSObject"); + jmethodID constructorID = env->GetMethodID(jsObjectClass, "<init>", "(J)V"); + if (constructorID) { + jlong nativeHandle = ptr_to_jlong(object); + rootObject->gcProtect(object); + result.l = env->NewObject(jsObjectClass, constructorID, nativeHandle); + } } } - // Now convert value to a string if the target type is a java.lang.string, and we're not - // converting from a Null. - if (!result.l && !strcmp(javaClassName, "java.lang.String")) { -#ifdef CONVERT_NULL_TO_EMPTY_STRING - if (value->isNull()) { + // Create an appropriate Java object if target type is java.lang.Object. + if (!result.l && !strcmp(javaClassName, "java.lang.Object")) { + if (value.isString()) { + UString stringValue = asString(value)->value(exec); JNIEnv* env = getJNIEnv(); - jchar buf[2]; - jobject javaString = env->functions->NewString(env, buf, 0); + jobject javaString = env->functions->NewString(env, (const jchar*)stringValue.data(), stringValue.size()); result.l = javaString; - } else -#else - if (!value.isNull()) -#endif - { + } else if (value.isNumber()) { + double doubleValue = value.uncheckedGetNumber(); + JNIEnv* env = getJNIEnv(); + jclass clazz = env->FindClass("java/lang/Double"); + jmethodID constructor = env->GetMethodID(clazz, "<init>", "(D)V"); + jobject javaDouble = env->functions->NewObject(env, clazz, constructor, doubleValue); + result.l = javaDouble; + } else if (value.isBoolean()) { + bool boolValue = value.getBoolean(); + JNIEnv* env = getJNIEnv(); + jclass clazz = env->FindClass("java/lang/Boolean"); + jmethodID constructor = env->GetMethodID(clazz, "<init>", "(Z)V"); + jobject javaBoolean = env->functions->NewObject(env, clazz, constructor, boolValue); + result.l = javaBoolean; + } else if (value.isUndefined()) { + UString stringValue = "undefined"; + JNIEnv* env = getJNIEnv(); + jobject javaString = env->functions->NewString(env, (const jchar*)stringValue.data(), stringValue.size()); + result.l = javaString; + } + } + + // Convert value to a string if the target type is a java.lang.String, and we're not + // converting from a null. + if (!result.l && !strcmp(javaClassName, "java.lang.String")) { + if (!value.isNull()) { UString stringValue = value.toString(exec); JNIEnv* env = getJNIEnv(); - jobject javaString = env->functions->NewString(env, (const jchar *)stringValue.data(), stringValue.size()); + jobject javaString = env->functions->NewString(env, (const jchar*)stringValue.data(), stringValue.size()); result.l = javaString; } +<<<<<<< HEAD } else if (!result.l) // ANDROID memset(&result, 0, sizeof(jvalue)); // Handle it the same as a void case +======= + } +>>>>>>> webkit.org at r58033 } break; @@ -272,15 +308,15 @@ jvalue convertValueToJValue(ExecState* exec, JSValue value, JNIType jniType, con } break; - break; - case invalid_type: - default: case void_type: +<<<<<<< HEAD { // ANDROID memset(&result, 0, sizeof(jvalue)); } +======= +>>>>>>> webkit.org at r58033 break; } return result; diff --git a/WebCore/bridge/jni/jsc/JNIUtilityPrivate.h b/WebCore/bridge/jni/jsc/JNIUtilityPrivate.h index 0297f97..8d4652d 100644 --- a/WebCore/bridge/jni/jsc/JNIUtilityPrivate.h +++ b/WebCore/bridge/jni/jsc/JNIUtilityPrivate.h @@ -39,7 +39,9 @@ class JSObject; namespace Bindings { -jvalue convertValueToJValue(ExecState*, JSValue, JNIType, const char* javaClassName); +class RootObject; + +jvalue convertValueToJValue(ExecState*, RootObject*, JSValue, JNIType, const char* javaClassName); bool dispatchJNICall(ExecState*, const void* targetAppletView, jobject obj, bool isStatic, JNIType returnType, jmethodID methodID, jvalue* args, jvalue& result, const char* callingURL, JSValue& exceptionDescription); } // namespace Bindings diff --git a/WebCore/bridge/jni/jsc/JavaClassJSC.cpp b/WebCore/bridge/jni/jsc/JavaClassJSC.cpp index ec5c172..e1b8b4c 100644 --- a/WebCore/bridge/jni/jsc/JavaClassJSC.cpp +++ b/WebCore/bridge/jni/jsc/JavaClassJSC.cpp @@ -40,7 +40,7 @@ JavaClass::JavaClass(jobject anInstance) jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;"); if (!aClass) { - fprintf(stderr, "%s: unable to call getClass on instance %p\n", __PRETTY_FUNCTION__, anInstance); + LOG_ERROR("Unable to call getClass on instance %p", anInstance); m_name = fastStrDup("<Unknown>"); return; } diff --git a/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp b/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp index f2a2cf4..666df54 100644 --- a/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp +++ b/WebCore/bridge/jni/jsc/JavaInstanceJSC.cpp @@ -28,16 +28,20 @@ #if ENABLE(MAC_JAVA_BRIDGE) +#include "JavaRuntimeObject.h" #include "JNIBridgeJSC.h" #include "JNIUtility.h" #include "JNIUtilityPrivate.h" #include "JavaClassJSC.h" +#include "Logging.h" +#include "runtime_method.h" #include "runtime_object.h" #include "runtime_root.h" #include <runtime/ArgList.h> #include <runtime/Error.h> #include <runtime/JSLock.h> +<<<<<<< HEAD #if PLATFORM(ANDROID) #include <assert.h> #endif @@ -56,8 +60,11 @@ #define LOG_TAG JavaInstanceJSC.cpp #endif +======= +>>>>>>> webkit.org at r58033 using namespace JSC::Bindings; using namespace JSC; +using namespace WebCore; JavaInstance::JavaInstance(jobject instance, PassRefPtr<RootObject> rootObject) : Instance(rootObject) @@ -71,6 +78,11 @@ JavaInstance::~JavaInstance() delete m_class; } +RuntimeObject* JavaInstance::newRuntimeObject(ExecState* exec) +{ + return new (exec) JavaRuntimeObject(exec, this); +} + #define NUM_LOCAL_REFS 64 void JavaInstance::virtualBegin() @@ -119,10 +131,35 @@ JSValue JavaInstance::booleanValue() const return jsBoolean(booleanValue); } -JSValue JavaInstance::invokeMethod(ExecState* exec, const MethodList& methodList, const ArgList &args) +class JavaRuntimeMethod : public RuntimeMethod { +public: + JavaRuntimeMethod(ExecState* exec, const Identifier& name, Bindings::MethodList& list) + : RuntimeMethod(exec, name, list) + { + } + + virtual const ClassInfo* classInfo() const { return &s_info; } + + static const ClassInfo s_info; +}; + +const ClassInfo JavaRuntimeMethod::s_info = { "JavaRuntimeMethod", &RuntimeMethod::s_info, 0, 0 }; + +JSValue JavaInstance::getMethod(ExecState* exec, const Identifier& propertyName) +{ + MethodList methodList = getClass()->methodsNamed(propertyName, this); + return new (exec) JavaRuntimeMethod(exec, propertyName, methodList); +} + +JSValue JavaInstance::invokeMethod(ExecState* exec, RuntimeMethod* runtimeMethod, const ArgList &args) { - int i, count = args.size(); - jvalue* jArgs; + if (!asObject(runtimeMethod)->inherits(&JavaRuntimeMethod::s_info)) + return throwError(exec, TypeError, "Attempt to invoke non-Java method on Java object."); + + const MethodList& methodList = *runtimeMethod->methods(); + + int i; + int count = args.size(); JSValue resultValue; Method* method = 0; size_t numMethods = methodList.size(); @@ -132,31 +169,27 @@ JSValue JavaInstance::invokeMethod(ExecState* exec, const MethodList& methodList // 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; for (size_t methodIndex = 0; methodIndex < numMethods; methodIndex++) { - aMethod = methodList[methodIndex]; + Method* aMethod = methodList[methodIndex]; if (aMethod->numParameters() == count) { method = aMethod; break; } } if (!method) { - JS_LOG("unable to find an appropiate method\n"); + LOG(LiveConnect, "JavaInstance::invokeMethod unable to find an appropiate method"); return jsUndefined(); } const JavaMethod* jMethod = static_cast<const JavaMethod*>(method); - JS_LOG("call %s %s on %p\n", UString(jMethod->name()).UTF8String().c_str(), jMethod->signature(), m_instance->m_instance); + LOG(LiveConnect, "JavaInstance::invokeMethod call %s %s on %p", UString(jMethod->name()).UTF8String().data(), jMethod->signature(), m_instance->m_instance); - if (count > 0) - jArgs = (jvalue*)malloc(count * sizeof(jvalue)); - else - jArgs = 0; + Vector<jvalue> jArgs(count); for (i = 0; i < count; i++) { JavaParameter* aParameter = jMethod->parameterAt(i); - jArgs[i] = convertValueToJValue(exec, args.at(i), aParameter->getJNIType(), aParameter->type()); - JS_LOG("arg[%d] = %s\n", i, args.at(i).toString(exec).ascii()); + jArgs[i] = convertValueToJValue(exec, m_rootObject.get(), args.at(i), aParameter->getJNIType(), aParameter->type()); + LOG(LiveConnect, "JavaInstance::invokeMethod arg[%d] = %s", i, args.at(i).toString(exec).ascii()); } jvalue result; @@ -173,55 +206,53 @@ JSValue JavaInstance::invokeMethod(ExecState* exec, const MethodList& methodList jobject obj = m_instance->m_instance; JSValue exceptionDescription; const char *callingURL = 0; // FIXME, need to propagate calling URL to Java - handled = dispatchJNICall(exec, rootObject->nativeHandle(), obj, jMethod->isStatic(), jMethod->JNIReturnType(), jMethod->methodID(obj), jArgs, result, callingURL, exceptionDescription); + handled = dispatchJNICall(exec, rootObject->nativeHandle(), obj, jMethod->isStatic(), jMethod->JNIReturnType(), jMethod->methodID(obj), jArgs.data(), result, callingURL, exceptionDescription); if (exceptionDescription) { throwError(exec, GeneralError, exceptionDescription.toString(exec)); - free(jArgs); return jsUndefined(); } } - // The following code can be conditionally removed once we have a Tiger update that - // contains the new Java plugin. It is needed for builds prior to Tiger. +#ifdef BUILDING_ON_TIGER if (!handled) { jobject obj = m_instance->m_instance; switch (jMethod->JNIReturnType()) { case void_type: - callJNIMethodIDA<void>(obj, jMethod->methodID(obj), jArgs); + callJNIMethodIDA<void>(obj, jMethod->methodID(obj), jArgs.data()); break; case object_type: - result.l = callJNIMethodIDA<jobject>(obj, jMethod->methodID(obj), jArgs); + result.l = callJNIMethodIDA<jobject>(obj, jMethod->methodID(obj), jArgs.data()); break; case boolean_type: - result.z = callJNIMethodIDA<jboolean>(obj, jMethod->methodID(obj), jArgs); + result.z = callJNIMethodIDA<jboolean>(obj, jMethod->methodID(obj), jArgs.data()); break; case byte_type: - result.b = callJNIMethodIDA<jbyte>(obj, jMethod->methodID(obj), jArgs); + result.b = callJNIMethodIDA<jbyte>(obj, jMethod->methodID(obj), jArgs.data()); break; case char_type: - result.c = callJNIMethodIDA<jchar>(obj, jMethod->methodID(obj), jArgs); + result.c = callJNIMethodIDA<jchar>(obj, jMethod->methodID(obj), jArgs.data()); break; case short_type: - result.s = callJNIMethodIDA<jshort>(obj, jMethod->methodID(obj), jArgs); + result.s = callJNIMethodIDA<jshort>(obj, jMethod->methodID(obj), jArgs.data()); break; case int_type: - result.i = callJNIMethodIDA<jint>(obj, jMethod->methodID(obj), jArgs); + result.i = callJNIMethodIDA<jint>(obj, jMethod->methodID(obj), jArgs.data()); break; - case long_type: - result.j = callJNIMethodIDA<jlong>(obj, jMethod->methodID(obj), jArgs); + result.j = callJNIMethodIDA<jlong>(obj, jMethod->methodID(obj), jArgs.data()); break; case float_type: - result.f = callJNIMethodIDA<jfloat>(obj, jMethod->methodID(obj), jArgs); + result.f = callJNIMethodIDA<jfloat>(obj, jMethod->methodID(obj), jArgs.data()); break; case double_type: - result.d = callJNIMethodIDA<jdouble>(obj, jMethod->methodID(obj), jArgs); + result.d = callJNIMethodIDA<jdouble>(obj, jMethod->methodID(obj), jArgs.data()); break; + case array_type: case invalid_type: - default: break; } } +#endif switch (jMethod->JNIReturnType()) { case void_type: @@ -233,13 +264,28 @@ JSValue JavaInstance::invokeMethod(ExecState* exec, const MethodList& methodList case object_type: { if (result.l) { + // FIXME: array_type return type is handled below, can we actually get an array here? const char* arrayType = jMethod->returnType(); if (arrayType[0] == '[') resultValue = JavaArray::convertJObjectToArray(exec, result.l, arrayType, rootObject); - else - resultValue = JavaInstance::create(result.l, rootObject)->createRuntimeObject(exec); + else { + jobject classOfInstance = callJNIMethod<jobject>(result.l, "getClass", "()Ljava/lang/Class;"); + jstring className = static_cast<jstring>(callJNIMethod<jobject>(classOfInstance, "getName", "()Ljava/lang/String;")); + if (!strcmp(JavaString(className).UTF8String(), "sun.plugin.javascript.webkit.JSObject")) { + // Pull the nativeJSObject value from the Java instance. This is a pointer to the JSObject. + JNIEnv* env = getJNIEnv(); + jfieldID fieldID = env->GetFieldID(static_cast<jclass>(classOfInstance), "nativeJSObject", "J"); + jlong nativeHandle = env->GetLongField(result.l, fieldID); + // FIXME: Handling of undefined values differs between functions in JNIUtilityPrivate.cpp and those in those in jni_jsobject.mm, + // and so it does between different versions of LiveConnect spec. There should not be multiple code paths to do the same work. + if (nativeHandle == 1 /* UndefinedHandle */) + return jsUndefined(); + return static_cast<JSObject*>(jlong_to_ptr(nativeHandle)); + } else + return JavaInstance::create(result.l, rootObject)->createRuntimeObject(exec); + } } else - resultValue = jsUndefined(); + return jsUndefined(); } break; @@ -291,16 +337,21 @@ JSValue JavaInstance::invokeMethod(ExecState* exec, const MethodList& methodList } break; + case array_type: + { + const char* arrayType = jMethod->returnType(); + ASSERT(arrayType[0] == '['); + resultValue = JavaArray::convertJObjectToArray(exec, result.l, arrayType, rootObject); + } + break; + case invalid_type: - default: { resultValue = jsUndefined(); } break; } - free(jArgs); - return resultValue; } @@ -328,11 +379,15 @@ JSValue JavaInstance::valueOf(ExecState* exec) const JObjectWrapper::JObjectWrapper(jobject instance) : m_refCount(0) { +<<<<<<< HEAD assert(instance); #if PLATFORM(ANDROID) if (!instance) LOGE("Attempted to create JObjectWrapper for null object"); #endif +======= + ASSERT(instance); +>>>>>>> webkit.org at r58033 // Cache the JNIEnv used to get the global ref for this java instance. // It'll be used to delete the reference. @@ -340,19 +395,24 @@ JObjectWrapper::JObjectWrapper(jobject instance) m_instance = m_env->NewGlobalRef(instance); - JS_LOG("new global ref %p for %p\n", m_instance, instance); + LOG(LiveConnect, "JObjectWrapper ctor new global ref %p for %p", m_instance, instance); +<<<<<<< HEAD if (!m_instance) #if PLATFORM(ANDROID) LOGE("%s: could not get GlobalRef for %p\n", __PRETTY_FUNCTION__, instance); #else fprintf(stderr, "%s: could not get GlobalRef for %p\n", __PRETTY_FUNCTION__, instance); #endif +======= + if (!m_instance) + LOG_ERROR("Could not get GlobalRef for %p", instance); +>>>>>>> webkit.org at r58033 } JObjectWrapper::~JObjectWrapper() { - JS_LOG("deleting global ref %p\n", m_instance); + LOG(LiveConnect, "JObjectWrapper dtor deleting global ref %p", m_instance); m_env->DeleteGlobalRef(m_instance); } diff --git a/WebCore/bridge/jni/jsc/JavaInstanceJSC.h b/WebCore/bridge/jni/jsc/JavaInstanceJSC.h index a46c6d3..d395cc8 100644 --- a/WebCore/bridge/jni/jsc/JavaInstanceJSC.h +++ b/WebCore/bridge/jni/jsc/JavaInstanceJSC.h @@ -82,7 +82,8 @@ public: virtual JSValue valueOf(ExecState*) const; virtual JSValue defaultValue(ExecState*, PreferredPrimitiveType) const; - virtual JSValue invokeMethod(ExecState* exec, const MethodList& method, const ArgList& args); + virtual JSValue getMethod(ExecState* exec, const Identifier& propertyName); + virtual JSValue invokeMethod(ExecState* exec, RuntimeMethod* method, const ArgList& args); jobject javaInstance() const { return m_instance->m_instance; } @@ -92,6 +93,9 @@ public: protected: JavaInstance(jobject instance, PassRefPtr<RootObject>); + + virtual RuntimeObject* newRuntimeObject(ExecState*); + virtual void virtualBegin(); virtual void virtualEnd(); diff --git a/WebCore/bridge/jni/jsc/JavaRuntimeObject.cpp b/WebCore/bridge/jni/jsc/JavaRuntimeObject.cpp new file mode 100644 index 0000000..dc58b71 --- /dev/null +++ b/WebCore/bridge/jni/jsc/JavaRuntimeObject.cpp @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 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 "JavaInstanceJSC.h" +#include "JavaRuntimeObject.h" + +namespace JSC { +namespace Bindings { + +const ClassInfo JavaRuntimeObject::s_info = { "JavaRuntimeObject", &RuntimeObject::s_info, 0, 0 }; + +JavaRuntimeObject::JavaRuntimeObject(ExecState* exec, PassRefPtr<JavaInstance> instance) + : RuntimeObject(exec, instance) +{ +} + +JavaRuntimeObject::~JavaRuntimeObject() +{ +} + +JavaInstance* JavaRuntimeObject::getInternalJavaInstance() const +{ + return static_cast<JavaInstance*>(getInternalInstance()); +} + + + +} +} diff --git a/WebCore/bridge/jni/jsc/JavaRuntimeObject.h b/WebCore/bridge/jni/jsc/JavaRuntimeObject.h new file mode 100644 index 0000000..d9bf693 --- /dev/null +++ b/WebCore/bridge/jni/jsc/JavaRuntimeObject.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * 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 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 JavaRuntimeObject_h +#define JavaRuntimeObject_h + +#include "runtime_object.h" + +namespace JSC { +namespace Bindings { + +class JavaInstance; + +class JavaRuntimeObject : public RuntimeObject { +public: + JavaRuntimeObject(ExecState*, PassRefPtr<JavaInstance>); + virtual ~JavaRuntimeObject(); + + JavaInstance* getInternalJavaInstance() const; + + static const ClassInfo s_info; + +private: + virtual const ClassInfo* classInfo() const { return &s_info; } +}; + +} +} + +#endif diff --git a/WebCore/bridge/jni/jsc/JavaStringJSC.h b/WebCore/bridge/jni/jsc/JavaStringJSC.h index 7c37f70..0a7dad5 100644 --- a/WebCore/bridge/jni/jsc/JavaStringJSC.h +++ b/WebCore/bridge/jni/jsc/JavaStringJSC.h @@ -62,13 +62,13 @@ public: const char* UTF8String() const { - if (!m_utf8String.c_str()) { + if (!m_utf8String.data()) { JSLock lock(SilenceAssertionsOnly); m_utf8String = UString(m_rep).UTF8String(); } - return m_utf8String.c_str(); + return m_utf8String.data(); } - const jchar* uchars() const { return (const jchar*)m_rep->data(); } + const jchar* uchars() const { return (const jchar*)m_rep->characters(); } int length() const { return m_rep->length(); } UString uString() const { return UString(m_rep); } diff --git a/WebCore/bridge/jni/v8/JavaStringV8.h b/WebCore/bridge/jni/v8/JavaStringV8.h index 08d4b95..21420b7 100644 --- a/WebCore/bridge/jni/v8/JavaStringV8.h +++ b/WebCore/bridge/jni/v8/JavaStringV8.h @@ -26,8 +26,8 @@ #ifndef JavaStringV8_h #define JavaStringV8_h -#include "CString.h" #include "JNIUtility.h" +#include <wtf/text/CString.h> namespace JSC { @@ -42,7 +42,7 @@ public: { int size = e->GetStringLength(s); const char* cs = getCharactersFromJStringInEnv(e, s); - m_utf8String = WebCore::CString(cs, size); + m_utf8String = WTF::CString(cs, size); releaseCharactersForJStringInEnv(e, s, cs); } @@ -51,7 +51,7 @@ public: int length() const { return m_utf8String.length(); } private: - WebCore::CString m_utf8String; + WTF::CString m_utf8String; }; } // namespace Bindings |