]> git.saurik.com Git - apple/javascriptcore.git/blob - API/JSValueRef.cpp
a12cc3409a2e10dd5ef6c8986fe187e6bdf8276a
[apple/javascriptcore.git] / 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 }