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(MAC_JAVA_BRIDGE) 30 31 #include "JNIUtility.h" 32 #include "JSDOMWindow.h" 33 #include <runtime/Identifier.h> 34 #include <runtime/JSLock.h> 35 36 using namespace JSC::Bindings; 37 38 JavaClass::JavaClass(jobject anInstance) 39 { 40 jobject aClass = callJNIMethod<jobject>(anInstance, "getClass", "()Ljava/lang/Class;"); 41 42 if (!aClass) { 43 fprintf(stderr, "%s: unable to call getClass on instance %p\n", __PRETTY_FUNCTION__, anInstance); 44 m_name = fastStrDup("<Unknown>"); 45 return; 46 } 47 48 if (jstring className = (jstring)callJNIMethod<jobject>(aClass, "getName", "()Ljava/lang/String;")) { 49 const char* classNameC = getCharactersFromJString(className); 50 m_name = fastStrDup(classNameC); 51 releaseCharactersForJString(className, classNameC); 52 } else 53 m_name = fastStrDup("<Unknown>"); 54 55 int i; 56 JNIEnv* env = getJNIEnv(); 57 58 // Get the fields 59 if (jarray fields = (jarray)callJNIMethod<jobject>(aClass, "getFields", "()[Ljava/lang/reflect/Field;")) { 60 int numFields = env->GetArrayLength(fields); 61 for (i = 0; i < numFields; i++) { 62 jobject aJField = env->GetObjectArrayElement((jobjectArray)fields, i); 63 JavaField* aField = new JavaField(env, aJField); // deleted in the JavaClass destructor 64 { 65 JSLock lock(SilenceAssertionsOnly); 66 m_fields.set(((UString)aField->name()).rep(), aField); 67 } 68 env->DeleteLocalRef(aJField); 69 } 70 env->DeleteLocalRef(fields); 71 } 72 73 // Get the methods 74 if (jarray methods = (jarray)callJNIMethod<jobject>(aClass, "getMethods", "()[Ljava/lang/reflect/Method;")) { 75 int numMethods = env->GetArrayLength(methods); 76 for (i = 0; i < numMethods; i++) { 77 jobject aJMethod = env->GetObjectArrayElement((jobjectArray)methods, i); 78 JavaMethod* aMethod = new JavaMethod(env, aJMethod); // deleted in the JavaClass destructor 79 MethodList* methodList; 80 { 81 JSLock lock(SilenceAssertionsOnly); 82 83 methodList = m_methods.get(((UString)aMethod->name()).rep()); 84 if (!methodList) { 85 methodList = new MethodList(); 86 m_methods.set(((UString)aMethod->name()).rep(), methodList); 87 } 88 } 89 methodList->append(aMethod); 90 env->DeleteLocalRef(aJMethod); 91 } 92 env->DeleteLocalRef(methods); 93 } 94 95 env->DeleteLocalRef(aClass); 96 } 97 98 JavaClass::~JavaClass() 99 { 100 fastFree(const_cast<char*>(m_name)); 101 102 JSLock lock(SilenceAssertionsOnly); 103 104 deleteAllValues(m_fields); 105 m_fields.clear(); 106 107 MethodListMap::const_iterator end = m_methods.end(); 108 for (MethodListMap::const_iterator it = m_methods.begin(); it != end; ++it) { 109 const MethodList* methodList = it->second; 110 deleteAllValues(*methodList); 111 delete methodList; 112 } 113 m_methods.clear(); 114 } 115 116 MethodList JavaClass::methodsNamed(const Identifier& identifier, Instance*) const 117 { 118 MethodList* methodList = m_methods.get(identifier.ustring().rep()); 119 120 if (methodList) 121 return *methodList; 122 return MethodList(); 123 } 124 125 Field* JavaClass::fieldNamed(const Identifier& identifier, Instance*) const 126 { 127 return m_fields.get(identifier.ustring().rep()); 128 } 129 130 bool JavaClass::isNumberClass() const 131 { 132 return (!strcmp(m_name, "java.lang.Byte") 133 || !strcmp(m_name, "java.lang.Short") 134 || !strcmp(m_name, "java.lang.Integer") 135 || !strcmp(m_name, "java.lang.Long") 136 || !strcmp(m_name, "java.lang.Float") 137 || !strcmp(m_name, "java.lang.Double")); 138 } 139 140 bool JavaClass::isBooleanClass() const 141 { 142 return !strcmp(m_name, "java.lang.Boolean"); 143 } 144 145 bool JavaClass::isStringClass() const 146 { 147 return !strcmp(m_name, "java.lang.String"); 148 } 149 150 #endif // ENABLE(MAC_JAVA_BRIDGE) 151