2 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "JSValueRef.h"
29 #include <wtf/Platform.h>
32 #include "JSCallbackObject.h"
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>
41 #include <wtf/Assertions.h>
43 #include <algorithm> // for std::min
47 ::JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
49 ExecState* exec = toJS(ctx);
50 APIEntryShim entryShim(exec);
52 JSValue jsValue = toJS(exec, value);
54 if (jsValue.isUndefined())
55 return kJSTypeUndefined;
58 if (jsValue.isBoolean())
59 return kJSTypeBoolean;
60 if (jsValue.isNumber())
62 if (jsValue.isString())
64 ASSERT(jsValue.isObject());
68 bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
70 ExecState* exec = toJS(ctx);
71 APIEntryShim entryShim(exec);
73 JSValue jsValue = toJS(exec, value);
74 return jsValue.isUndefined();
77 bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
79 ExecState* exec = toJS(ctx);
80 APIEntryShim entryShim(exec);
82 JSValue jsValue = toJS(exec, value);
83 return jsValue.isNull();
86 bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
88 ExecState* exec = toJS(ctx);
89 APIEntryShim entryShim(exec);
91 JSValue jsValue = toJS(exec, value);
92 return jsValue.isBoolean();
95 bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
97 ExecState* exec = toJS(ctx);
98 APIEntryShim entryShim(exec);
100 JSValue jsValue = toJS(exec, value);
101 return jsValue.isNumber();
104 bool JSValueIsString(JSContextRef ctx, JSValueRef value)
106 ExecState* exec = toJS(ctx);
107 APIEntryShim entryShim(exec);
109 JSValue jsValue = toJS(exec, value);
110 return jsValue.isString();
113 bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
115 ExecState* exec = toJS(ctx);
116 APIEntryShim entryShim(exec);
118 JSValue jsValue = toJS(exec, value);
119 return jsValue.isObject();
122 bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
124 ExecState* exec = toJS(ctx);
125 APIEntryShim entryShim(exec);
127 JSValue jsValue = toJS(exec, value);
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);
138 bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception)
140 ExecState* exec = toJS(ctx);
141 APIEntryShim entryShim(exec);
143 JSValue jsA = toJS(exec, a);
144 JSValue jsB = toJS(exec, b);
146 bool result = JSValue::equal(exec, jsA, jsB); // false if an exception is thrown
147 if (exec->hadException()) {
149 *exception = toRef(exec, exec->exception());
150 exec->clearException();
155 bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
157 ExecState* exec = toJS(ctx);
158 APIEntryShim entryShim(exec);
160 JSValue jsA = toJS(exec, a);
161 JSValue jsB = toJS(exec, b);
163 return JSValue::strictEqual(exec, jsA, jsB);
166 bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
168 ExecState* exec = toJS(ctx);
169 APIEntryShim entryShim(exec);
171 JSValue jsValue = toJS(exec, value);
173 JSObject* jsConstructor = toJS(constructor);
174 if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
176 bool result = jsConstructor->hasInstance(exec, jsValue, jsConstructor->get(exec, exec->propertyNames().prototype)); // false if an exception is thrown
177 if (exec->hadException()) {
179 *exception = toRef(exec, exec->exception());
180 exec->clearException();
185 JSValueRef JSValueMakeUndefined(JSContextRef ctx)
187 ExecState* exec = toJS(ctx);
188 APIEntryShim entryShim(exec);
190 return toRef(exec, jsUndefined());
193 JSValueRef JSValueMakeNull(JSContextRef ctx)
195 ExecState* exec = toJS(ctx);
196 APIEntryShim entryShim(exec);
198 return toRef(exec, jsNull());
201 JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
203 ExecState* exec = toJS(ctx);
204 APIEntryShim entryShim(exec);
206 return toRef(exec, jsBoolean(value));
209 JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
211 ExecState* exec = toJS(ctx);
212 APIEntryShim entryShim(exec);
214 return toRef(exec, jsNumber(exec, value));
217 JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
219 ExecState* exec = toJS(ctx);
220 APIEntryShim entryShim(exec);
222 return toRef(exec, jsString(exec, string->ustring()));
225 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
227 ExecState* exec = toJS(ctx);
228 APIEntryShim entryShim(exec);
230 JSValue jsValue = toJS(exec, value);
231 return jsValue.toBoolean(exec);
234 double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
236 ExecState* exec = toJS(ctx);
237 APIEntryShim entryShim(exec);
239 JSValue jsValue = toJS(exec, value);
241 double number = jsValue.toNumber(exec);
242 if (exec->hadException()) {
244 *exception = toRef(exec, exec->exception());
245 exec->clearException();
251 JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
253 ExecState* exec = toJS(ctx);
254 APIEntryShim entryShim(exec);
256 JSValue jsValue = toJS(exec, value);
258 RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)));
259 if (exec->hadException()) {
261 *exception = toRef(exec, exec->exception());
262 exec->clearException();
265 return stringRef.release().releaseRef();
268 JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
270 ExecState* exec = toJS(ctx);
271 APIEntryShim entryShim(exec);
273 JSValue jsValue = toJS(exec, value);
275 JSObjectRef objectRef = toRef(jsValue.toObject(exec));
276 if (exec->hadException()) {
278 *exception = toRef(exec, exec->exception());
279 exec->clearException();
285 void JSValueProtect(JSContextRef ctx, JSValueRef value)
287 ExecState* exec = toJS(ctx);
288 APIEntryShim entryShim(exec);
290 JSValue jsValue = toJSForGC(exec, value);
294 void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
296 ExecState* exec = toJS(ctx);
297 APIEntryShim entryShim(exec);
299 JSValue jsValue = toJSForGC(exec, value);
300 gcUnprotect(jsValue);