]>
git.saurik.com Git - apple/javascriptcore.git/blob - API/JSValueRef.cpp
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"
31 #include "JSCallbackObject.h"
33 #include <runtime/JSGlobalObject.h>
34 #include <runtime/JSONObject.h>
35 #include <runtime/JSString.h>
36 #include <runtime/LiteralParser.h>
37 #include <runtime/Operations.h>
38 #include <runtime/Protect.h>
39 #include <runtime/UString.h>
40 #include <runtime/JSValue.h>
42 #include <wtf/Assertions.h>
43 #include <wtf/text/StringHash.h>
45 #include <algorithm> // for std::min
49 :: JSType
JSValueGetType ( JSContextRef ctx
, JSValueRef value
)
51 ExecState
* exec
= toJS ( ctx
);
52 APIEntryShim
entryShim ( exec
);
54 JSValue jsValue
= toJS ( exec
, value
);
56 if ( jsValue
. isUndefined ())
57 return kJSTypeUndefined
;
60 if ( jsValue
. isBoolean ())
61 return kJSTypeBoolean
;
62 if ( jsValue
. isNumber ())
64 if ( jsValue
. isString ())
66 ASSERT ( jsValue
. isObject ());
70 bool JSValueIsUndefined ( JSContextRef ctx
, JSValueRef value
)
72 ExecState
* exec
= toJS ( ctx
);
73 APIEntryShim
entryShim ( exec
);
75 JSValue jsValue
= toJS ( exec
, value
);
76 return jsValue
. isUndefined ();
79 bool JSValueIsNull ( JSContextRef ctx
, JSValueRef value
)
81 ExecState
* exec
= toJS ( ctx
);
82 APIEntryShim
entryShim ( exec
);
84 JSValue jsValue
= toJS ( exec
, value
);
85 return jsValue
. isNull ();
88 bool JSValueIsBoolean ( JSContextRef ctx
, JSValueRef value
)
90 ExecState
* exec
= toJS ( ctx
);
91 APIEntryShim
entryShim ( exec
);
93 JSValue jsValue
= toJS ( exec
, value
);
94 return jsValue
. isBoolean ();
97 bool JSValueIsNumber ( JSContextRef ctx
, JSValueRef value
)
99 ExecState
* exec
= toJS ( ctx
);
100 APIEntryShim
entryShim ( exec
);
102 JSValue jsValue
= toJS ( exec
, value
);
103 return jsValue
. isNumber ();
106 bool JSValueIsString ( JSContextRef ctx
, JSValueRef value
)
108 ExecState
* exec
= toJS ( ctx
);
109 APIEntryShim
entryShim ( exec
);
111 JSValue jsValue
= toJS ( exec
, value
);
112 return jsValue
. isString ();
115 bool JSValueIsObject ( JSContextRef ctx
, JSValueRef value
)
117 ExecState
* exec
= toJS ( ctx
);
118 APIEntryShim
entryShim ( exec
);
120 JSValue jsValue
= toJS ( exec
, value
);
121 return jsValue
. isObject ();
124 bool JSValueIsObjectOfClass ( JSContextRef ctx
, JSValueRef value
, JSClassRef jsClass
)
126 ExecState
* exec
= toJS ( ctx
);
127 APIEntryShim
entryShim ( exec
);
129 JSValue jsValue
= toJS ( exec
, value
);
131 if ( JSObject
* o
= jsValue
. getObject ()) {
132 if ( o
-> inherits (& JSCallbackObject
< JSGlobalObject
>:: s_info
))
133 return jsCast
< JSCallbackObject
< JSGlobalObject
>*>( o
)-> inherits ( jsClass
);
134 if ( o
-> inherits (& JSCallbackObject
< JSNonFinalObject
>:: s_info
))
135 return jsCast
< JSCallbackObject
< JSNonFinalObject
>*>( o
)-> inherits ( jsClass
);
140 bool JSValueIsEqual ( JSContextRef ctx
, JSValueRef a
, JSValueRef b
, JSValueRef
* exception
)
142 ExecState
* exec
= toJS ( ctx
);
143 APIEntryShim
entryShim ( exec
);
145 JSValue jsA
= toJS ( exec
, a
);
146 JSValue jsB
= toJS ( exec
, b
);
148 bool result
= JSValue :: equal ( exec
, jsA
, jsB
); // false if an exception is thrown
149 if ( exec
-> hadException ()) {
151 * exception
= toRef ( exec
, exec
-> exception ());
152 exec
-> clearException ();
157 bool JSValueIsStrictEqual ( JSContextRef ctx
, JSValueRef a
, JSValueRef b
)
159 ExecState
* exec
= toJS ( ctx
);
160 APIEntryShim
entryShim ( exec
);
162 JSValue jsA
= toJS ( exec
, a
);
163 JSValue jsB
= toJS ( exec
, b
);
165 return JSValue :: strictEqual ( exec
, jsA
, jsB
);
168 bool JSValueIsInstanceOfConstructor ( JSContextRef ctx
, JSValueRef value
, JSObjectRef constructor
, JSValueRef
* exception
)
170 ExecState
* exec
= toJS ( ctx
);
171 APIEntryShim
entryShim ( exec
);
173 JSValue jsValue
= toJS ( exec
, value
);
175 JSObject
* jsConstructor
= toJS ( constructor
);
176 if (! jsConstructor
-> structure ()-> typeInfo (). implementsHasInstance ())
178 bool result
= jsConstructor
-> methodTable ()-> hasInstance ( jsConstructor
, exec
, jsValue
, jsConstructor
-> get ( exec
, exec
-> propertyNames (). prototype
)); // false if an exception is thrown
179 if ( exec
-> hadException ()) {
181 * exception
= toRef ( exec
, exec
-> exception ());
182 exec
-> clearException ();
187 JSValueRef
JSValueMakeUndefined ( JSContextRef ctx
)
189 ExecState
* exec
= toJS ( ctx
);
190 APIEntryShim
entryShim ( exec
);
192 return toRef ( exec
, jsUndefined ());
195 JSValueRef
JSValueMakeNull ( JSContextRef ctx
)
197 ExecState
* exec
= toJS ( ctx
);
198 APIEntryShim
entryShim ( exec
);
200 return toRef ( exec
, jsNull ());
203 JSValueRef
JSValueMakeBoolean ( JSContextRef ctx
, bool value
)
205 ExecState
* exec
= toJS ( ctx
);
206 APIEntryShim
entryShim ( exec
);
208 return toRef ( exec
, jsBoolean ( value
));
211 JSValueRef
JSValueMakeNumber ( JSContextRef ctx
, double value
)
213 ExecState
* exec
= toJS ( ctx
);
214 APIEntryShim
entryShim ( exec
);
216 // Our JSValue representation relies on a standard bit pattern for NaN. NaNs
217 // generated internally to JavaScriptCore naturally have that representation,
218 // but an external NaN might not.
220 value
= std :: numeric_limits
< double >:: quiet_NaN ();
222 return toRef ( exec
, jsNumber ( value
));
225 JSValueRef
JSValueMakeString ( JSContextRef ctx
, JSStringRef string
)
227 ExecState
* exec
= toJS ( ctx
);
228 APIEntryShim
entryShim ( exec
);
230 return toRef ( exec
, jsString ( exec
, string
-> ustring ()));
233 JSValueRef
JSValueMakeFromJSONString ( JSContextRef ctx
, JSStringRef string
)
235 ExecState
* exec
= toJS ( ctx
);
236 APIEntryShim
entryShim ( exec
);
237 UString str
= string
-> ustring ();
239 LiteralParser
< LChar
> parser ( exec
, str
. characters8 (), str
. length (), StrictJSON
);
240 return toRef ( exec
, parser
. tryLiteralParse ());
242 LiteralParser
< UChar
> parser ( exec
, str
. characters16 (), str
. length (), StrictJSON
);
243 return toRef ( exec
, parser
. tryLiteralParse ());
246 JSStringRef
JSValueCreateJSONString ( JSContextRef ctx
, JSValueRef apiValue
, unsigned indent
, JSValueRef
* exception
)
248 ExecState
* exec
= toJS ( ctx
);
249 APIEntryShim
entryShim ( exec
);
250 JSValue value
= toJS ( exec
, apiValue
);
251 UString result
= JSONStringify ( exec
, value
, indent
);
254 if ( exec
-> hadException ()) {
256 * exception
= toRef ( exec
, exec
-> exception ());
257 exec
-> clearException ();
260 return OpaqueJSString :: create ( result
). leakRef ();
263 bool JSValueToBoolean ( JSContextRef ctx
, JSValueRef value
)
265 ExecState
* exec
= toJS ( ctx
);
266 APIEntryShim
entryShim ( exec
);
268 JSValue jsValue
= toJS ( exec
, value
);
269 return jsValue
. toBoolean ( exec
);
272 double JSValueToNumber ( JSContextRef ctx
, JSValueRef value
, JSValueRef
* exception
)
274 ExecState
* exec
= toJS ( ctx
);
275 APIEntryShim
entryShim ( exec
);
277 JSValue jsValue
= toJS ( exec
, value
);
279 double number
= jsValue
. toNumber ( exec
);
280 if ( exec
-> hadException ()) {
282 * exception
= toRef ( exec
, exec
-> exception ());
283 exec
-> clearException ();
284 number
= std :: numeric_limits
< double >:: quiet_NaN ();
289 JSStringRef
JSValueToStringCopy ( JSContextRef ctx
, JSValueRef value
, JSValueRef
* exception
)
291 ExecState
* exec
= toJS ( ctx
);
292 APIEntryShim
entryShim ( exec
);
294 JSValue jsValue
= toJS ( exec
, value
);
296 RefPtr
< OpaqueJSString
> stringRef ( OpaqueJSString :: create ( jsValue
. toString ( exec
)-> value ( exec
)));
297 if ( exec
-> hadException ()) {
299 * exception
= toRef ( exec
, exec
-> exception ());
300 exec
-> clearException ();
303 return stringRef
. release (). leakRef ();
306 JSObjectRef
JSValueToObject ( JSContextRef ctx
, JSValueRef value
, JSValueRef
* exception
)
308 ExecState
* exec
= toJS ( ctx
);
309 APIEntryShim
entryShim ( exec
);
311 JSValue jsValue
= toJS ( exec
, value
);
313 JSObjectRef objectRef
= toRef ( jsValue
. toObject ( exec
));
314 if ( exec
-> hadException ()) {
316 * exception
= toRef ( exec
, exec
-> exception ());
317 exec
-> clearException ();
323 void JSValueProtect ( JSContextRef ctx
, JSValueRef value
)
325 ExecState
* exec
= toJS ( ctx
);
326 APIEntryShim
entryShim ( exec
);
328 JSValue jsValue
= toJSForGC ( exec
, value
);
332 void JSValueUnprotect ( JSContextRef ctx
, JSValueRef value
)
334 ExecState
* exec
= toJS ( ctx
);
335 APIEntryShim
entryShim ( exec
);
337 JSValue jsValue
= toJSForGC ( exec
, value
);
338 gcUnprotect ( jsValue
);