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
37namespace JSC {
38
39static const double D32 = 4294967296.0;
40
41// ECMA 9.4
42double 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
50double JSValue::toIntegerPreserveNaN(ExecState* exec) const
51{
52    if (isInt32())
53        return asInt32();
54    return trunc(toNumber(exec));
55}
56
57JSObject* 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
71JSObject* 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
83JSObject* 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
96JSObject* 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
110char* 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.
145int32_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
183NEVER_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
192bool JSValue::isValidCallee()
193{
194    return asObject(asObject(asCell())->getAnonymousValue(0))->isGlobalObject();
195}
196
197} // namespace JSC
198