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
45using namespace JSC;
46
47::JSType JSValueGetType(JSContextRef ctx, JSValueRef value)
48{
49 ExecState* exec = toJS(c: ctx);
50 APIEntryShim entryShim(exec);
51
52 JSValue jsValue = toJS(exec, v: 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
68bool JSValueIsUndefined(JSContextRef ctx, JSValueRef value)
69{
70 ExecState* exec = toJS(c: ctx);
71 APIEntryShim entryShim(exec);
72
73 JSValue jsValue = toJS(exec, v: value);
74 return jsValue.isUndefined();
75}
76
77bool JSValueIsNull(JSContextRef ctx, JSValueRef value)
78{
79 ExecState* exec = toJS(c: ctx);
80 APIEntryShim entryShim(exec);
81
82 JSValue jsValue = toJS(exec, v: value);
83 return jsValue.isNull();
84}
85
86bool JSValueIsBoolean(JSContextRef ctx, JSValueRef value)
87{
88 ExecState* exec = toJS(c: ctx);
89 APIEntryShim entryShim(exec);
90
91 JSValue jsValue = toJS(exec, v: value);
92 return jsValue.isBoolean();
93}
94
95bool JSValueIsNumber(JSContextRef ctx, JSValueRef value)
96{
97 ExecState* exec = toJS(c: ctx);
98 APIEntryShim entryShim(exec);
99
100 JSValue jsValue = toJS(exec, v: value);
101 return jsValue.isNumber();
102}
103
104bool JSValueIsString(JSContextRef ctx, JSValueRef value)
105{
106 ExecState* exec = toJS(c: ctx);
107 APIEntryShim entryShim(exec);
108
109 JSValue jsValue = toJS(exec, v: value);
110 return jsValue.isString();
111}
112
113bool JSValueIsObject(JSContextRef ctx, JSValueRef value)
114{
115 ExecState* exec = toJS(c: ctx);
116 APIEntryShim entryShim(exec);
117
118 JSValue jsValue = toJS(exec, v: value);
119 return jsValue.isObject();
120}
121
122bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
123{
124 ExecState* exec = toJS(c: ctx);
125 APIEntryShim entryShim(exec);
126
127 JSValue jsValue = toJS(exec, v: value);
128
129 if (JSObject* o = jsValue.getObject()) {
130 if (o->inherits(info: &JSCallbackObject<JSGlobalObject>::info))
131 return static_cast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(c: jsClass);
132 else if (o->inherits(info: &JSCallbackObject<JSObject>::info))
133 return static_cast<JSCallbackObject<JSObject>*>(o)->inherits(c: jsClass);
134 }
135 return false;
136}
137
138bool JSValueIsEqual(JSContextRef ctx, JSValueRef a, JSValueRef b, JSValueRef* exception)
139{
140 ExecState* exec = toJS(c: ctx);
141 APIEntryShim entryShim(exec);
142
143 JSValue jsA = toJS(exec, v: a);
144 JSValue jsB = toJS(exec, v: b);
145
146 bool result = JSValue::equal(exec, v1: jsA, v2: jsB); // false if an exception is thrown
147 if (exec->hadException()) {
148 if (exception)
149 *exception = toRef(exec, v: exec->exception());
150 exec->clearException();
151 }
152 return result;
153}
154
155bool JSValueIsStrictEqual(JSContextRef ctx, JSValueRef a, JSValueRef b)
156{
157 ExecState* exec = toJS(c: ctx);
158 APIEntryShim entryShim(exec);
159
160 JSValue jsA = toJS(exec, v: a);
161 JSValue jsB = toJS(exec, v: b);
162
163 return JSValue::strictEqual(exec, v1: jsA, v2: jsB);
164}
165
166bool JSValueIsInstanceOfConstructor(JSContextRef ctx, JSValueRef value, JSObjectRef constructor, JSValueRef* exception)
167{
168 ExecState* exec = toJS(c: ctx);
169 APIEntryShim entryShim(exec);
170
171 JSValue jsValue = toJS(exec, v: value);
172
173 JSObject* jsConstructor = toJS(o: constructor);
174 if (!jsConstructor->structure()->typeInfo().implementsHasInstance())
175 return false;
176 bool result = jsConstructor->hasInstance(exec, jsValue, prototypeProperty: jsConstructor->get(exec, propertyName: exec->propertyNames().prototype)); // false if an exception is thrown
177 if (exec->hadException()) {
178 if (exception)
179 *exception = toRef(exec, v: exec->exception());
180 exec->clearException();
181 }
182 return result;
183}
184
185JSValueRef JSValueMakeUndefined(JSContextRef ctx)
186{
187 ExecState* exec = toJS(c: ctx);
188 APIEntryShim entryShim(exec);
189
190 return toRef(exec, v: jsUndefined());
191}
192
193JSValueRef JSValueMakeNull(JSContextRef ctx)
194{
195 ExecState* exec = toJS(c: ctx);
196 APIEntryShim entryShim(exec);
197
198 return toRef(exec, v: jsNull());
199}
200
201JSValueRef JSValueMakeBoolean(JSContextRef ctx, bool value)
202{
203 ExecState* exec = toJS(c: ctx);
204 APIEntryShim entryShim(exec);
205
206 return toRef(exec, v: jsBoolean(b: value));
207}
208
209JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
210{
211 ExecState* exec = toJS(c: ctx);
212 APIEntryShim entryShim(exec);
213
214 return toRef(exec, v: jsNumber(exec, d: value));
215}
216
217JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
218{
219 ExecState* exec = toJS(c: ctx);
220 APIEntryShim entryShim(exec);
221
222 return toRef(exec, v: jsString(exec, s: string->ustring()));
223}
224
225bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
226{
227 ExecState* exec = toJS(c: ctx);
228 APIEntryShim entryShim(exec);
229
230 JSValue jsValue = toJS(exec, v: value);
231 return jsValue.toBoolean(exec);
232}
233
234double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
235{
236 ExecState* exec = toJS(c: ctx);
237 APIEntryShim entryShim(exec);
238
239 JSValue jsValue = toJS(exec, v: value);
240
241 double number = jsValue.toNumber(exec);
242 if (exec->hadException()) {
243 if (exception)
244 *exception = toRef(exec, v: exec->exception());
245 exec->clearException();
246 number = NaN;
247 }
248 return number;
249}
250
251JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
252{
253 ExecState* exec = toJS(c: ctx);
254 APIEntryShim entryShim(exec);
255
256 JSValue jsValue = toJS(exec, v: value);
257
258 RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)));
259 if (exec->hadException()) {
260 if (exception)
261 *exception = toRef(exec, v: exec->exception());
262 exec->clearException();
263 stringRef.clear();
264 }
265 return stringRef.release().releaseRef();
266}
267
268JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
269{
270 ExecState* exec = toJS(c: ctx);
271 APIEntryShim entryShim(exec);
272
273 JSValue jsValue = toJS(exec, v: value);
274
275 JSObjectRef objectRef = toRef(o: jsValue.toObject(exec));
276 if (exec->hadException()) {
277 if (exception)
278 *exception = toRef(exec, v: exec->exception());
279 exec->clearException();
280 objectRef = 0;
281 }
282 return objectRef;
283}
284
285void JSValueProtect(JSContextRef ctx, JSValueRef value)
286{
287 ExecState* exec = toJS(c: ctx);
288 APIEntryShim entryShim(exec);
289
290 JSValue jsValue = toJSForGC(exec, v: value);
291 gcProtect(value: jsValue);
292}
293
294void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
295{
296 ExecState* exec = toJS(c: ctx);
297 APIEntryShim entryShim(exec);
298
299 JSValue jsValue = toJSForGC(exec, v: value);
300 gcUnprotect(value: jsValue);
301}
302

source code of qtscript/src/3rdparty/javascriptcore/JavaScriptCore/API/JSValueRef.cpp