tizen beta release
[framework/web/webkit-efl.git] / Source / JavaScriptCore / runtime / JSValueInlineMethods.h
1 /*
2  * Copyright (C) 2011 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 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 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 #ifndef JSValueInlineMethods_h
27 #define JSValueInlineMethods_h
28
29 #include "JSValue.h"
30
31 namespace JSC {
32
33     ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
34     {
35         if (isInt32())
36             return asInt32();
37         return JSC::toInt32(toNumber(exec));
38     }
39
40     inline uint32_t JSValue::toUInt32(ExecState* exec) const
41     {
42         // See comment on JSC::toUInt32, above.
43         return toInt32(exec);
44     }
45
46     inline bool JSValue::isUInt32() const
47     {
48         return isInt32() && asInt32() >= 0;
49     }
50
51     inline uint32_t JSValue::asUInt32() const
52     {
53         ASSERT(isUInt32());
54         return asInt32();
55     }
56
57     inline double JSValue::asNumber() const
58     {
59         ASSERT(isNumber());
60         return isInt32() ? asInt32() : asDouble();
61     }
62
63     inline JSValue jsNaN()
64     {
65         return JSValue(std::numeric_limits<double>::quiet_NaN());
66     }
67
68     inline JSValue::JSValue(char i)
69     {
70         *this = JSValue(static_cast<int32_t>(i));
71     }
72
73     inline JSValue::JSValue(unsigned char i)
74     {
75         *this = JSValue(static_cast<int32_t>(i));
76     }
77
78     inline JSValue::JSValue(short i)
79     {
80         *this = JSValue(static_cast<int32_t>(i));
81     }
82
83     inline JSValue::JSValue(unsigned short i)
84     {
85         *this = JSValue(static_cast<int32_t>(i));
86     }
87
88     inline JSValue::JSValue(unsigned i)
89     {
90         if (static_cast<int32_t>(i) < 0) {
91             *this = JSValue(EncodeAsDouble, static_cast<double>(i));
92             return;
93         }
94         *this = JSValue(static_cast<int32_t>(i));
95     }
96
97     inline JSValue::JSValue(long i)
98     {
99         if (static_cast<int32_t>(i) != i) {
100             *this = JSValue(EncodeAsDouble, static_cast<double>(i));
101             return;
102         }
103         *this = JSValue(static_cast<int32_t>(i));
104     }
105
106     inline JSValue::JSValue(unsigned long i)
107     {
108         if (static_cast<uint32_t>(i) != i) {
109             *this = JSValue(EncodeAsDouble, static_cast<double>(i));
110             return;
111         }
112         *this = JSValue(static_cast<uint32_t>(i));
113     }
114
115     inline JSValue::JSValue(long long i)
116     {
117         if (static_cast<int32_t>(i) != i) {
118             *this = JSValue(EncodeAsDouble, static_cast<double>(i));
119             return;
120         }
121         *this = JSValue(static_cast<int32_t>(i));
122     }
123
124     inline JSValue::JSValue(unsigned long long i)
125     {
126         if (static_cast<uint32_t>(i) != i) {
127             *this = JSValue(EncodeAsDouble, static_cast<double>(i));
128             return;
129         }
130         *this = JSValue(static_cast<uint32_t>(i));
131     }
132
133     inline JSValue::JSValue(double d)
134     {
135         const int32_t asInt32 = static_cast<int32_t>(d);
136         if (asInt32 != d || (!asInt32 && signbit(d))) { // true for -0.0
137             *this = JSValue(EncodeAsDouble, d);
138             return;
139         }
140         *this = JSValue(static_cast<int32_t>(d));
141     }
142
143 #if USE(JSVALUE32_64)
144     inline EncodedJSValue JSValue::encode(JSValue value)
145     {
146         return value.u.asInt64;
147     }
148
149     inline JSValue JSValue::decode(EncodedJSValue encodedJSValue)
150     {
151         JSValue v;
152         v.u.asInt64 = encodedJSValue;
153         return v;
154     }
155
156     inline JSValue::JSValue()
157     {
158         u.asBits.tag = EmptyValueTag;
159         u.asBits.payload = 0;
160     }
161
162     inline JSValue::JSValue(JSNullTag)
163     {
164         u.asBits.tag = NullTag;
165         u.asBits.payload = 0;
166     }
167     
168     inline JSValue::JSValue(JSUndefinedTag)
169     {
170         u.asBits.tag = UndefinedTag;
171         u.asBits.payload = 0;
172     }
173     
174     inline JSValue::JSValue(JSTrueTag)
175     {
176         u.asBits.tag = BooleanTag;
177         u.asBits.payload = 1;
178     }
179     
180     inline JSValue::JSValue(JSFalseTag)
181     {
182         u.asBits.tag = BooleanTag;
183         u.asBits.payload = 0;
184     }
185
186     inline JSValue::JSValue(HashTableDeletedValueTag)
187     {
188         u.asBits.tag = DeletedValueTag;
189         u.asBits.payload = 0;
190     }
191
192     inline JSValue::JSValue(JSCell* ptr)
193     {
194         if (ptr)
195             u.asBits.tag = CellTag;
196         else
197             u.asBits.tag = EmptyValueTag;
198         u.asBits.payload = reinterpret_cast<int32_t>(ptr);
199     }
200
201     inline JSValue::JSValue(const JSCell* ptr)
202     {
203         if (ptr)
204             u.asBits.tag = CellTag;
205         else
206             u.asBits.tag = EmptyValueTag;
207         u.asBits.payload = reinterpret_cast<int32_t>(const_cast<JSCell*>(ptr));
208     }
209
210     inline JSValue::operator bool() const
211     {
212         ASSERT(tag() != DeletedValueTag);
213         return tag() != EmptyValueTag;
214     }
215
216     inline bool JSValue::operator==(const JSValue& other) const
217     {
218         return u.asInt64 == other.u.asInt64;
219     }
220
221     inline bool JSValue::operator!=(const JSValue& other) const
222     {
223         return u.asInt64 != other.u.asInt64;
224     }
225
226     inline bool JSValue::isEmpty() const
227     {
228         return tag() == EmptyValueTag;
229     }
230
231     inline bool JSValue::isUndefined() const
232     {
233         return tag() == UndefinedTag;
234     }
235
236     inline bool JSValue::isNull() const
237     {
238         return tag() == NullTag;
239     }
240
241     inline bool JSValue::isUndefinedOrNull() const
242     {
243         return isUndefined() || isNull();
244     }
245
246     inline bool JSValue::isCell() const
247     {
248         return tag() == CellTag;
249     }
250
251     inline bool JSValue::isInt32() const
252     {
253         return tag() == Int32Tag;
254     }
255
256     inline bool JSValue::isDouble() const
257     {
258         return tag() < LowestTag;
259     }
260
261     inline bool JSValue::isTrue() const
262     {
263         return tag() == BooleanTag && payload();
264     }
265
266     inline bool JSValue::isFalse() const
267     {
268         return tag() == BooleanTag && !payload();
269     }
270
271     inline uint32_t JSValue::tag() const
272     {
273         return u.asBits.tag;
274     }
275     
276     inline int32_t JSValue::payload() const
277     {
278         return u.asBits.payload;
279     }
280     
281     inline int32_t JSValue::asInt32() const
282     {
283         ASSERT(isInt32());
284         return u.asBits.payload;
285     }
286     
287     inline double JSValue::asDouble() const
288     {
289         ASSERT(isDouble());
290         return u.asDouble;
291     }
292     
293     ALWAYS_INLINE JSCell* JSValue::asCell() const
294     {
295         ASSERT(isCell());
296         return reinterpret_cast<JSCell*>(u.asBits.payload);
297     }
298
299     ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
300     {
301         u.asDouble = d;
302     }
303
304     inline JSValue::JSValue(int i)
305     {
306         u.asBits.tag = Int32Tag;
307         u.asBits.payload = i;
308     }
309
310     inline bool JSValue::isNumber() const
311     {
312         return isInt32() || isDouble();
313     }
314
315     inline bool JSValue::isBoolean() const
316     {
317         return isTrue() || isFalse();
318     }
319
320     inline bool JSValue::asBoolean() const
321     {
322         ASSERT(isBoolean());
323         return payload();
324     }
325
326 #else // USE(JSVALUE32_64)
327
328     // JSValue member functions.
329     inline EncodedJSValue JSValue::encode(JSValue value)
330     {
331         return value.u.ptr;
332     }
333
334     inline JSValue JSValue::decode(EncodedJSValue ptr)
335     {
336         return JSValue(reinterpret_cast<JSCell*>(ptr));
337     }
338
339     // 0x0 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x0, which is in the (invalid) zero page.
340     inline JSValue::JSValue()
341     {
342         u.asInt64 = ValueEmpty;
343     }
344
345     // 0x4 can never occur naturally because it has a tag of 00, indicating a pointer value, but a payload of 0x4, which is in the (invalid) zero page.
346     inline JSValue::JSValue(HashTableDeletedValueTag)
347     {
348         u.asInt64 = ValueDeleted;
349     }
350
351     inline JSValue::JSValue(JSCell* ptr)
352     {
353         u.ptr = ptr;
354     }
355
356     inline JSValue::JSValue(const JSCell* ptr)
357     {
358         u.ptr = const_cast<JSCell*>(ptr);
359     }
360
361     inline JSValue::operator bool() const
362     {
363         return u.ptr;
364     }
365
366     inline bool JSValue::operator==(const JSValue& other) const
367     {
368         return u.ptr == other.u.ptr;
369     }
370
371     inline bool JSValue::operator!=(const JSValue& other) const
372     {
373         return u.ptr != other.u.ptr;
374     }
375
376     inline bool JSValue::isEmpty() const
377     {
378         return u.asInt64 == ValueEmpty;
379     }
380
381     inline bool JSValue::isUndefined() const
382     {
383         return asValue() == JSValue(JSUndefined);
384     }
385
386     inline bool JSValue::isNull() const
387     {
388         return asValue() == JSValue(JSNull);
389     }
390
391     inline bool JSValue::isTrue() const
392     {
393         return asValue() == JSValue(JSTrue);
394     }
395
396     inline bool JSValue::isFalse() const
397     {
398         return asValue() == JSValue(JSFalse);
399     }
400
401     inline bool JSValue::asBoolean() const
402     {
403         ASSERT(isBoolean());
404         return asValue() == JSValue(JSTrue);
405     }
406
407     inline int32_t JSValue::asInt32() const
408     {
409         ASSERT(isInt32());
410         return static_cast<int32_t>(u.asInt64);
411     }
412
413     inline bool JSValue::isDouble() const
414     {
415         return isNumber() && !isInt32();
416     }
417
418     inline JSValue::JSValue(JSNullTag)
419     {
420         u.asInt64 = ValueNull;
421     }
422     
423     inline JSValue::JSValue(JSUndefinedTag)
424     {
425         u.asInt64 = ValueUndefined;
426     }
427
428     inline JSValue::JSValue(JSTrueTag)
429     {
430         u.asInt64 = ValueTrue;
431     }
432
433     inline JSValue::JSValue(JSFalseTag)
434     {
435         u.asInt64 = ValueFalse;
436     }
437
438     inline bool JSValue::isUndefinedOrNull() const
439     {
440         // Undefined and null share the same value, bar the 'undefined' bit in the extended tag.
441         return (u.asInt64 & ~TagBitUndefined) == ValueNull;
442     }
443
444     inline bool JSValue::isBoolean() const
445     {
446         return (u.asInt64 & ~1) == ValueFalse;
447     }
448
449     inline bool JSValue::isCell() const
450     {
451         return !(u.asInt64 & TagMask);
452     }
453
454     inline bool JSValue::isInt32() const
455     {
456         return (u.asInt64 & TagTypeNumber) == TagTypeNumber;
457     }
458
459     inline intptr_t reinterpretDoubleToIntptr(double value)
460     {
461         return bitwise_cast<intptr_t>(value);
462     }
463     inline double reinterpretIntptrToDouble(intptr_t value)
464     {
465         return bitwise_cast<double>(value);
466     }
467
468     ALWAYS_INLINE JSValue::JSValue(EncodeAsDoubleTag, double d)
469     {
470         u.asInt64 = reinterpretDoubleToIntptr(d) + DoubleEncodeOffset;
471     }
472
473     inline JSValue::JSValue(int i)
474     {
475         u.asInt64 = TagTypeNumber | static_cast<uint32_t>(i);
476     }
477
478     inline double JSValue::asDouble() const
479     {
480         return reinterpretIntptrToDouble(u.asInt64 - DoubleEncodeOffset);
481     }
482
483     inline bool JSValue::isNumber() const
484     {
485         return u.asInt64 & TagTypeNumber;
486     }
487
488     ALWAYS_INLINE JSCell* JSValue::asCell() const
489     {
490         ASSERT(isCell());
491         return u.ptr;
492     }
493
494 #endif // USE(JSVALUE64)
495
496 } // namespace JSC
497
498 #endif // JSValueInlineMethods_h