initial import
[vuplus_webkit] / Source / JavaScriptCore / runtime / JSValue.cpp
1 /*
2  *  Copyright (C) 1999-2001 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2003, 2007, 2008 Apple Inc. All rights reserved.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public License
17  *  along with this library; see the file COPYING.LIB.  If not, write to
18  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #include "config.h"
24 #include "JSValue.h"
25
26 #include "BooleanConstructor.h"
27 #include "BooleanPrototype.h"
28 #include "Error.h"
29 #include "ExceptionHelpers.h"
30 #include "JSGlobalObject.h"
31 #include "JSFunction.h"
32 #include "JSNotAnObject.h"
33 #include "NumberObject.h"
34 #include <wtf/MathExtras.h>
35 #include <wtf/StringExtras.h>
36
37 namespace JSC {
38
39 static const double D32 = 4294967296.0;
40
41 // ECMA 9.4
42 double JSValue::toInteger(ExecState* exec) const
43 {
44     if (isInt32())
45         return asInt32();
46     double d = toNumber(exec);
47     return isnan(d) ? 0.0 : trunc(d);
48 }
49
50 double JSValue::toIntegerPreserveNaN(ExecState* exec) const
51 {
52     if (isInt32())
53         return asInt32();
54     return trunc(toNumber(exec));
55 }
56
57 double JSValue::toNumberSlowCase(ExecState* exec) const
58 {
59     ASSERT(!isInt32() && !isDouble());
60     if (isCell())
61         return asCell()->toNumber(exec);
62     if (isTrue())
63         return 1.0;
64     return isUndefined() ? std::numeric_limits<double>::quiet_NaN() : 0; // null and false both convert to 0.
65 }
66
67 JSObject* JSValue::toObjectSlowCase(ExecState* exec, JSGlobalObject* globalObject) const
68 {
69     ASSERT(!isCell());
70
71     if (isInt32() || isDouble())
72         return constructNumber(exec, globalObject, asValue());
73     if (isTrue() || isFalse())
74         return constructBooleanFromImmediateBoolean(exec, globalObject, asValue());
75
76     ASSERT(isUndefinedOrNull());
77     throwError(exec, createNotAnObjectError(exec, *this));
78     return JSNotAnObject::create(exec);
79 }
80
81 JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const
82 {
83     ASSERT(!isCell());
84
85     if (isInt32() || isDouble())
86         return constructNumber(exec, exec->lexicalGlobalObject(), asValue());
87     if (isTrue() || isFalse())
88         return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue());
89     ASSERT(isUndefinedOrNull());
90     return exec->globalThisValue();
91 }
92
93 JSObject* JSValue::synthesizeObject(ExecState* exec) const
94 {
95     ASSERT(!isCell());
96     if (isNumber())
97         return constructNumber(exec, exec->lexicalGlobalObject(), asValue());
98     if (isBoolean())
99         return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue());
100
101     ASSERT(isUndefinedOrNull());
102     throwError(exec, createNotAnObjectError(exec, *this));
103     return JSNotAnObject::create(exec);
104 }
105
106 JSObject* JSValue::synthesizePrototype(ExecState* exec) const
107 {
108     ASSERT(!isCell());
109     if (isNumber())
110         return exec->lexicalGlobalObject()->numberPrototype();
111     if (isBoolean())
112         return exec->lexicalGlobalObject()->booleanPrototype();
113
114     ASSERT(isUndefinedOrNull());
115     throwError(exec, createNotAnObjectError(exec, *this));
116     return JSNotAnObject::create(exec);
117 }
118
119 #ifndef NDEBUG
120 char* JSValue::description()
121 {
122     static const size_t size = 64;
123     static char description[size];
124
125     if (!*this)
126         snprintf(description, size, "<JSValue()>");
127     else if (isInt32())
128         snprintf(description, size, "Int32: %d", asInt32());
129     else if (isDouble()) {
130 #if USE(JSVALUE64)
131         snprintf(description, size, "Double: %lf, %lx", asDouble(), reinterpretDoubleToIntptr(asDouble()));
132 #else
133         union {
134             double asDouble;
135             uint32_t asTwoInt32s[2];
136         } u;
137         u.asDouble = asDouble();
138         snprintf(description, size, "Double: %lf, %08x:%08x", asDouble(), u.asTwoInt32s[1], u.asTwoInt32s[0]);
139 #endif
140     } else if (isCell())
141         snprintf(description, size, "Cell: %p", asCell());
142     else if (isTrue())
143         snprintf(description, size, "True");
144     else if (isFalse())
145         snprintf(description, size, "False");
146     else if (isNull())
147         snprintf(description, size, "Null");
148     else if (isUndefined())
149         snprintf(description, size, "Undefined");
150     else
151         snprintf(description, size, "INVALID");
152
153     return description;
154 }
155 #endif
156
157 // This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec.
158 // Note that this operation is identical to ToUInt32 other than to interpretation
159 // of the resulting bit-pattern (as such this metod is also called to implement
160 // ToUInt32).
161 //
162 // The operation can be descibed as round towards zero, then select the 32 least
163 // bits of the resulting value in 2s-complement representation.
164 int32_t toInt32(double number)
165 {
166     int64_t bits = WTF::bitwise_cast<int64_t>(number);
167     int32_t exp = (static_cast<int32_t>(bits >> 52) & 0x7ff) - 0x3ff;
168
169     // If exponent < 0 there will be no bits to the left of the decimal point
170     // after rounding; if the exponent is > 83 then no bits of precision can be
171     // left in the low 32-bit range of the result (IEEE-754 doubles have 52 bits
172     // of fractional precision).
173     // Note this case handles 0, -0, and all infinte, NaN, & denormal value. 
174     if (exp < 0 || exp > 83)
175         return 0;
176
177     // Select the appropriate 32-bits from the floating point mantissa.  If the
178     // exponent is 52 then the bits we need to select are already aligned to the
179     // lowest bits of the 64-bit integer representation of tghe number, no need
180     // to shift.  If the exponent is greater than 52 we need to shift the value
181     // left by (exp - 52), if the value is less than 52 we need to shift right
182     // accordingly.
183     int32_t result = (exp > 52)
184         ? static_cast<int32_t>(bits << (exp - 52))
185         : static_cast<int32_t>(bits >> (52 - exp));
186
187     // IEEE-754 double precision values are stored omitting an implicit 1 before
188     // the decimal point; we need to reinsert this now.  We may also the shifted
189     // invalid bits into the result that are not a part of the mantissa (the sign
190     // and exponent bits from the floatingpoint representation); mask these out.
191     if (exp < 32) {
192         int32_t missingOne = 1 << exp;
193         result &= missingOne - 1;
194         result += missingOne;
195     }
196
197     // If the input value was negative (we could test either 'number' or 'bits',
198     // but testing 'bits' is likely faster) invert the result appropriately.
199     return bits < 0 ? -result : result;
200 }
201
202 bool JSValue::isValidCallee()
203 {
204     return asObject(asCell())->globalObject();
205 }
206
207 } // namespace JSC