OSDN Git Service

am 70a336f2: am da8d052d: Merge "adding logging to determine the delay between event...
[android-x86/external-webkit.git] / JavaScriptCore / API / JSValueRef.cpp
1 /*
2  * Copyright (C) 2006, 2007 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 "JSValueRef.h"
28
29 #include <wtf/Platform.h>
30 #include "APICast.h"
31 #include "APIShims.h"
32 #include "JSCallbackObject.h"
33
34 #include <runtime/JSGlobalObject.h>
35 #include <runtime/JSString.h>
36 #include <runtime/Operations.h>
37 #include <runtime/Protect.h>
38 #include <runtime/UString.h>
39 #include <runtime/JSValue.h>
40
41 #include <wtf/Assertions.h>
42
43 #include <algorithm> // for std::min
44
45 using namespace JSC;
46
47 ::JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
48 {
49     ExecState* exec = toJS(ctx);
50     APIEntryShim entryShim(exec);
51
52     JSValue jsValue = toJS(exec, value);
53
54     if (jsValue.isUndefined())
55         return kJSTypeUndefined;
56     if (jsValue.isNull())
57         return kJSTypeNull;
58     if (jsValue.isBoolean())
59         return kJSTypeBoolean;
60     if (jsValue.isNumber())
61         return kJSTypeNumber;
62     if (jsValue.isString())
63         return kJSTypeString;
64     ASSERT(jsValue.isObject());
65     return kJSTypeObject;
66 }
67
68 bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
69 {
70     ExecState* exec = toJS(ctx);
71     APIEntryShim entryShim(exec);
72
73     JSValue jsValue = toJS(exec, value);
74     return jsValue.isUndefined();
75 }
76
77 bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
78 {
79     ExecState* exec = toJS(ctx);
80     APIEntryShim entryShim(exec);
81
82     JSValue jsValue = toJS(exec, value);
83     return jsValue.isNull();
84 }
85
86 bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
87 {
88     ExecState* exec = toJS(ctx);
89     APIEntryShim entryShim(exec);
90
91     JSValue jsValue = toJS(exec, value);
92     return jsValue.isBoolean();
93 }
94
95 bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
96 {
97     ExecState* exec = toJS(ctx);
98     APIEntryShim entryShim(exec);
99
100     JSValue jsValue = toJS(exec, value);
101     return jsValue.isNumber();
102 }
103
104 bool JSValueIsString(JSContextRef ctx, JSValueRef value)
105 {
106     ExecState* exec = toJS(ctx);
107     APIEntryShim entryShim(exec);
108
109     JSValue jsValue = toJS(exec, value);
110     return jsValue.isString();
111 }
112
113 bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
114 {
115     ExecState* exec = toJS(ctx);
116     APIEntryShim entryShim(exec);
117
118     JSValue jsValue = toJS(exec, value);
119     return jsValue.isObject();
120 }
121
122 bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
123 {
124     ExecState* exec = toJS(ctx);
125     APIEntryShim entryShim(exec);
126
127     JSValue jsValue = toJS(exec, value);
128     
129     if (JSObject* o = jsValue.getObject()) {
130         if (o->inherits(&JSCallbackObject<JSGlobalObject>::info))
131             return static_cast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
132         else if (o->inherits(&JSCallbackObject<JSObject>::info))
133             return static_cast<JSCallbackObject<JSObject>*>(o)->inherits(jsClass);
134     }
135     return false;
136 }
137
138 bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception)
139 {
140     ExecState* exec = toJS(ctx);
141     APIEntryShim entryShim(exec);
142
143     JSValue jsA = toJS(exec, a);
144     JSValue jsB = toJS(exec, b);
145
146     bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown
147     if (exec->hadException()) {
148         if (exception)
149             *exception = toRef(exec, exec->exception());
150         exec->clearException();
151     }
152     return result;
153 }
154
155 bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
156 {
157     ExecState* exec = toJS(ctx);
158     APIEntryShim entryShim(exec);
159
160     JSValue jsA = toJS(exec, a);
161     JSValue jsB = toJS(exec, b);
162
163     return JSValue::strictEqual(exec, jsA, jsB);
164 }
165
166 bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
167 {
168     ExecState* exec = toJS(ctx);
169     APIEntryShim entryShim(exec);
170
171     JSValue jsValue = toJS(exec, value);
172
173     JSObject* jsConstructor = toJS(constructor);
174     if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
175         return false;
176     bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
177     if (exec->hadException()) {
178         if (exception)
179             *exception = toRef(exec, exec->exception());
180         exec->clearException();
181     }
182     return result;
183 }
184
185 JSValueRef JSValueMakeUndefined(JSContextRef ctx)
186 {
187     ExecState* exec = toJS(ctx);
188     APIEntryShim entryShim(exec);
189
190     return toRef(exec, jsUndefined());
191 }
192
193 JSValueRef JSValueMakeNull(JSContextRef ctx)
194 {
195     ExecState* exec = toJS(ctx);
196     APIEntryShim entryShim(exec);
197
198     return toRef(exec, jsNull());
199 }
200
201 JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
202 {
203     ExecState* exec = toJS(ctx);
204     APIEntryShim entryShim(exec);
205
206     return toRef(exec, jsBoolean(value));
207 }
208
209 JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
210 {
211     ExecState* exec = toJS(ctx);
212     APIEntryShim entryShim(exec);
213
214     return toRef(exec, jsNumber(exec, value));
215 }
216
217 JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
218 {
219     ExecState* exec = toJS(ctx);
220     APIEntryShim entryShim(exec);
221
222     return toRef(exec, jsString(exec, string->ustring()));
223 }
224
225 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
226 {
227     ExecState* exec = toJS(ctx);
228     APIEntryShim entryShim(exec);
229
230     JSValue jsValue = toJS(exec, value);
231     return jsValue.toBoolean(exec);
232 }
233
234 double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
235 {
236     ExecState* exec = toJS(ctx);
237     APIEntryShim entryShim(exec);
238
239     JSValue jsValue = toJS(exec, value);
240
241     double number = jsValue.toNumber(exec);
242     if (exec->hadException()) {
243         if (exception)
244             *exception = toRef(exec, exec->exception());
245         exec->clearException();
246         number = NaN;
247     }
248     return number;
249 }
250
251 JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
252 {
253     ExecState* exec = toJS(ctx);
254     APIEntryShim entryShim(exec);
255
256     JSValue jsValue = toJS(exec, value);
257     
258     RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)));
259     if (exec->hadException()) {
260         if (exception)
261             *exception = toRef(exec, exec->exception());
262         exec->clearException();
263         stringRef.clear();
264     }
265     return stringRef.release().releaseRef();
266 }
267
268 JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
269 {
270     ExecState* exec = toJS(ctx);
271     APIEntryShim entryShim(exec);
272
273     JSValue jsValue = toJS(exec, value);
274     
275     JSObjectRef objectRef = toRef(jsValue.toObject(exec));
276     if (exec->hadException()) {
277         if (exception)
278             *exception = toRef(exec, exec->exception());
279         exec->clearException();
280         objectRef = 0;
281     }
282     return objectRef;
283 }    
284
285 void JSValueProtect(JSContextRef ctx, JSValueRef value)
286 {
287     ExecState* exec = toJS(ctx);
288     APIEntryShim entryShim(exec);
289
290     JSValue jsValue = toJSForGC(exec, value);
291     gcProtect(jsValue);
292 }
293
294 void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
295 {
296     ExecState* exec = toJS(ctx);
297     APIEntryShim entryShim(exec);
298
299     JSValue jsValue = toJSForGC(exec, value);
300     gcUnprotect(jsValue);
301 }