]>
git.saurik.com Git - apple/javascriptcore.git/blob - runtime/JSValue.cpp
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.
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.
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.
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.
26 #include "BooleanConstructor.h"
27 #include "BooleanPrototype.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>
39 static const double D32
= 4294967296.0;
42 double JSValue::toInteger(ExecState
* exec
) const
46 double d
= toNumber(exec
);
47 return isnan(d
) ? 0.0 : trunc(d
);
50 double JSValue::toIntegerPreserveNaN(ExecState
* exec
) const
54 return trunc(toNumber(exec
));
57 JSObject
* JSValue::toObjectSlowCase(ExecState
* exec
, JSGlobalObject
* globalObject
) const
61 if (isInt32() || isDouble())
62 return constructNumber(exec
, globalObject
, asValue());
63 if (isTrue() || isFalse())
64 return constructBooleanFromImmediateBoolean(exec
, globalObject
, asValue());
66 ASSERT(isUndefinedOrNull());
67 throwError(exec
, createNotAnObjectError(exec
, *this));
68 return new (exec
) JSNotAnObject(exec
);
71 JSObject
* JSValue::toThisObjectSlowCase(ExecState
* exec
) const
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();
83 JSObject
* JSValue::synthesizeObject(ExecState
* exec
) const
87 return constructNumber(exec
, exec
->lexicalGlobalObject(), asValue());
89 return constructBooleanFromImmediateBoolean(exec
, exec
->lexicalGlobalObject(), asValue());
91 ASSERT(isUndefinedOrNull());
92 throwError(exec
, createNotAnObjectError(exec
, *this));
93 return new (exec
) JSNotAnObject(exec
);
96 JSObject
* JSValue::synthesizePrototype(ExecState
* exec
) const
100 return exec
->lexicalGlobalObject()->numberPrototype();
102 return exec
->lexicalGlobalObject()->booleanPrototype();
104 ASSERT(isUndefinedOrNull());
105 throwError(exec
, createNotAnObjectError(exec
, *this));
106 return new (exec
) JSNotAnObject(exec
);
110 char* JSValue::description()
112 static const size_t size
= 32;
113 static char description
[size
];
116 snprintf(description
, size
, "<JSValue()>");
118 snprintf(description
, size
, "Int32: %d", asInt32());
120 snprintf(description
, size
, "Double: %lf", asDouble());
122 snprintf(description
, size
, "Cell: %p", asCell());
124 snprintf(description
, size
, "True");
126 snprintf(description
, size
, "False");
128 snprintf(description
, size
, "Null");
129 else if (isUndefined())
130 snprintf(description
, size
, "Undefined");
132 snprintf(description
, size
, "INVALID");
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
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.
145 int32_t toInt32(double number
)
147 int64_t bits
= WTF::bitwise_cast
<int64_t>(number
);
148 int32_t exp
= (static_cast<int32_t>(bits
>> 52) & 0x7ff) - 0x3ff;
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)
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
164 int32_t result
= (exp
> 52)
165 ? static_cast<int32_t>(bits
<< (exp
- 52))
166 : static_cast<int32_t>(bits
>> (52 - exp
));
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.
173 int32_t missingOne
= 1 << exp
;
174 result
&= missingOne
- 1;
175 result
+= missingOne
;
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
;
183 NEVER_INLINE
double nonInlineNaN()
188 return std::numeric_limits
<double>::quiet_NaN();
192 bool JSValue::isValidCallee()
194 return asObject(asObject(asCell())->getAnonymousValue(0))->isGlobalObject();