source: webkit/trunk/JavaScriptCore/kjs/JSValue.h@ 37285

Last change on this file since 37285 was 37285, checked in by [email protected], 17 years ago

JavaScriptCore:

2008-10-03 Maciej Stachowiak <[email protected]>

Reviewed by Cameron Zwarich.


I changed things so that functions which use "this" do a fast
version of toThisObject conversion if needed. Currently we miss
the conversion entirely, at least for primitive types. Using
TypeInfo and the primitive check, I made the fast case bail out
pretty fast.


This is inexplicably an 1.007x SunSpider speedup (and a wash on V8 benchmarks).


Also renamed some opcodes for clarity:


init ==> enter
init_activation ==> enter_with_activation


  • VM/CTI.cpp: (JSC::CTI::privateCompileMainPass): (JSC::CTI::privateCompileSlowCases):
  • VM/CodeBlock.cpp: (JSC::CodeBlock::dump):
  • VM/CodeGenerator.cpp: (JSC::CodeGenerator::generate): (JSC::CodeGenerator::CodeGenerator):
  • VM/Machine.cpp: (JSC::Machine::privateExecute): (JSC::Machine::cti_op_convert_this):
  • VM/Machine.h:
  • VM/Opcode.h:
  • kjs/JSActivation.cpp: (JSC::JSActivation::JSActivation):
  • kjs/JSActivation.h: (JSC::JSActivation::createStructureID):
  • kjs/JSCell.h: (JSC::JSValue::needsThisConversion):
  • kjs/JSGlobalData.cpp: (JSC::JSGlobalData::JSGlobalData):
  • kjs/JSGlobalData.h:
  • kjs/JSNumberCell.h: (JSC::JSNumberCell::createStructureID):
  • kjs/JSStaticScopeObject.h: (JSC::JSStaticScopeObject::JSStaticScopeObject): (JSC::JSStaticScopeObject::createStructureID):
  • kjs/JSString.h: (JSC::JSString::createStructureID):
  • kjs/JSValue.h:
  • kjs/TypeInfo.h: (JSC::TypeInfo::needsThisConversion):
  • kjs/nodes.h: (JSC::ScopeNode::usesThis):

WebCore:

2008-10-03 Maciej Stachowiak <[email protected]>

Reviewed by Cameron Zwarich.

Updated so toThis conversion for the split window is handled properly.

  • bindings/scripts/CodeGeneratorJS.pm:

LayoutTests:

2008-10-03 Maciej Stachowiak <[email protected]>

Reviewed by Cameron Zwarich.


  • test case for: "this" object in methods called on primitives should be wrapper object
  • fast/js/primitive-method-this-expected.txt: Added.
  • fast/js/primitive-method-this.html: Added.
  • fast/js/resources/primitive-method-this.js: Added.
  • Property svn:eol-style set to native
File size: 8.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, 2004, 2005, 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#ifndef JSValue_h
24#define JSValue_h
25
26#include "CallData.h"
27#include "ConstructData.h"
28#include "JSImmediate.h"
29#include "ustring.h"
30#include <stddef.h> // for size_t
31
32// The magic number 0x4000 is not important here, it is being subtracted back out (avoiding using zero since this
33// can have unexpected effects in this type of macro, particularly where multiple-inheritance is involved).
34#define OBJECT_OFFSET(class, member) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->member)) - 0x4000)
35
36namespace JSC {
37
38 class ExecState;
39 class Identifier;
40 class JSCell;
41 class JSObject;
42 class JSString;
43 class PropertySlot;
44 class PutPropertySlot;
45 class StructureID;
46 struct ClassInfo;
47 struct Instruction;
48
49 /**
50 * JSValue is the base type for all primitives (Undefined, Null, Boolean,
51 * String, Number) and objects in ECMAScript.
52 *
53 * Note: you should never inherit from JSValue as it is for primitive types
54 * only (all of which are provided internally by KJS). Instead, inherit from
55 * JSObject.
56 */
57 class JSValue : Noncopyable {
58 friend class JSCell; // so it can derive from this class
59 private:
60 JSValue();
61 virtual ~JSValue();
62
63 public:
64 // Querying the type.
65 bool isUndefined() const;
66 bool isNull() const;
67 bool isUndefinedOrNull() const;
68 bool isBoolean() const;
69 bool isNumber() const;
70 bool isString() const;
71 bool isGetterSetter() const;
72 bool isObject() const;
73 bool isObject(const ClassInfo*) const; // FIXME: Merge with inherits.
74
75 // Extracting the value.
76 bool getBoolean(bool&) const;
77 bool getBoolean() const; // false if not a boolean
78 bool getNumber(double&) const;
79 double getNumber() const; // NaN if not a number
80 double uncheckedGetNumber() const;
81 bool getString(UString&) const;
82 UString getString() const; // null string if not a string
83 JSObject* getObject(); // NULL if not an object
84 const JSObject* getObject() const; // NULL if not an object
85
86 CallType getCallData(CallData&);
87 ConstructType getConstructData(ConstructData&);
88
89 // Extracting integer values.
90 bool getUInt32(uint32_t&) const;
91 bool getTruncatedInt32(int32_t&) const;
92 bool getTruncatedUInt32(uint32_t&) const;
93
94 // Basic conversions.
95 enum PreferredPrimitiveType { NoPreference, PreferNumber, PreferString };
96 JSValue* toPrimitive(ExecState*, PreferredPrimitiveType = NoPreference) const;
97 bool getPrimitiveNumber(ExecState*, double& number, JSValue*&);
98
99 bool toBoolean(ExecState*) const;
100
101 // toNumber conversion is expected to be side effect free if an exception has
102 // been set in the ExecState already.
103 double toNumber(ExecState*) const;
104 JSValue* toJSNumber(ExecState*) const; // Fast path for when you expect that the value is an immediate number.
105 UString toString(ExecState*) const;
106 JSObject* toObject(ExecState*) const;
107
108 // Integer conversions.
109 double toInteger(ExecState*) const;
110 double toIntegerPreserveNaN(ExecState*) const;
111 int32_t toInt32(ExecState*) const;
112 int32_t toInt32(ExecState*, bool& ok) const;
113 uint32_t toUInt32(ExecState*) const;
114 uint32_t toUInt32(ExecState*, bool& ok) const;
115
116 // These are identical logic to above, and faster than jsNumber(number)->toInt32(exec)
117 static int32_t toInt32(double);
118 static uint32_t toUInt32(double);
119
120 // Floating point conversions.
121 float toFloat(ExecState*) const;
122
123 // Garbage collection.
124 void mark();
125 bool marked() const;
126
127 static int32_t toInt32SlowCase(double, bool& ok);
128 static uint32_t toUInt32SlowCase(double, bool& ok);
129
130 // Object operations, with the toObject operation included.
131 JSValue* get(ExecState*, const Identifier& propertyName) const;
132 JSValue* get(ExecState*, const Identifier& propertyName, PropertySlot&) const;
133 JSValue* get(ExecState*, unsigned propertyName) const;
134 JSValue* get(ExecState*, unsigned propertyName, PropertySlot&) const;
135 void put(ExecState*, const Identifier& propertyName, JSValue*, PutPropertySlot&);
136 void put(ExecState*, unsigned propertyName, JSValue*);
137 bool deleteProperty(ExecState*, const Identifier& propertyName);
138 bool deleteProperty(ExecState*, unsigned propertyName);
139
140 bool needsThisConversion() const;
141 JSObject* toThisObject(ExecState*) const;
142 UString toThisString(ExecState*) const;
143 JSString* toThisJSString(ExecState*);
144
145 JSValue* getJSNumber(); // 0 if this is not a JSNumber or number object
146
147 JSCell* asCell();
148 const JSCell* asCell() const;
149
150 private:
151 bool getPropertySlot(ExecState*, const Identifier& propertyName, PropertySlot&);
152 bool getPropertySlot(ExecState*, unsigned propertyName, PropertySlot&);
153 int32_t toInt32SlowCase(ExecState*, bool& ok) const;
154 uint32_t toUInt32SlowCase(ExecState*, bool& ok) const;
155 };
156
157 inline JSValue::JSValue()
158 {
159 }
160
161 inline JSValue::~JSValue()
162 {
163 }
164
165 inline bool JSValue::isUndefined() const
166 {
167 return this == jsUndefined();
168 }
169
170 inline bool JSValue::isNull() const
171 {
172 return this == jsNull();
173 }
174
175 inline bool JSValue::isUndefinedOrNull() const
176 {
177 return JSImmediate::isUndefinedOrNull(this);
178 }
179
180 inline bool JSValue::isBoolean() const
181 {
182 return JSImmediate::isBoolean(this);
183 }
184
185 inline bool JSValue::getBoolean(bool& v) const
186 {
187 if (JSImmediate::isBoolean(this)) {
188 v = JSImmediate::toBoolean(this);
189 return true;
190 }
191
192 return false;
193 }
194
195 inline bool JSValue::getBoolean() const
196 {
197 return this == jsBoolean(true);
198 }
199
200 ALWAYS_INLINE int32_t JSValue::toInt32(ExecState* exec) const
201 {
202 int32_t i;
203 if (getTruncatedInt32(i))
204 return i;
205 bool ok;
206 return toInt32SlowCase(exec, ok);
207 }
208
209 inline uint32_t JSValue::toUInt32(ExecState* exec) const
210 {
211 uint32_t i;
212 if (getTruncatedUInt32(i))
213 return i;
214 bool ok;
215 return toUInt32SlowCase(exec, ok);
216 }
217
218 inline int32_t JSValue::toInt32(double val)
219 {
220 if (!(val >= -2147483648.0 && val < 2147483648.0)) {
221 bool ignored;
222 return toInt32SlowCase(val, ignored);
223 }
224 return static_cast<int32_t>(val);
225 }
226
227 inline uint32_t JSValue::toUInt32(double val)
228 {
229 if (!(val >= 0.0 && val < 4294967296.0)) {
230 bool ignored;
231 return toUInt32SlowCase(val, ignored);
232 }
233 return static_cast<uint32_t>(val);
234 }
235
236 inline int32_t JSValue::toInt32(ExecState* exec, bool& ok) const
237 {
238 int32_t i;
239 if (getTruncatedInt32(i)) {
240 ok = true;
241 return i;
242 }
243 return toInt32SlowCase(exec, ok);
244 }
245
246 inline uint32_t JSValue::toUInt32(ExecState* exec, bool& ok) const
247 {
248 uint32_t i;
249 if (getTruncatedUInt32(i)) {
250 ok = true;
251 return i;
252 }
253 return toUInt32SlowCase(exec, ok);
254 }
255
256} // namespace JSC
257
258#endif // JSValue_h
Note: See TracBrowser for help on using the repository browser.