OSDN Git Service

Fix build break for emulator
[android-x86/external-webkit.git] / Source / WebCore / bridge / jni / JavaMethodJobject.cpp
1 /*
2  * Copyright (C) 2003, 2004, 2005, 2007, 2009 Apple Inc. All rights reserved.
3  * Copyright 2010, The Android Open Source Project
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #include "config.h"
28 #include "JavaMethodJobject.h"
29
30 #if ENABLE(JAVA_BRIDGE)
31
32 #include "JavaString.h"
33
34 #if USE(JSC)
35 #include <runtime/JSObject.h>
36 #include <runtime/ScopeChain.h>
37 #endif
38 #include <wtf/text/StringBuilder.h>
39
40 using namespace JSC;
41 using namespace JSC::Bindings;
42
43 JavaMethodJobject::JavaMethodJobject(JNIEnv* env, jobject aMethod)
44 {
45     // Get return type name
46     jstring returnTypeName = 0;
47     if (jobject returnType = callJNIMethod<jobject>(aMethod, "getReturnType", "()Ljava/lang/Class;")) {
48             returnTypeName = static_cast<jstring>(callJNIMethod<jobject>(returnType, "getName", "()Ljava/lang/String;"));
49         if (!returnTypeName)
50             returnTypeName = env->NewStringUTF("<Unknown>");
51         env->DeleteLocalRef(returnType);
52     }
53     m_returnTypeClassName = JavaString(env, returnTypeName);
54     m_returnType = javaTypeFromClassName(m_returnTypeClassName.utf8());
55     env->DeleteLocalRef(returnTypeName);
56
57     // Get method name
58     jstring methodName = static_cast<jstring>(callJNIMethod<jobject>(aMethod, "getName", "()Ljava/lang/String;"));
59     if (!methodName)
60         methodName = env->NewStringUTF("<Unknown>");
61     m_name = JavaString(env, methodName);
62     env->DeleteLocalRef(methodName);
63
64     // Get parameters
65     if (jarray jparameters = static_cast<jarray>(callJNIMethod<jobject>(aMethod, "getParameterTypes", "()[Ljava/lang/Class;"))) {
66         unsigned int numParams = env->GetArrayLength(jparameters);
67
68         for (unsigned int i = 0; i < numParams; i++) {
69             jobject aParameter = env->GetObjectArrayElement(static_cast<jobjectArray>(jparameters), i);
70             jstring parameterName = static_cast<jstring>(callJNIMethod<jobject>(aParameter, "getName", "()Ljava/lang/String;"));
71             if (!parameterName)
72                 parameterName = env->NewStringUTF("<Unknown>");
73             m_parameters.append(JavaString(env, parameterName).impl());
74             env->DeleteLocalRef(aParameter);
75             env->DeleteLocalRef(parameterName);
76         }
77         env->DeleteLocalRef(jparameters);
78     }
79
80     // Created lazily.
81     m_signature = 0;
82
83     jclass modifierClass = env->FindClass("java/lang/reflect/Modifier");
84     int modifiers = callJNIMethod<jint>(aMethod, "getModifiers", "()I");
85     m_isStatic = static_cast<bool>(callJNIStaticMethod<jboolean>(modifierClass, "isStatic", "(I)Z", modifiers));
86     env->DeleteLocalRef(modifierClass);
87 }
88
89 JavaMethodJobject::~JavaMethodJobject()
90 {
91     if (m_signature)
92         fastFree(m_signature);
93 }
94
95 // JNI method signatures use '/' between components of a class name, but
96 // we get '.' between components from the reflection API.
97 static void appendClassName(StringBuilder& builder, const char* className)
98 {
99 #if USE(JSC)
100     ASSERT(JSLock::lockCount() > 0);
101 #endif
102
103     char* c = fastStrDup(className);
104
105     char* result = c;
106     while (*c) {
107         if (*c == '.')
108             *c = '/';
109         c++;
110     }
111
112     builder.append(result);
113
114     fastFree(result);
115 }
116
117 const char* JavaMethodJobject::signature() const
118 {
119     if (!m_signature) {
120 #if USE(JSC)
121         JSLock lock(SilenceAssertionsOnly);
122 #endif
123
124         StringBuilder signatureBuilder;
125         signatureBuilder.append('(');
126         for (unsigned int i = 0; i < m_parameters.size(); i++) {
127             CString javaClassName = parameterAt(i).utf8();
128             JavaType type = javaTypeFromClassName(javaClassName.data());
129             if (type == JavaTypeArray)
130                 appendClassName(signatureBuilder, javaClassName.data());
131             else {
132                 signatureBuilder.append(signatureFromJavaType(type));
133 #if PLATFORM(ANDROID) && USE(V8)
134                 // FIXME: Upstream to WebKit
135                 // https://bugs.webkit.org/show_bug.cgi?id=62389
136                 if (type == JavaTypeObject || type == JavaTypeString) {
137 #else
138                 if (type == JavaTypeObject) {
139 #endif
140                     appendClassName(signatureBuilder, javaClassName.data());
141                     signatureBuilder.append(';');
142                 }
143             }
144         }
145         signatureBuilder.append(')');
146
147         const char* returnType = m_returnTypeClassName.utf8();
148         if (m_returnType == JavaTypeArray)
149             appendClassName(signatureBuilder, returnType);
150         else {
151             signatureBuilder.append(signatureFromJavaType(m_returnType));
152 #if PLATFORM(ANDROID) && USE(V8)
153             // FIXME: Upstream to WebKit
154             // https://bugs.webkit.org/show_bug.cgi?id=62389
155             if (m_returnType == JavaTypeObject || m_returnType == JavaTypeString) {
156 #else
157             if (m_returnType == JavaTypeObject) {
158 #endif
159                 appendClassName(signatureBuilder, returnType);
160                 signatureBuilder.append(';');
161             }
162         }
163
164         String signatureString = signatureBuilder.toString();
165         m_signature = fastStrDup(signatureString.utf8().data());
166     }
167
168     return m_signature;
169 }
170
171 #endif // ENABLE(JAVA_BRIDGE)