source: webkit/trunk/JavaScriptCore/kjs/value.cpp@ 26912

Last change on this file since 26912 was 26912, checked in by darin, 18 years ago

Reviewed by Maciej.

This should restore correctness and make speed better too, restoring some
of the optimization we lost in my last check-in.

  • kjs/JSImmediate.h: (KJS::JSImmediate::getTruncatedInt32): Added. Uses the range checking idiom I used in my patch yesterday. (KJS::JSImmediate::getTruncatedUInt32): Ditto.
  • kjs/internal.h: Removed getInt32 and added getTruncatedInt/UInt32.
  • kjs/internal.cpp: (KJS::NumberImp::getUInt32): Changed to always use double, since I can't find a way to write this more efficiently for float. (KJS::NumberImp::getTruncatedInt32): Added. (KJS::NumberImp::getTruncatedUInt32): Added.
  • kjs/value.h: Removed getInt32 and added getTruncatedInt/UInt32. (KJS::JSValue::getUInt32): (KJS::JSValue::getTruncatedInt32): Added. (KJS::JSValue::getTruncatedUInt32): Added. (KJS::JSValue::toInt32): Changed getInt32 call to getTruncatedInt32. (KJS::JSValue::toUInt32): Changed getUInt32 call to getTruncatedUInt32.
  • kjs/value.cpp: (KJS::JSCell::getTruncatedInt32): Added. (KJS::JSCell::getTruncatedUInt32): Added. (KJS::JSValue::toInteger): Changed getUInt32 call to getTruncatedInt32. (KJS::JSValue::toInt32SlowCase): Removed extra getInt32 call I accidentally had left in here. (KJS::JSValue::toUInt32SlowCase): Ditto. (KJS::JSValue::toUInt16): Changed getUInt32 call to getTruncatedUInt32.
  • Property svn:eol-style set to native
File size: 4.4 KB
Line 
1/*
2 * Copyright (C) 1999-2001 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2007 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 "value.h"
25
26#include "error_object.h"
27#include "nodes.h"
28#include "operations.h"
29#include <stdio.h>
30#include <string.h>
31#include <wtf/MathExtras.h>
32
33namespace KJS {
34
35static const double D16 = 65536.0;
36static const double D32 = 4294967296.0;
37
38void *JSCell::operator new(size_t size)
39{
40 return Collector::allocate(size);
41}
42
43bool JSCell::getUInt32(uint32_t&) const
44{
45 return false;
46}
47
48bool JSCell::getTruncatedInt32(int32_t&) const
49{
50 return false;
51}
52
53bool JSCell::getTruncatedUInt32(uint32_t&) const
54{
55 return false;
56}
57
58// ECMA 9.4
59double JSValue::toInteger(ExecState *exec) const
60{
61 int32_t i;
62 if (getTruncatedInt32(i))
63 return i;
64 return roundValue(exec, const_cast<JSValue*>(this));
65}
66
67int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
68{
69 ok = true;
70
71 double d = roundValue(exec, const_cast<JSValue*>(this));
72 if (d >= -D32 / 2 && d < D32 / 2)
73 return static_cast<int32_t>(d);
74
75 if (isNaN(d) || isInf(d)) {
76 ok = false;
77 return 0;
78 }
79 double d32 = fmod(d, D32);
80
81 if (d32 >= D32 / 2)
82 d32 -= D32;
83 else if (d32 < -D32 / 2)
84 d32 += D32;
85
86 return static_cast<int32_t>(d32);
87}
88
89uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
90{
91 ok = true;
92
93 double d = roundValue(exec, const_cast<JSValue*>(this));
94 if (d >= 0.0 && d < D32)
95 return static_cast<uint32_t>(d);
96
97 if (isNaN(d) || isInf(d)) {
98 ok = false;
99 return 0;
100 }
101 double d32 = fmod(d, D32);
102
103 if (d32 < 0)
104 d32 += D32;
105
106 return static_cast<uint32_t>(d32);
107}
108
109uint16_t JSValue::toUInt16(ExecState *exec) const
110{
111 uint32_t i;
112 if (getTruncatedUInt32(i))
113 return static_cast<uint16_t>(i);
114
115 double d = roundValue(exec, const_cast<JSValue*>(this));
116 if (d >= 0.0 && d < D16)
117 return static_cast<uint16_t>(d);
118
119 if (isNaN(d) || isInf(d))
120 return 0;
121 double d16 = fmod(d, D16);
122
123 if (d16 < 0)
124 d16 += D16;
125
126 return static_cast<uint16_t>(d16);
127}
128
129float JSValue::toFloat(ExecState* exec) const
130{
131 return static_cast<float>(toNumber(exec));
132}
133
134bool JSCell::getNumber(double &numericValue) const
135{
136 if (!isNumber())
137 return false;
138 numericValue = static_cast<const NumberImp *>(this)->value();
139 return true;
140}
141
142double JSCell::getNumber() const
143{
144 return isNumber() ? static_cast<const NumberImp *>(this)->value() : NaN;
145}
146
147bool JSCell::getString(UString &stringValue) const
148{
149 if (!isString())
150 return false;
151 stringValue = static_cast<const StringImp *>(this)->value();
152 return true;
153}
154
155UString JSCell::getString() const
156{
157 return isString() ? static_cast<const StringImp *>(this)->value() : UString();
158}
159
160JSObject *JSCell::getObject()
161{
162 return isObject() ? static_cast<JSObject *>(this) : 0;
163}
164
165const JSObject *JSCell::getObject() const
166{
167 return isObject() ? static_cast<const JSObject *>(this) : 0;
168}
169
170JSCell* jsString(const char* s)
171{
172 return new StringImp(s ? s : "");
173}
174
175JSCell* jsString(const UString& s)
176{
177 return s.isNull() ? new StringImp("") : new StringImp(s);
178}
179
180JSCell* jsOwnedString(const UString& s)
181{
182 return s.isNull() ? new StringImp("", StringImp::HasOtherOwner) : new StringImp(s, StringImp::HasOtherOwner);
183}
184
185// This method includes a PIC branch to set up the NumberImp's vtable, so we quarantine
186// it in a separate function to keep the normal case speedy.
187JSValue *jsNumberCell(double d)
188{
189 return new NumberImp(d);
190}
191
192} // namespace KJS
Note: See TracBrowser for help on using the repository browser.