• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
toInteger(ExecState * exec) const42 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 
toIntegerPreserveNaN(ExecState * exec) const50 double JSValue::toIntegerPreserveNaN(ExecState* exec) const
51 {
52     if (isInt32())
53         return asInt32();
54     return trunc(toNumber(exec));
55 }
56 
toObjectSlowCase(ExecState * exec,JSGlobalObject * globalObject) const57 JSObject* JSValue::toObjectSlowCase(ExecState* exec, JSGlobalObject* globalObject) const
58 {
59     ASSERT(!isCell());
60 
61     if (isInt32() || isDouble())
62         return constructNumber(exec, globalObject, asValue());
63     if (isTrue() || isFalse())
64         return constructBooleanFromImmediateBoolean(exec, globalObject, asValue());
65 
66     ASSERT(isUndefinedOrNull());
67     throwError(exec, createNotAnObjectError(exec, *this));
68     return new (exec) JSNotAnObject(exec);
69 }
70 
toThisObjectSlowCase(ExecState * exec) const71 JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const
72 {
73     ASSERT(!isCell());
74 
75     if (isInt32() || isDouble())
76         return constructNumber(exec, exec->lexicalGlobalObject(), asValue());
77     if (isTrue() || isFalse())
78         return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue());
79     ASSERT(isUndefinedOrNull());
80     return exec->globalThisValue();
81 }
82 
synthesizeObject(ExecState * exec) const83 JSObject* JSValue::synthesizeObject(ExecState* exec) const
84 {
85     ASSERT(!isCell());
86     if (isNumber())
87         return constructNumber(exec, exec->lexicalGlobalObject(), asValue());
88     if (isBoolean())
89         return constructBooleanFromImmediateBoolean(exec, exec->lexicalGlobalObject(), asValue());
90 
91     ASSERT(isUndefinedOrNull());
92     throwError(exec, createNotAnObjectError(exec, *this));
93     return new (exec) JSNotAnObject(exec);
94 }
95 
synthesizePrototype(ExecState * exec) const96 JSObject* JSValue::synthesizePrototype(ExecState* exec) const
97 {
98     ASSERT(!isCell());
99     if (isNumber())
100         return exec->lexicalGlobalObject()->numberPrototype();
101     if (isBoolean())
102         return exec->lexicalGlobalObject()->booleanPrototype();
103 
104     ASSERT(isUndefinedOrNull());
105     throwError(exec, createNotAnObjectError(exec, *this));
106     return new (exec) JSNotAnObject(exec);
107 }
108 
109 #ifndef NDEBUG
description()110 char* JSValue::description()
111 {
112     static const size_t size = 32;
113     static char description[size];
114 
115     if (!*this)
116         snprintf(description, size, "<JSValue()>");
117     else if (isInt32())
118         snprintf(description, size, "Int32: %d", asInt32());
119     else if (isDouble())
120         snprintf(description, size, "Double: %lf", asDouble());
121     else if (isCell())
122         snprintf(description, size, "Cell: %p", asCell());
123     else if (isTrue())
124         snprintf(description, size, "True");
125     else if (isFalse())
126         snprintf(description, size, "False");
127     else if (isNull())
128         snprintf(description, size, "Null");
129     else if (isUndefined())
130         snprintf(description, size, "Undefined");
131     else
132         snprintf(description, size, "INVALID");
133 
134     return description;
135 }
136 #endif
137 
138 // This in the ToInt32 operation is defined in section 9.5 of the ECMA-262 spec.
139 // Note that this operation is identical to ToUInt32 other than to interpretation
140 // of the resulting bit-pattern (as such this metod is also called to implement
141 // ToUInt32).
142 //
143 // The operation can be descibed as round towards zero, then select the 32 least
144 // bits of the resulting value in 2s-complement representation.
toInt32(double number)145 int32_t toInt32(double number)
146 {
147     int64_t bits = WTF::bitwise_cast<int64_t>(number);
148     int32_t exp = (static_cast<int32_t>(bits >> 52) & 0x7ff) - 0x3ff;
149 
150     // If exponent < 0 there will be no bits to the left of the decimal point
151     // after rounding; if the exponent is > 83 then no bits of precision can be
152     // left in the low 32-bit range of the result (IEEE-754 doubles have 52 bits
153     // of fractional precision).
154     // Note this case handles 0, -0, and all infinte, NaN, & denormal value.
155     if (exp < 0 || exp > 83)
156         return 0;
157 
158     // Select the appropriate 32-bits from the floating point mantissa.  If the
159     // exponent is 52 then the bits we need to select are already aligned to the
160     // lowest bits of the 64-bit integer representation of tghe number, no need
161     // to shift.  If the exponent is greater than 52 we need to shift the value
162     // left by (exp - 52), if the value is less than 52 we need to shift right
163     // accordingly.
164     int32_t result = (exp > 52)
165         ? static_cast<int32_t>(bits << (exp - 52))
166         : static_cast<int32_t>(bits >> (52 - exp));
167 
168     // IEEE-754 double precision values are stored omitting an implicit 1 before
169     // the decimal point; we need to reinsert this now.  We may also the shifted
170     // invalid bits into the result that are not a part of the mantissa (the sign
171     // and exponent bits from the floatingpoint representation); mask these out.
172     if (exp < 32) {
173         int32_t missingOne = 1 << exp;
174         result &= missingOne - 1;
175         result += missingOne;
176     }
177 
178     // If the input value was negative (we could test either 'number' or 'bits',
179     // but testing 'bits' is likely faster) invert the result appropriately.
180     return bits < 0 ? -result : result;
181 }
182 
nonInlineNaN()183 NEVER_INLINE double nonInlineNaN()
184 {
185 #if OS(SYMBIAN)
186     return nanval();
187 #else
188     return std::numeric_limits<double>::quiet_NaN();
189 #endif
190 }
191 
isValidCallee()192 bool JSValue::isValidCallee()
193 {
194     return asObject(asObject(asCell())->getAnonymousValue(0))->isGlobalObject();
195 }
196 
197 } // namespace JSC
198