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