Home | History | Annotate | Download | only in jsc
      1 /*
      2  * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
     17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
     20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
     21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "config.h"
     27 #include "JavaClassJSC.h"
     28 
     29 #if ENABLE(JAVA_BRIDGE)
     30 
     31 #include "JSDOMWindow.h"
     32 #include "JavaFieldJSC.h"
     33 #include "JavaMethodJobject.h"
     34 #include <runtime/Identifier.h>
     35 #include <runtime/JSLock.h>
     36 
     37 using namespace JSC::Bindings;
     38 
     39 JavaClass::JavaClass(jobject anInstance)
     40 {
     41     jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;");
     42 
     43     if (!aClass) {
     44         LOG_ERROR("Unable to call getClass on instance %p", anInstance);
     45         m_name = fastStrDup("<Unknown>");
     46         return;
     47     }
     48 
     49     if (jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;")) {
     50         const char* classNameC = getCharactersFromJString(className);
     51         m_name = fastStrDup(classNameC);
     52         releaseCharactersForJString(className, classNameC);
     53     } else
     54         m_name = fastStrDup("<Unknown>");
     55 
     56     int i;
     57     JNIEnv* env = getJNIEnv();
     58 
     59     // Get the fields
     60     if (jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;")) {
     61         int numFields = env->GetArrayLength(fields);
     62         for (i = 0; i < numFields; i++) {
     63             jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i);
     64             JavaField* aField = new JavaField(env, aJField); // deleted in the JavaClass destructor
     65             {
     66                 JSLock lock(SilenceAssertionsOnly);
     67                 m_fields.set(aField->name().impl(), aField);
     68             }
     69             env->DeleteLocalRef(aJField);
     70         }
     71         env->DeleteLocalRef(fields);
     72     }
     73 
     74     // Get the methods
     75     if (jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;")) {
     76         int numMethods = env->GetArrayLength(methods);
     77         for (i = 0; i < numMethods; i++) {
     78             jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i);
     79             JavaMethod* aMethod = new JavaMethodJobject(env, aJMethod); // deleted in the JavaClass destructor
     80             MethodList* methodList;
     81             {
     82                 JSLock lock(SilenceAssertionsOnly);
     83 
     84                 methodList = m_methods.get(aMethod->name().impl());
     85                 if (!methodList) {
     86                     methodList = new MethodList();
     87                     m_methods.set(aMethod->name().impl(), methodList);
     88                 }
     89             }
     90             methodList->append(aMethod);
     91             env->DeleteLocalRef(aJMethod);
     92         }
     93         env->DeleteLocalRef(methods);
     94     }
     95 
     96     env->DeleteLocalRef(aClass);
     97 }
     98 
     99 JavaClass::~JavaClass()
    100 {
    101     fastFree(const_cast<char*>(m_name));
    102 
    103     JSLock lock(SilenceAssertionsOnly);
    104 
    105     deleteAllValues(m_fields);
    106     m_fields.clear();
    107 
    108     MethodListMap::const_iterator end = m_methods.end();
    109     for (MethodListMap::const_iterator it = m_methods.begin(); it != end; ++it) {
    110         const MethodList* methodList = it->second;
    111         deleteAllValues(*methodList);
    112         delete methodList;
    113     }
    114     m_methods.clear();
    115 }
    116 
    117 MethodList JavaClass::methodsNamed(const Identifier& identifier, Instance*) const
    118 {
    119     MethodList* methodList = m_methods.get(identifier.ustring().impl());
    120 
    121     if (methodList)
    122         return *methodList;
    123     return MethodList();
    124 }
    125 
    126 Field* JavaClass::fieldNamed(const Identifier& identifier, Instance*) const
    127 {
    128     return m_fields.get(identifier.ustring().impl());
    129 }
    130 
    131 bool JavaClass::isNumberClass() const
    132 {
    133     return (!strcmp(m_name, "java.lang.Byte")
    134         || !strcmp(m_name, "java.lang.Short")
    135         || !strcmp(m_name, "java.lang.Integer")
    136         || !strcmp(m_name, "java.lang.Long")
    137         || !strcmp(m_name, "java.lang.Float")
    138         || !strcmp(m_name, "java.lang.Double"));
    139 }
    140 
    141 bool JavaClass::isBooleanClass() const
    142 {
    143     return !strcmp(m_name, "java.lang.Boolean");
    144 }
    145 
    146 bool JavaClass::isStringClass() const
    147 {
    148     return !strcmp(m_name, "java.lang.String");
    149 }
    150 
    151 #endif // ENABLE(JAVA_BRIDGE)
    152