• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
JSValueGetType(JSContextRef ctx,JSValueRef value)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 
JSValueIsUndefined(JSContextRef ctx,JSValueRef value)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 
JSValueIsNull(JSContextRef ctx,JSValueRef value)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 
JSValueIsBoolean(JSContextRef ctx,JSValueRef value)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 
JSValueIsNumber(JSContextRef ctx,JSValueRef value)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 
JSValueIsString(JSContextRef ctx,JSValueRef value)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 
JSValueIsObject(JSContextRef ctx,JSValueRef value)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 
JSValueIsObjectOfClass(JSContextRef ctx,JSValueRef value,JSClassRef jsClass)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 
JSValueIsEqual(JSContextRef ctx,JSValueRef a,JSValueRef b,JSValueRef * exception)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 
JSValueIsStrictEqual(JSContextRef ctx,JSValueRef a,JSValueRef b)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 
JSValueIsInstanceOfConstructor(JSContextRef ctx,JSValueRef value,JSObjectRef constructor,JSValueRef * exception)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 
JSValueMakeUndefined(JSContextRef ctx)185 JSValueRef JSValueMakeUndefined(JSContextRef ctx)
186 {
187     ExecState* exec = toJS(ctx);
188     APIEntryShim entryShim(exec);
189 
190     return toRef(exec, jsUndefined());
191 }
192 
JSValueMakeNull(JSContextRef ctx)193 JSValueRef JSValueMakeNull(JSContextRef ctx)
194 {
195     ExecState* exec = toJS(ctx);
196     APIEntryShim entryShim(exec);
197 
198     return toRef(exec, jsNull());
199 }
200 
JSValueMakeBoolean(JSContextRef ctx,bool value)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 
JSValueMakeNumber(JSContextRef ctx,double value)209 JSValueRef JSValueMakeNumber(JSContextRef ctx, double value)
210 {
211     ExecState* exec = toJS(ctx);
212     APIEntryShim entryShim(exec);
213 
214     // Our JSValue representation relies on a standard bit pattern for NaN. NaNs
215     // generated internally to JavaScriptCore naturally have that representation,
216     // but an external NaN might not.
217     if (isnan(value))
218         value = NaN;
219 
220     return toRef(exec, jsNumber(exec, value));
221 }
222 
JSValueMakeString(JSContextRef ctx,JSStringRef string)223 JSValueRef JSValueMakeString(JSContextRef ctx, JSStringRef string)
224 {
225     ExecState* exec = toJS(ctx);
226     APIEntryShim entryShim(exec);
227 
228     return toRef(exec, jsString(exec, string->ustring()));
229 }
230 
JSValueToBoolean(JSContextRef ctx,JSValueRef value)231 bool JSValueToBoolean(JSContextRef ctx, JSValueRef value)
232 {
233     ExecState* exec = toJS(ctx);
234     APIEntryShim entryShim(exec);
235 
236     JSValue jsValue = toJS(exec, value);
237     return jsValue.toBoolean(exec);
238 }
239 
JSValueToNumber(JSContextRef ctx,JSValueRef value,JSValueRef * exception)240 double JSValueToNumber(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
241 {
242     ExecState* exec = toJS(ctx);
243     APIEntryShim entryShim(exec);
244 
245     JSValue jsValue = toJS(exec, value);
246 
247     double number = jsValue.toNumber(exec);
248     if (exec->hadException()) {
249         if (exception)
250             *exception = toRef(exec, exec->exception());
251         exec->clearException();
252         number = NaN;
253     }
254     return number;
255 }
256 
JSValueToStringCopy(JSContextRef ctx,JSValueRef value,JSValueRef * exception)257 JSStringRef JSValueToStringCopy(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
258 {
259     ExecState* exec = toJS(ctx);
260     APIEntryShim entryShim(exec);
261 
262     JSValue jsValue = toJS(exec, value);
263 
264     RefPtr<OpaqueJSString> stringRef(OpaqueJSString::create(jsValue.toString(exec)));
265     if (exec->hadException()) {
266         if (exception)
267             *exception = toRef(exec, exec->exception());
268         exec->clearException();
269         stringRef.clear();
270     }
271     return stringRef.release().releaseRef();
272 }
273 
JSValueToObject(JSContextRef ctx,JSValueRef value,JSValueRef * exception)274 JSObjectRef JSValueToObject(JSContextRef ctx, JSValueRef value, JSValueRef* exception)
275 {
276     ExecState* exec = toJS(ctx);
277     APIEntryShim entryShim(exec);
278 
279     JSValue jsValue = toJS(exec, value);
280 
281     JSObjectRef objectRef = toRef(jsValue.toObject(exec));
282     if (exec->hadException()) {
283         if (exception)
284             *exception = toRef(exec, exec->exception());
285         exec->clearException();
286         objectRef = 0;
287     }
288     return objectRef;
289 }
290 
JSValueProtect(JSContextRef ctx,JSValueRef value)291 void JSValueProtect(JSContextRef ctx, JSValueRef value)
292 {
293     ExecState* exec = toJS(ctx);
294     APIEntryShim entryShim(exec);
295 
296     JSValue jsValue = toJSForGC(exec, value);
297     gcProtect(jsValue);
298 }
299 
JSValueUnprotect(JSContextRef ctx,JSValueRef value)300 void JSValueUnprotect(JSContextRef ctx, JSValueRef value)
301 {
302     ExecState* exec = toJS(ctx);
303     APIEntryShim entryShim(exec);
304 
305     JSValue jsValue = toJSForGC(exec, value);
306     gcUnprotect(jsValue);
307 }
308