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