• 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 "ExceptionHelpers.h"
29 #include "JSGlobalObject.h"
30 #include "JSFunction.h"
31 #include "JSNotAnObject.h"
32 #include "NumberObject.h"
33 #include <wtf/MathExtras.h>
34 #include <wtf/StringExtras.h>
35 
36 namespace JSC {
37 
38 static const double D32 = 4294967296.0;
39 
40 // ECMA 9.4
toInteger(ExecState * exec) const41 double JSValue::toInteger(ExecState* exec) const
42 {
43     if (isInt32())
44         return asInt32();
45     double d = toNumber(exec);
46     return isnan(d) ? 0.0 : trunc(d);
47 }
48 
toIntegerPreserveNaN(ExecState * exec) const49 double JSValue::toIntegerPreserveNaN(ExecState* exec) const
50 {
51     if (isInt32())
52         return asInt32();
53     return trunc(toNumber(exec));
54 }
55 
toObjectSlowCase(ExecState * exec) const56 JSObject* JSValue::toObjectSlowCase(ExecState* exec) const
57 {
58     ASSERT(!isCell());
59 
60     if (isInt32() || isDouble())
61         return constructNumber(exec, asValue());
62     if (isTrue() || isFalse())
63         return constructBooleanFromImmediateBoolean(exec, asValue());
64     ASSERT(isUndefinedOrNull());
65     JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull());
66     exec->setException(exception);
67     return new (exec) JSNotAnObject(exec, exception);
68 }
69 
toThisObjectSlowCase(ExecState * exec) const70 JSObject* JSValue::toThisObjectSlowCase(ExecState* exec) const
71 {
72     ASSERT(!isCell());
73 
74     if (isInt32() || isDouble())
75         return constructNumber(exec, asValue());
76     if (isTrue() || isFalse())
77         return constructBooleanFromImmediateBoolean(exec, asValue());
78     ASSERT(isUndefinedOrNull());
79     return exec->globalThisValue();
80 }
81 
synthesizeObject(ExecState * exec) const82 JSObject* JSValue::synthesizeObject(ExecState* exec) const
83 {
84     ASSERT(!isCell());
85     if (isNumber())
86         return constructNumber(exec, asValue());
87     if (isBoolean())
88         return constructBooleanFromImmediateBoolean(exec, asValue());
89 
90     JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull());
91     exec->setException(exception);
92     return new (exec) JSNotAnObject(exec, exception);
93 }
94 
synthesizePrototype(ExecState * exec) const95 JSObject* JSValue::synthesizePrototype(ExecState* exec) const
96 {
97     ASSERT(!isCell());
98     if (isNumber())
99         return exec->lexicalGlobalObject()->numberPrototype();
100     if (isBoolean())
101         return exec->lexicalGlobalObject()->booleanPrototype();
102 
103     JSNotAnObjectErrorStub* exception = createNotAnObjectErrorStub(exec, isNull());
104     exec->setException(exception);
105     return new (exec) JSNotAnObject(exec, exception);
106 }
107 
108 #ifndef NDEBUG
description()109 char* JSValue::description()
110 {
111     static const size_t size = 32;
112     static char description[size];
113 
114     if (!*this)
115         snprintf(description, size, "<JSValue()>");
116     else if (isInt32())
117         snprintf(description, size, "Int32: %d", asInt32());
118     else if (isDouble())
119         snprintf(description, size, "Double: %lf", asDouble());
120     else if (isCell())
121         snprintf(description, size, "Cell: %p", asCell());
122     else if (isTrue())
123         snprintf(description, size, "True");
124     else if (isFalse())
125         snprintf(description, size, "False");
126     else if (isNull())
127         snprintf(description, size, "Null");
128     else {
129         ASSERT(isUndefined());
130         snprintf(description, size, "Undefined");
131     }
132 
133     return description;
134 }
135 #endif
136 
toInt32SlowCase(double d,bool & ok)137 int32_t toInt32SlowCase(double d, bool& ok)
138 {
139     ok = true;
140 
141     if (d >= -D32 / 2 && d < D32 / 2)
142         return static_cast<int32_t>(d);
143 
144     if (isnan(d) || isinf(d)) {
145         ok = false;
146         return 0;
147     }
148 
149     double d32 = fmod(trunc(d), D32);
150     if (d32 >= D32 / 2)
151         d32 -= D32;
152     else if (d32 < -D32 / 2)
153         d32 += D32;
154     return static_cast<int32_t>(d32);
155 }
156 
toUInt32SlowCase(double d,bool & ok)157 uint32_t toUInt32SlowCase(double d, bool& ok)
158 {
159     ok = true;
160 
161     if (d >= 0.0 && d < D32)
162         return static_cast<uint32_t>(d);
163 
164     if (isnan(d) || isinf(d)) {
165         ok = false;
166         return 0;
167     }
168 
169     double d32 = fmod(trunc(d), D32);
170     if (d32 < 0)
171         d32 += D32;
172     return static_cast<uint32_t>(d32);
173 }
174 
nonInlineNaN()175 NEVER_INLINE double nonInlineNaN()
176 {
177 #if OS(SYMBIAN)
178     return nanval();
179 #else
180     return std::numeric_limits<double>::quiet_NaN();
181 #endif
182 }
183 
184 } // namespace JSC
185