18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/*
29d25b5789c947f3974b7a4f722240ae95cad733eSteve Block * Copyright (C) 2003, 2004, 2005, 2006, 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
239d25b5789c947f3974b7a4f722240ae95cad733eSteve 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"
27be164dbcfc9adfae8ae7c559ebdff00580f8086dSteve Block#include "JavaClassJSC.h"
288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
2921939df44de1705786c545cd1bf519d47250322dBen Murdoch#if ENABLE(JAVA_BRIDGE)
308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "JSDOMWindow.h"
3281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch#include "JavaFieldJSC.h"
332bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "JavaMethodJobject.h"
34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include <runtime/Identifier.h>
358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <runtime/JSLock.h>
368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectusing namespace JSC::Bindings;
388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectJavaClass::JavaClass(jobject anInstance)
408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");
429d25b5789c947f3974b7a4f722240ae95cad733eSteve Block
438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (!aClass) {
44dcc8cf2e65d1aa555cce12431a16547e66b469eeSteve Block        LOG_ERROR("Unable to call getClass on instance %p", anInstance);
458a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        m_name = fastStrDup("<Unknown>");
468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return;
478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
489d25b5789c947f3974b7a4f722240ae95cad733eSteve Block
49ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block    if (jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;")) {
50ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block        const char* classNameC = getCharactersFromJString(className);
518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        m_name = fastStrDup(classNameC);
52ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block        releaseCharactersForJString(className, classNameC);
53ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block    } else
548a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block        m_name = fastStrDup("<Unknown>");
558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    int i;
579d25b5789c947f3974b7a4f722240ae95cad733eSteve Block    JNIEnv* env = getJNIEnv();
588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get the fields
60ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block    if (jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;")) {
61ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block        int numFields = env->GetArrayLength(fields);
62ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block        for (i = 0; i < numFields; i++) {
63ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block            jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
64ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block            JavaField* aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
65ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block            {
66ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block                JSLock lock(SilenceAssertionsOnly);
6781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                m_fields.set(aField->name().impl(), aField);
68ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block            }
69ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block            env->DeleteLocalRef(aJField);
708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
71ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block        env->DeleteLocalRef(fields);
728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    // Get the methods
75ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block    if (jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;")) {
76ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block        int numMethods = env->GetArrayLength(methods);
77ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block        for (i = 0; i < numMethods; i++) {
78ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block            jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i);
792bde8e466a4451c7319e3a072d118917957d6554Steve Block            JavaMethod* aMethod = new JavaMethodJobject(env, aJMethod); // deleted in the JavaClass destructor
80ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block            MethodList* methodList;
81ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block            {
82ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block                JSLock lock(SilenceAssertionsOnly);
83ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block
8481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                methodList = m_methods.get(aMethod->name().impl());
85ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block                if (!methodList) {
86ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block                    methodList = new MethodList();
8781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch                    m_methods.set(aMethod->name().impl(), methodList);
88ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block                }
898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project            }
90ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block            methodList->append(aMethod);
91ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block            env->DeleteLocalRef(aJMethod);
928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        }
93ec28ff89fe9033115677d675a81d6a95419fcff4Steve Block        env->DeleteLocalRef(methods);
949d25b5789c947f3974b7a4f722240ae95cad733eSteve Block    }
95073888a8dc1673fa90ca33226485b7bb0e19d460Ben Murdoch
96469a7df2e8a310b163b244af6bcc308ab29f0a1cPatrick Scott    env->DeleteLocalRef(aClass);
978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
999d25b5789c947f3974b7a4f722240ae95cad733eSteve BlockJavaClass::~JavaClass()
1009d25b5789c947f3974b7a4f722240ae95cad733eSteve Block{
1018a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block    fastFree(const_cast<char*>(m_name));
1028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1030bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    JSLock lock(SilenceAssertionsOnly);
1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1059d25b5789c947f3974b7a4f722240ae95cad733eSteve Block    deleteAllValues(m_fields);
1069d25b5789c947f3974b7a4f722240ae95cad733eSteve Block    m_fields.clear();
1078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1089d25b5789c947f3974b7a4f722240ae95cad733eSteve Block    MethodListMap::const_iterator end = m_methods.end();
1099d25b5789c947f3974b7a4f722240ae95cad733eSteve Block    for (MethodListMap::const_iterator it = m_methods.begin(); it != end; ++it) {
1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        const MethodList* methodList = it->second;
1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        deleteAllValues(*methodList);
1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        delete methodList;
1138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    }
1149d25b5789c947f3974b7a4f722240ae95cad733eSteve Block    m_methods.clear();
1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectMethodList JavaClass::methodsNamed(const Identifier& identifier, Instance*) const
1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
119f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    MethodList* methodList = m_methods.get(identifier.ustring().impl());
1209d25b5789c947f3974b7a4f722240ae95cad733eSteve Block
1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    if (methodList)
1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project        return *methodList;
1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project    return MethodList();
1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1269d25b5789c947f3974b7a4f722240ae95cad733eSteve BlockField* JavaClass::fieldNamed(const Identifier& identifier, Instance*) const
1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
128f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick    return m_fields.get(identifier.ustring().impl());
1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JavaClass::isNumberClass() const
1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1339d25b5789c947f3974b7a4f722240ae95cad733eSteve Block    return (!strcmp(m_name, "java.lang.Byte")
1349d25b5789c947f3974b7a4f722240ae95cad733eSteve Block        || !strcmp(m_name, "java.lang.Short")
1359d25b5789c947f3974b7a4f722240ae95cad733eSteve Block        || !strcmp(m_name, "java.lang.Integer")
1369d25b5789c947f3974b7a4f722240ae95cad733eSteve Block        || !strcmp(m_name, "java.lang.Long")
1379d25b5789c947f3974b7a4f722240ae95cad733eSteve Block        || !strcmp(m_name, "java.lang.Float")
1389d25b5789c947f3974b7a4f722240ae95cad733eSteve Block        || !strcmp(m_name, "java.lang.Double"));
1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JavaClass::isBooleanClass() const
1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1439d25b5789c947f3974b7a4f722240ae95cad733eSteve Block    return !strcmp(m_name, "java.lang.Boolean");
1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool JavaClass::isStringClass() const
1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{
1489d25b5789c947f3974b7a4f722240ae95cad733eSteve Block    return !strcmp(m_name, "java.lang.String");
1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project}
1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project
15121939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif // ENABLE(JAVA_BRIDGE)
152