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

Last change on this file since 28476 was 27747, checked in by [email protected], 18 years ago

2007-11-12 Eric Seidel <[email protected]>

Reviewed by Oliver.

Add evaluateToInt32 and evaluateUInt32 methods and deploy them.
Fix a few missing evaluateToBoolean methods
Deploy all evaluateTo* functions to more nodes to avoid slowdowns
http://bugs.webkit.org/show_bug.cgi?id=15950

SunSpider claims this is at least a 1.4% speedup.

  • kjs/JSImmediate.h: (KJS::JSImmediate::getTruncatedInt32): (KJS::JSImmediate::toDouble): (KJS::JSImmediate::getUInt32):
  • kjs/nodes.cpp: (KJS::ExpressionNode::evaluateToNumber): (KJS::ExpressionNode::evaluateToInt32): (KJS::ExpressionNode::evaluateToUInt32): (KJS::NumberNode::evaluateToInt32): (KJS::NumberNode::evaluateToUInt32): (KJS::ImmediateNumberNode::evaluateToInt32): (KJS::ImmediateNumberNode::evaluateToUInt32): (KJS::ResolveNode::evaluate): (KJS::ResolveNode::evaluateToNumber): (KJS::ResolveNode::evaluateToBoolean): (KJS::ResolveNode::evaluateToInt32): (KJS::ResolveNode::evaluateToUInt32): (KJS::LocalVarAccessNode::evaluateToInt32): (KJS::LocalVarAccessNode::evaluateToUInt32): (KJS::BracketAccessorNode::evaluateToNumber): (KJS::BracketAccessorNode::evaluateToBoolean): (KJS::BracketAccessorNode::evaluateToInt32): (KJS::BracketAccessorNode::evaluateToUInt32): (KJS::DotAccessorNode::inlineEvaluate): (KJS::DotAccessorNode::evaluate): (KJS::DotAccessorNode::evaluateToNumber): (KJS::DotAccessorNode::evaluateToBoolean): (KJS::DotAccessorNode::evaluateToInt32): (KJS::DotAccessorNode::evaluateToUInt32): (KJS::NewExprNode::inlineEvaluate): (KJS::NewExprNode::evaluate): (KJS::NewExprNode::evaluateToNumber): (KJS::NewExprNode::evaluateToBoolean): (KJS::NewExprNode::evaluateToInt32): (KJS::NewExprNode::evaluateToUInt32): (KJS::FunctionCallResolveNode::inlineEvaluate): (KJS::FunctionCallResolveNode::evaluate): (KJS::FunctionCallResolveNode::evaluateToNumber): (KJS::FunctionCallResolveNode::evaluateToBoolean): (KJS::FunctionCallResolveNode::evaluateToInt32): (KJS::FunctionCallResolveNode::evaluateToUInt32): (KJS::LocalVarFunctionCallNode::evaluate): (KJS::LocalVarFunctionCallNode::evaluateToNumber): (KJS::LocalVarFunctionCallNode::evaluateToBoolean): (KJS::LocalVarFunctionCallNode::evaluateToInt32): (KJS::LocalVarFunctionCallNode::evaluateToUInt32): (KJS::FunctionCallDotNode::evaluate): (KJS::FunctionCallDotNode::evaluateToNumber): (KJS::FunctionCallDotNode::evaluateToBoolean): (KJS::FunctionCallDotNode::evaluateToInt32): (KJS::FunctionCallDotNode::evaluateToUInt32): (KJS::PostDecLocalVarNode::inlineEvaluateToNumber): (KJS::PostDecLocalVarNode::evaluateToNumber): (KJS::PostDecLocalVarNode::evaluateToBoolean): (KJS::PostDecLocalVarNode::evaluateToInt32): (KJS::PostDecLocalVarNode::evaluateToUInt32): (KJS::typeStringForValue): (KJS::UnaryPlusNode::evaluate): (KJS::UnaryPlusNode::evaluateToBoolean): (KJS::UnaryPlusNode::evaluateToNumber): (KJS::UnaryPlusNode::evaluateToInt32): (KJS::BitwiseNotNode::inlineEvaluateToInt32): (KJS::BitwiseNotNode::evaluate): (KJS::BitwiseNotNode::evaluateToNumber): (KJS::BitwiseNotNode::evaluateToBoolean): (KJS::BitwiseNotNode::evaluateToInt32): (KJS::MultNode::evaluateToBoolean): (KJS::MultNode::evaluateToInt32): (KJS::MultNode::evaluateToUInt32): (KJS::DivNode::evaluateToInt32): (KJS::DivNode::evaluateToUInt32): (KJS::ModNode::evaluateToBoolean): (KJS::ModNode::evaluateToInt32): (KJS::ModNode::evaluateToUInt32): (KJS::AddNode::evaluateToNumber): (KJS::AddNode::evaluateToInt32): (KJS::AddNode::evaluateToUInt32): (KJS::AddNumbersNode::evaluateToInt32): (KJS::AddNumbersNode::evaluateToUInt32): (KJS::SubNode::evaluateToInt32): (KJS::SubNode::evaluateToUInt32): (KJS::LeftShiftNode::inlineEvaluateToInt32): (KJS::LeftShiftNode::evaluate): (KJS::LeftShiftNode::evaluateToNumber): (KJS::LeftShiftNode::evaluateToInt32): (KJS::RightShiftNode::inlineEvaluateToInt32): (KJS::RightShiftNode::evaluate): (KJS::RightShiftNode::evaluateToNumber): (KJS::RightShiftNode::evaluateToInt32): (KJS::UnsignedRightShiftNode::inlineEvaluateToUInt32): (KJS::UnsignedRightShiftNode::evaluate): (KJS::UnsignedRightShiftNode::evaluateToNumber): (KJS::UnsignedRightShiftNode::evaluateToInt32): (KJS::LessNode::inlineEvaluateToBoolean): (KJS::LessNode::evaluate): (KJS::LessNode::evaluateToBoolean): (KJS::LessNumbersNode::inlineEvaluateToBoolean): (KJS::LessNumbersNode::evaluate): (KJS::LessNumbersNode::evaluateToBoolean): (KJS::LessStringsNode::inlineEvaluateToBoolean): (KJS::LessStringsNode::evaluate): (KJS::BitAndNode::evaluate): (KJS::BitAndNode::inlineEvaluateToInt32): (KJS::BitAndNode::evaluateToNumber): (KJS::BitAndNode::evaluateToBoolean): (KJS::BitAndNode::evaluateToInt32): (KJS::BitXOrNode::inlineEvaluateToInt32): (KJS::BitXOrNode::evaluate): (KJS::BitXOrNode::evaluateToNumber): (KJS::BitXOrNode::evaluateToBoolean): (KJS::BitXOrNode::evaluateToInt32): (KJS::BitOrNode::inlineEvaluateToInt32): (KJS::BitOrNode::evaluate): (KJS::BitOrNode::evaluateToNumber): (KJS::BitOrNode::evaluateToBoolean): (KJS::BitOrNode::evaluateToInt32): (KJS::ConditionalNode::evaluateToNumber): (KJS::ConditionalNode::evaluateToInt32): (KJS::ConditionalNode::evaluateToUInt32): (KJS::valueForReadModifyAssignment): (KJS::AssignExprNode::evaluate): (KJS::AssignExprNode::evaluateToBoolean): (KJS::AssignExprNode::evaluateToNumber): (KJS::AssignExprNode::evaluateToInt32): (KJS::VarDeclNode::handleSlowCase):
  • kjs/nodes.h: (KJS::FunctionCallResolveNode::precedence): (KJS::AddNode::precedence): (KJS::AddNode::): (KJS::LessNumbersNode::): (KJS::LessStringsNode::):
  • kjs/value.cpp: (KJS::JSValue::toInt32SlowCase): (KJS::JSValue::toUInt32SlowCase):
  • kjs/value.h: (KJS::JSValue::asCell): (KJS::JSValue::toInt32): (KJS::JSValue::toUInt32):
  • Property svn:eol-style set to native
File size: 4.2 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 <stdio.h>
29#include <string.h>
30#include <wtf/MathExtras.h>
31
32namespace KJS {
33
34static const double D16 = 65536.0;
35static const double D32 = 4294967296.0;
36
37void *JSCell::operator new(size_t size)
38{
39 return Collector::allocate(size);
40}
41
42bool JSCell::getUInt32(uint32_t&) const
43{
44 return false;
45}
46
47bool JSCell::getTruncatedInt32(int32_t&) const
48{
49 return false;
50}
51
52bool JSCell::getTruncatedUInt32(uint32_t&) const
53{
54 return false;
55}
56
57// ECMA 9.4
58double JSValue::toInteger(ExecState *exec) const
59{
60 int32_t i;
61 if (getTruncatedInt32(i))
62 return i;
63 double d = toNumber(exec);
64 return isnan(d) ? 0.0 : trunc(d);
65}
66
67double JSValue::toIntegerPreserveNaN(ExecState *exec) const
68{
69 int32_t i;
70 if (getTruncatedInt32(i))
71 return i;
72 return trunc(toNumber(exec));
73}
74
75int32_t JSValue::toInt32SlowCase(double d, bool& ok)
76{
77 ok = true;
78
79 if (d >= -D32 / 2 && d < D32 / 2)
80 return static_cast<int32_t>(d);
81
82 if (isnan(d) || isinf(d)) {
83 ok = false;
84 return 0;
85 }
86
87 double d32 = fmod(trunc(d), D32);
88 if (d32 >= D32 / 2)
89 d32 -= D32;
90 else if (d32 < -D32 / 2)
91 d32 += D32;
92 return static_cast<int32_t>(d32);
93}
94
95int32_t JSValue::toInt32SlowCase(ExecState* exec, bool& ok) const
96{
97 return JSValue::toInt32SlowCase(toNumber(exec), ok);
98}
99
100uint32_t JSValue::toUInt32SlowCase(double d, bool& ok)
101{
102 ok = true;
103
104 if (d >= 0.0 && d < D32)
105 return static_cast<uint32_t>(d);
106
107 if (isnan(d) || isinf(d)) {
108 ok = false;
109 return 0;
110 }
111
112 double d32 = fmod(trunc(d), D32);
113 if (d32 < 0)
114 d32 += D32;
115 return static_cast<uint32_t>(d32);
116}
117
118uint32_t JSValue::toUInt32SlowCase(ExecState* exec, bool& ok) const
119{
120 return JSValue::toUInt32SlowCase(toNumber(exec), ok);
121}
122
123float JSValue::toFloat(ExecState* exec) const
124{
125 return static_cast<float>(toNumber(exec));
126}
127
128bool JSCell::getNumber(double &numericValue) const
129{
130 if (!isNumber())
131 return false;
132 numericValue = static_cast<const NumberImp *>(this)->value();
133 return true;
134}
135
136double JSCell::getNumber() const
137{
138 return isNumber() ? static_cast<const NumberImp *>(this)->value() : NaN;
139}
140
141bool JSCell::getString(UString &stringValue) const
142{
143 if (!isString())
144 return false;
145 stringValue = static_cast<const StringImp *>(this)->value();
146 return true;
147}
148
149UString JSCell::getString() const
150{
151 return isString() ? static_cast<const StringImp *>(this)->value() : UString();
152}
153
154JSObject *JSCell::getObject()
155{
156 return isObject() ? static_cast<JSObject *>(this) : 0;
157}
158
159const JSObject *JSCell::getObject() const
160{
161 return isObject() ? static_cast<const JSObject *>(this) : 0;
162}
163
164JSCell* jsString(const char* s)
165{
166 return new StringImp(s ? s : "");
167}
168
169JSCell* jsString(const UString& s)
170{
171 return s.isNull() ? new StringImp("") : new StringImp(s);
172}
173
174JSCell* jsOwnedString(const UString& s)
175{
176 return s.isNull() ? new StringImp("", StringImp::HasOtherOwner) : new StringImp(s, StringImp::HasOtherOwner);
177}
178
179// This method includes a PIC branch to set up the NumberImp's vtable, so we quarantine
180// it in a separate function to keep the normal case speedy.
181JSValue *jsNumberCell(double d)
182{
183 return new NumberImp(d);
184}
185
186} // namespace KJS
Note: See TracBrowser for help on using the repository browser.