18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block * Copyright (C) 2003, 2004, 2005, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
38e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
48e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without
58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions
68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met:
78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *    documentation and/or other materials provided with the distribution.
128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project *
138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2320b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */
258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h"
2720ab751acc0d49d74648373f701f3d0c4ff187c0Steve Block#include "JNIUtility.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2921939df44de1705786c545cd1bf519d47250322dBen Murdoch#if ENABLE(JAVA_BRIDGE)
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <dlfcn.h>
328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace JSC {
348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace Bindings {
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Blockstatic jint KJSGetCreatedJavaVMs(JavaVM** vmBuf, jsize bufLen, jsize* nVMs)
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    static void* javaVMFramework = 0;
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!javaVMFramework)
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        javaVMFramework = dlopen("/System/Library/Frameworks/JavaVM.framework/JavaVM", RTLD_LAZY);
428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!javaVMFramework)
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return JNI_ERR;
448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
4520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    typedef jint(*FunctionPointerType)(JavaVM**, jsize, jsize*);
4620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    static FunctionPointerType functionPointer = 0;
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!functionPointer)
4820b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        functionPointer = reinterpret_cast<FunctionPointerType>(dlsym(javaVMFramework, "JNI_GetCreatedJavaVMs"));
498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!functionPointer)
508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return JNI_ERR;
518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return functionPointer(vmBuf, bufLen, nVMs);
528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
5420b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Blockstatic JavaVM* jvm = 0;
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// Provide the ability for an outside component to specify the JavaVM to use
5720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block// If the jvm value is set, the getJavaVM function below will just return.
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// In getJNIEnv(), if AttachCurrentThread is called to a VM that is already
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project// attached, the result is a no-op.
6020b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Blockvoid setJavaVM(JavaVM* javaVM)
618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jvm = javaVM;
638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
6520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve BlockJavaVM* getJavaVM()
668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (jvm)
688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return jvm;
698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
7020b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    JavaVM* jvmArray[1];
718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jsize bufLen = 1;
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jsize nJVMs = 0;
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jint jniError = 0;
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Assumes JVM is already running ..., one per process
7620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    jniError = KJSGetCreatedJavaVMs(jvmArray, bufLen, &nJVMs);
7720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    if (jniError == JNI_OK && nJVMs > 0)
788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        jvm = jvmArray[0];
7920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    else
80dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        LOG_ERROR("JNI_GetCreatedJavaVMs failed, returned %ld", static_cast<long>(jniError));
8120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return jvm;
838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectJNIEnv* getJNIEnv()
868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    union {
888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        JNIEnv* env;
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        void* dummy;
908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    } u;
918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jint jniError = 0;
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
9381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#if OS(ANDROID)
9481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    jniError = getJavaVM()->AttachCurrentThread(&u.env, 0);
9581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#else
9620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    jniError = getJavaVM()->AttachCurrentThread(&u.dummy, 0);
9781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#endif
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (jniError == JNI_OK)
998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return u.env;
100dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block    LOG_ERROR("AttachCurrentThread failed, returned %ld", static_cast<long>(jniError));
10120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    return 0;
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
10420b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve BlockjmethodID getMethodID(jobject obj, const char* name, const char* sig)
1058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
10620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    JNIEnv* env = getJNIEnv();
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jmethodID mid = 0;
10820b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
10920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    if (env) {
11020b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        jclass cls = env->GetObjectClass(obj);
11120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        if (cls) {
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            mid = env->GetMethodID(cls, name, sig);
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            if (!mid) {
1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                env->ExceptionClear();
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                mid = env->GetStaticMethodID(cls, name, sig);
11620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block                if (!mid)
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    env->ExceptionClear();
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        env->DeleteLocalRef(cls);
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return mid;
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
12520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Blockconst char* getCharactersFromJString(jstring aJString)
1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
12720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    return getCharactersFromJStringInEnv(getJNIEnv(), aJString);
1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13020b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Blockvoid releaseCharactersForJString(jstring aJString, const char* s)
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
13220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    releaseCharactersForJStringInEnv(getJNIEnv(), aJString, s);
1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
13520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Blockconst char* getCharactersFromJStringInEnv(JNIEnv* env, jstring aJString)
1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jboolean isCopy;
13820b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    const char* s = env->GetStringUTFChars(aJString, &isCopy);
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!s) {
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        env->ExceptionDescribe();
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        env->ExceptionClear();
14220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        fprintf(stderr, "\n");
1438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return s;
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
14720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Blockvoid releaseCharactersForJStringInEnv(JNIEnv* env, jstring aJString, const char* s)
1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
14920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    env->ReleaseStringUTFChars(aJString, s);
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Blockconst jchar* getUCharactersFromJStringInEnv(JNIEnv* env, jstring aJString)
1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jboolean isCopy;
15520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    const jchar* s = env->GetStringChars(aJString, &isCopy);
1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!s) {
1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        env->ExceptionDescribe();
1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        env->ExceptionClear();
15920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        fprintf(stderr, "\n");
1608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return s;
1628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
16420b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Blockvoid releaseUCharactersForJStringInEnv(JNIEnv* env, jstring aJString, const jchar* s)
1658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
16620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    env->ReleaseStringChars(aJString, s);
1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1692bde8e466a4451c7319e3a072d118917957d6554Steve BlockJavaType javaTypeFromClassName(const char* name)
1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1712bde8e466a4451c7319e3a072d118917957d6554Steve Block    JavaType type;
17220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
17320b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    if (!strcmp("byte", name))
1742bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeByte;
17520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    else if (!strcmp("short", name))
1762bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeShort;
17720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    else if (!strcmp("int", name))
1782bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeInt;
17920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    else if (!strcmp("long", name))
1802bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeLong;
18120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    else if (!strcmp("float", name))
1822bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeFloat;
18320b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    else if (!strcmp("double", name))
1842bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeDouble;
18520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    else if (!strcmp("char", name))
1862bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeChar;
18720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    else if (!strcmp("boolean", name))
1882bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeBoolean;
18920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    else if (!strcmp("void", name))
1902bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeVoid;
19120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    else if ('[' == name[0])
1922bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeArray;
1932bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(V8)
1942bde8e466a4451c7319e3a072d118917957d6554Steve Block    else if (!strcmp("java.lang.String", name))
1952bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeString;
1962bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
1978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    else
1982bde8e466a4451c7319e3a072d118917957d6554Steve Block        type = JavaTypeObject;
19920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return type;
2018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2032bde8e466a4451c7319e3a072d118917957d6554Steve Blockconst char* signatureFromJavaType(JavaType type)
2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
20520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    switch (type) {
2062bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeVoid:
20720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "V";
20820b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2092bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeArray:
21020b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "[";
21120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2122bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeObject:
2132bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(V8)
2142bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeString:
2152bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
21620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "L";
21720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2182bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeBoolean:
21920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "Z";
22020b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2212bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeByte:
22220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "B";
22320b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2242bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeChar:
22520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "C";
22620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2272bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeShort:
22820b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "S";
22920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2302bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeInt:
23120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "I";
23220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2332bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeLong:
23420b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "J";
23520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2362bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeFloat:
23720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "F";
23820b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2392bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeDouble:
24020b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        return "D";
24120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
2422bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeInvalid:
24320b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    default:
2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return "";
2478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2492bde8e466a4451c7319e3a072d118917957d6554Steve BlockJavaType javaTypeFromPrimitiveType(char type)
2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
25120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    switch (type) {
25220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case 'V':
2532bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeVoid;
25420b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
25520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case 'L':
2562bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeObject;
25720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
25820b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case '[':
2592bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeArray;
26020b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
26120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case 'Z':
2622bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeBoolean;
26320b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
26420b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case 'B':
2652bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeByte;
26620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
26720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case 'C':
2682bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeChar;
26920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
27020b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case 'S':
2712bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeShort;
27220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
27320b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case 'I':
2742bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeInt;
27520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
27620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case 'J':
2772bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeLong;
27820b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
27920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case 'F':
2802bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeFloat;
28120b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
28220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    case 'D':
2832bde8e466a4451c7319e3a072d118917957d6554Steve Block        return JavaTypeDouble;
28420b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block
28520b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    default:
2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        break;
2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
2882bde8e466a4451c7319e3a072d118917957d6554Steve Block    return JavaTypeInvalid;
2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
2908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2912bde8e466a4451c7319e3a072d118917957d6554Steve Blockjvalue getJNIField(jobject obj, JavaType type, const char* name, const char* signature)
2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
29320b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    JavaVM* jvm = getJavaVM();
29420b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    JNIEnv* env = getJNIEnv();
2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jvalue result;
2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
29727ec2eed4cd59f9a3311789d4fa99829e3e67e20Steve Block    memset(&result, 0, sizeof(jvalue));
29820b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block    if (obj && jvm && env) {
2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        jclass cls = env->GetObjectClass(obj);
30020b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        if (cls) {
3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            jfieldID field = env->GetFieldID(cls, name, signature);
30220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block            if (field) {
3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                switch (type) {
3042bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeArray:
3052bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeObject:
3062bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(V8)
3072bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeString:
3082bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
3098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.l = env->functions->GetObjectField(env, obj, field);
3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
3112bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeBoolean:
3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.z = env->functions->GetBooleanField(env, obj, field);
3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
3142bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeByte:
3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.b = env->functions->GetByteField(env, obj, field);
3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
3172bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeChar:
3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.c = env->functions->GetCharField(env, obj, field);
3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
3202bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeShort:
3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.s = env->functions->GetShortField(env, obj, field);
3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
3232bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeInt:
3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.i = env->functions->GetIntField(env, obj, field);
3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
3262bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeLong:
3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.j = env->functions->GetLongField(env, obj, field);
3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
3292bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeFloat:
3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.f = env->functions->GetFloatField(env, obj, field);
3318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
3322bde8e466a4451c7319e3a072d118917957d6554Steve Block                case JavaTypeDouble:
3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    result.d = env->functions->GetDoubleField(env, obj, field);
3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                    break;
3358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                default:
336dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                    LOG_ERROR("Invalid field type (%d)", static_cast<int>(type));
3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                }
33820b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block            } else {
339dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block                LOG_ERROR("Could not find field: %s", name);
3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                env->ExceptionDescribe();
3418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project                env->ExceptionClear();
34220b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block                fprintf(stderr, "\n");
3438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
3448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            env->DeleteLocalRef(cls);
34620b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block        } else
347dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block            LOG_ERROR("Could not find class for object");
3488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
3498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return result;
3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
3528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
3532bde8e466a4451c7319e3a072d118917957d6554Steve Blockjvalue callJNIMethod(jobject object, JavaType returnType, const char* name, const char* signature, jvalue* args)
3542bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3552bde8e466a4451c7319e3a072d118917957d6554Steve Block    jmethodID methodId = getMethodID(object, name, signature);
3562bde8e466a4451c7319e3a072d118917957d6554Steve Block    jvalue result;
3572bde8e466a4451c7319e3a072d118917957d6554Steve Block    switch (returnType) {
3582bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeVoid:
3592bde8e466a4451c7319e3a072d118917957d6554Steve Block        callJNIMethodIDA<void>(object, methodId, args);
3602bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3612bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeObject:
3622bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(V8)
3632bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeString:
3642bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
3652bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.l = callJNIMethodIDA<jobject>(object, methodId, args);
3662bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3672bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeBoolean:
3682bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.z = callJNIMethodIDA<jboolean>(object, methodId, args);
3692bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3702bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeByte:
3712bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.b = callJNIMethodIDA<jbyte>(object, methodId, args);
3722bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3732bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeChar:
3742bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.c = callJNIMethodIDA<jchar>(object, methodId, args);
3752bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3762bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeShort:
3772bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.s = callJNIMethodIDA<jshort>(object, methodId, args);
3782bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3792bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeInt:
3802bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.i = callJNIMethodIDA<jint>(object, methodId, args);
3812bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3822bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeLong:
3832bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.j = callJNIMethodIDA<jlong>(object, methodId, args);
3842bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3852bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeFloat:
3862bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.f = callJNIMethodIDA<jfloat>(object, methodId, args);
3872bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3882bde8e466a4451c7319e3a072d118917957d6554Steve Block    case JavaTypeDouble:
3892bde8e466a4451c7319e3a072d118917957d6554Steve Block        result.d = callJNIMethodIDA<jdouble>(object, methodId, args);
3902bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3912bde8e466a4451c7319e3a072d118917957d6554Steve Block    default:
3922bde8e466a4451c7319e3a072d118917957d6554Steve Block        break;
3932bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3942bde8e466a4451c7319e3a072d118917957d6554Steve Block    return result;
3952bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3962bde8e466a4451c7319e3a072d118917957d6554Steve Block
39720b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block} // namespace Bindings
3988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
39920b6a09ef6412dd2ad39520ea8d4c2fcdafe3f08Steve Block} // namespace JSC
4008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
40121939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif // ENABLE(JAVA_BRIDGE)
402