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
JavaClass(jobject anInstance)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
~JavaClass()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
methodsNamed(const Identifier & identifier,Instance *) const116 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
fieldNamed(const Identifier & identifier,Instance *) const125 Field* JavaClass::fieldNamed(const Identifier& identifier, Instance*) const
126 {
127 return m_fields.get(identifier.ustring().rep());
128 }
129
isNumberClass() const130 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
isBooleanClass() const140 bool JavaClass::isBooleanClass() const
141 {
142 return !strcmp(m_name, "java.lang.Boolean");
143 }
144
isStringClass() const145 bool JavaClass::isStringClass() const
146 {
147 return !strcmp(m_name, "java.lang.String");
148 }
149
150 #endif // ENABLE(MAC_JAVA_BRIDGE)
151