source: webkit/trunk/JavaScriptCore/kjs/nodes.h@ 29815

Last change on this file since 29815 was 29815, checked in by Darin Adler, 17 years ago

JavaScriptCore:

Reviewed by Oliver.

Test: fast/js/function-toString-parentheses.html

The problem here was that a NumberNode with a negative number in it had the wrong
precedence. It's not a primary expression, it's a unary operator with a primary
expression after it.

Once the precedence of NumberNode was fixed, the cases from bug 17020 were also
fixed without trying to treat bracket nodes like dot nodes. That wasn't needed.
The reason we handle numbers before dot nodes specially is that the dot is a
legal character in a number. The same is not true of a bracket. Eventually we
could get smarter, and only add the parentheses when there is actual ambiguity.
There is none if the string form of the number already has a dot in it, or if
it's a number with a alphabetic name like infinity or NAN.

  • kjs/nodes.h: Renamed back from ObjectAccess to DotExpr. (KJS::NumberNode::precedence): Return PrecUnary for negative numbers, since they serialize as a unary operator, not a primary expression.
  • kjs/nodes2string.cpp: (KJS::SourceStream::operator<<): Clear m_numberNeedsParens if this adds parens; one set is enough. (KJS::bracketNodeStreamTo): Remove unneeded special flag here. Normal operator precedence suffices. (KJS::NewExprNode::streamTo): Ditto.

LayoutTests:

Reviewed by Oliver.

  • fast/js/function-toString-parentheses-expected.txt: Updated.
  • fast/js/resources/function-toString-parentheses.js: More test cases.
  • Property svn:eol-style set to native
File size: 83.7 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich ([email protected])
6 * Copyright (C) 2007 Maks Orlovich
7 * Copyright (C) 2007 Eric Seidel <[email protected]>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 *
24 */
25
26#ifndef NODES_H_
27#define NODES_H_
28
29#include "internal.h"
30#include "regexp.h"
31#include "SymbolTable.h"
32#include <wtf/ListRefPtr.h>
33#include <wtf/MathExtras.h>
34#include <wtf/OwnPtr.h>
35#include <wtf/Vector.h>
36
37#if PLATFORM(X86) && COMPILER(GCC)
38#define KJS_FAST_CALL __attribute__((regparm(3)))
39#else
40#define KJS_FAST_CALL
41#endif
42
43namespace KJS {
44
45 class FuncDeclNode;
46 class Node;
47 class PropertyListNode;
48 class SourceStream;
49 class ConstDeclNode;
50
51 enum Operator {
52 OpEqual,
53 OpPlusEq,
54 OpMinusEq,
55 OpMultEq,
56 OpDivEq,
57 OpPlusPlus,
58 OpMinusMinus,
59 OpAndEq,
60 OpXOrEq,
61 OpOrEq,
62 OpModEq,
63 OpLShift,
64 OpRShift,
65 OpURShift,
66 };
67
68 enum Precedence {
69 PrecPrimary,
70 PrecMember,
71 PrecCall,
72 PrecLeftHandSide,
73 PrecPostfix,
74 PrecUnary,
75 PrecMultiplicitave,
76 PrecAdditive,
77 PrecShift,
78 PrecRelational,
79 PrecEquality,
80 PrecBitwiseAnd,
81 PrecBitwiseXor,
82 PrecBitwiseOr,
83 PrecLogicalAnd,
84 PrecLogicalOr,
85 PrecConditional,
86 PrecAssignment,
87 PrecExpression
88 };
89
90 struct DeclarationStacks {
91 typedef Vector<Node*, 16> NodeStack;
92 enum { IsConstant, HasInitializer } VarAttrs;
93 typedef Vector<std::pair<Identifier, unsigned>, 16> VarStack;
94 typedef Vector<FuncDeclNode*, 16> FunctionStack;
95
96 DeclarationStacks(ExecState* e, NodeStack& n, VarStack& v, FunctionStack& f)
97 : exec(e)
98 , nodeStack(n)
99 , varStack(v)
100 , functionStack(f)
101 {
102 }
103
104 ExecState* exec;
105 NodeStack& nodeStack;
106 VarStack& varStack;
107 FunctionStack& functionStack;
108 };
109
110 class ParserRefCounted : Noncopyable {
111 protected:
112 ParserRefCounted() KJS_FAST_CALL;
113 ParserRefCounted(PlacementNewAdoptType) KJS_FAST_CALL { }
114
115 public:
116 void ref() KJS_FAST_CALL;
117 void deref() KJS_FAST_CALL;
118 unsigned refcount() KJS_FAST_CALL;
119
120 static void deleteNewObjects() KJS_FAST_CALL;
121
122 virtual ~ParserRefCounted();
123 };
124
125 class Node : public ParserRefCounted {
126 public:
127 Node() KJS_FAST_CALL;
128 Node(PlacementNewAdoptType placementAdopt) KJS_FAST_CALL
129 : ParserRefCounted(placementAdopt) { }
130
131 UString toString() const KJS_FAST_CALL;
132 int lineNo() const KJS_FAST_CALL { return m_line; }
133
134 // Serialization.
135 virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
136 virtual Precedence precedence() const = 0;
137 virtual bool needsParensIfLeftmost() const { return false; }
138
139 // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
140 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL { }
141
142 protected:
143 Node(JSType) KJS_FAST_CALL; // used by ExpressionNode
144
145 // for use in execute()
146 JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
147 JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
148
149 // for use in evaluate()
150 JSValue* throwError(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
151 JSValue* throwError(ExecState*, ErrorType, const char* msg, const char*) KJS_FAST_CALL;
152 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*) KJS_FAST_CALL;
153 JSValue* throwError(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
154 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, const Identifier&) KJS_FAST_CALL;
155 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, Node*) KJS_FAST_CALL;
156 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, const Identifier&) KJS_FAST_CALL;
157
158 JSValue* throwUndefinedVariableError(ExecState*, const Identifier&) KJS_FAST_CALL;
159
160 void handleException(ExecState*) KJS_FAST_CALL;
161 void handleException(ExecState*, JSValue*) KJS_FAST_CALL;
162
163 // for use in execute()
164 JSValue* rethrowException(ExecState*) KJS_FAST_CALL;
165
166 int m_line : 28;
167 unsigned m_expectedReturnType : 3; // JSType
168 };
169
170 class ExpressionNode : public Node {
171 public:
172 ExpressionNode() KJS_FAST_CALL : Node() {}
173 ExpressionNode(JSType expectedReturn) KJS_FAST_CALL
174 : Node(expectedReturn) {}
175
176 // Special constructor for cases where we overwrite an object in place.
177 ExpressionNode(PlacementNewAdoptType) KJS_FAST_CALL
178 : Node(PlacementNewAdopt) {}
179
180 virtual bool isNumber() const KJS_FAST_CALL { return false; }
181 virtual bool isLocation() const KJS_FAST_CALL { return false; }
182 virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
183 virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
184 virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
185
186 JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
187
188 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
189 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
190 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
191 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
192 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
193
194 // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance
195 virtual void optimizeForUnnecessaryResult() { }
196 };
197
198 class StatementNode : public Node {
199 public:
200 StatementNode() KJS_FAST_CALL;
201 void setLoc(int line0, int line1) KJS_FAST_CALL;
202 int firstLine() const KJS_FAST_CALL { return lineNo(); }
203 int lastLine() const KJS_FAST_CALL { return m_lastLine; }
204 virtual JSValue* execute(ExecState *exec) KJS_FAST_CALL = 0;
205 void pushLabel(const Identifier &id) KJS_FAST_CALL { ls.push(id); }
206 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
207 virtual bool isEmptyStatement() const KJS_FAST_CALL { return false; }
208 protected:
209 LabelStack ls;
210 private:
211 int m_lastLine;
212 };
213
214 class NullNode : public ExpressionNode {
215 public:
216 NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {}
217 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
218 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
219 virtual Precedence precedence() const { return PrecPrimary; }
220 };
221
222 class FalseNode : public ExpressionNode {
223 public:
224 FalseNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {}
225 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
226 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; }
227 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
228 virtual Precedence precedence() const { return PrecPrimary; }
229 };
230
231 class TrueNode : public ExpressionNode {
232 public:
233 TrueNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {}
234 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
235 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; }
236 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
237 virtual Precedence precedence() const { return PrecPrimary; }
238 };
239
240 class PlaceholderTrueNode : public TrueNode {
241 public:
242 // Like TrueNode, but does not serialize as "true".
243 PlaceholderTrueNode() KJS_FAST_CALL : TrueNode() { }
244 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
245 };
246
247 class NumberNode : public ExpressionNode {
248 public:
249 NumberNode(double v) KJS_FAST_CALL : ExpressionNode(NumberType), m_double(v) {}
250 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
251 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
252 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
253 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
254 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
255 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
256 virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; }
257
258 virtual bool isNumber() const KJS_FAST_CALL { return true; }
259 double value() const KJS_FAST_CALL { return m_double; }
260 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; }
261
262 protected:
263 double m_double;
264 };
265
266 class ImmediateNumberNode : public NumberNode {
267 public:
268 ImmediateNumberNode(JSValue* v, double d) KJS_FAST_CALL : NumberNode(d), m_value(v) { ASSERT(v == JSImmediate::from(d)); }
269 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
270 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
271 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
272
273 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
274 private:
275 JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr
276 };
277
278 class StringNode : public ExpressionNode {
279 public:
280 StringNode(const UString* v) KJS_FAST_CALL : ExpressionNode(StringType), m_value(*v) {}
281 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
282 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
283 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
284 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
285 virtual Precedence precedence() const { return PrecPrimary; }
286
287 private:
288 UString m_value;
289 };
290
291 class RegExpNode : public ExpressionNode {
292 public:
293 RegExpNode(const UString& pattern, const UString& flags) KJS_FAST_CALL
294 : m_regExp(new RegExp(pattern, flags))
295 {
296 }
297 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
298 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
299 virtual Precedence precedence() const { return PrecPrimary; }
300 private:
301 RefPtr<RegExp> m_regExp;
302 };
303
304 class ThisNode : public ExpressionNode {
305 public:
306 ThisNode() KJS_FAST_CALL {}
307 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
308 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
309 virtual Precedence precedence() const { return PrecPrimary; }
310 };
311
312 class ResolveNode : public ExpressionNode {
313 public:
314 ResolveNode(const Identifier &s) KJS_FAST_CALL
315 : ident(s)
316 {
317 }
318
319 // Special constructor for cases where we overwrite an object in place.
320 ResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
321 : ExpressionNode(PlacementNewAdopt)
322 , ident(PlacementNewAdopt)
323 {
324 }
325
326 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
327
328 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
329 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
330 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
331 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
332 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
333 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
334 virtual Precedence precedence() const { return PrecPrimary; }
335
336 virtual bool isLocation() const KJS_FAST_CALL { return true; }
337 virtual bool isResolveNode() const KJS_FAST_CALL { return true; }
338 const Identifier& identifier() const KJS_FAST_CALL { return ident; }
339
340 protected:
341 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
342 Identifier ident;
343 size_t index; // Used by LocalVarAccessNode.
344 };
345
346 class LocalVarAccessNode : public ResolveNode {
347 public:
348 // Overwrites a ResolveNode in place.
349 LocalVarAccessNode(size_t i) KJS_FAST_CALL
350 : ResolveNode(PlacementNewAdopt)
351 {
352 ASSERT(i != missingSymbolMarker());
353 index = i;
354 }
355 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
356 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
357 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
358 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
359 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
360 private:
361 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
362 };
363
364 class ElementNode : public Node {
365 public:
366 ElementNode(int e, ExpressionNode* n) KJS_FAST_CALL : elision(e), node(n) { }
367 ElementNode(ElementNode* l, int e, ExpressionNode* n) KJS_FAST_CALL
368 : elision(e), node(n) { l->next = this; }
369 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
370 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
371 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
372
373 PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return next.release(); }
374
375 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
376
377 private:
378 friend class ArrayNode;
379 ListRefPtr<ElementNode> next;
380 int elision;
381 RefPtr<ExpressionNode> node;
382 };
383
384 class ArrayNode : public ExpressionNode {
385 public:
386 ArrayNode(int e) KJS_FAST_CALL : elision(e), opt(true) { }
387 ArrayNode(ElementNode* ele) KJS_FAST_CALL
388 : element(ele), elision(0), opt(false) { }
389 ArrayNode(int eli, ElementNode* ele) KJS_FAST_CALL
390 : element(ele), elision(eli), opt(true) { }
391 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
392 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
393 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
394 virtual Precedence precedence() const { return PrecPrimary; }
395 private:
396 RefPtr<ElementNode> element;
397 int elision;
398 bool opt;
399 };
400
401 class PropertyNode : public Node {
402 public:
403 enum Type { Constant, Getter, Setter };
404 PropertyNode(const Identifier& n, ExpressionNode* a, Type t) KJS_FAST_CALL
405 : m_name(n), assign(a), type(t) { }
406 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
407 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
408 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
409
410 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
411 const Identifier& name() const { return m_name; }
412
413 private:
414 friend class PropertyListNode;
415 Identifier m_name;
416 RefPtr<ExpressionNode> assign;
417 Type type;
418 };
419
420 class PropertyListNode : public Node {
421 public:
422 PropertyListNode(PropertyNode* n) KJS_FAST_CALL
423 : node(n) { }
424 PropertyListNode(PropertyNode* n, PropertyListNode* l) KJS_FAST_CALL
425 : node(n) { l->next = this; }
426 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
427 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
428 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
429
430 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
431 PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
432
433 private:
434 friend class ObjectLiteralNode;
435 RefPtr<PropertyNode> node;
436 ListRefPtr<PropertyListNode> next;
437 };
438
439 class ObjectLiteralNode : public ExpressionNode {
440 public:
441 ObjectLiteralNode() KJS_FAST_CALL { }
442 ObjectLiteralNode(PropertyListNode* l) KJS_FAST_CALL : list(l) { }
443 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
444 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
445 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
446 virtual Precedence precedence() const { return PrecPrimary; }
447 virtual bool needsParensIfLeftmost() const { return true; }
448 private:
449 RefPtr<PropertyListNode> list;
450 };
451
452 class BracketAccessorNode : public ExpressionNode {
453 public:
454 BracketAccessorNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
455 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
456 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
457 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
458 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
459 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
460 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
461 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
462 virtual Precedence precedence() const { return PrecMember; }
463
464 virtual bool isLocation() const KJS_FAST_CALL { return true; }
465 virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return true; }
466 ExpressionNode* base() KJS_FAST_CALL { return expr1.get(); }
467 ExpressionNode* subscript() KJS_FAST_CALL { return expr2.get(); }
468
469 private:
470 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
471 RefPtr<ExpressionNode> expr1;
472 RefPtr<ExpressionNode> expr2;
473 };
474
475 class DotAccessorNode : public ExpressionNode {
476 public:
477 DotAccessorNode(ExpressionNode* e, const Identifier& s) KJS_FAST_CALL : expr(e), ident(s) { }
478 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
479 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
480 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
481 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
482 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
483 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
484 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
485 virtual Precedence precedence() const { return PrecMember; }
486
487 virtual bool isLocation() const KJS_FAST_CALL { return true; }
488 virtual bool isDotAccessorNode() const KJS_FAST_CALL { return true; }
489 ExpressionNode* base() const KJS_FAST_CALL { return expr.get(); }
490 const Identifier& identifier() const KJS_FAST_CALL { return ident; }
491
492 private:
493 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
494 RefPtr<ExpressionNode> expr;
495 Identifier ident;
496 };
497
498 class ArgumentListNode : public Node {
499 public:
500 ArgumentListNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
501 ArgumentListNode(ArgumentListNode* l, ExpressionNode* e) KJS_FAST_CALL
502 : expr(e) { l->next = this; }
503 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
504 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
505 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
506
507 void evaluateList(ExecState*, List&) KJS_FAST_CALL;
508 PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
509
510 private:
511 friend class ArgumentsNode;
512 ListRefPtr<ArgumentListNode> next;
513 RefPtr<ExpressionNode> expr;
514 };
515
516 class ArgumentsNode : public Node {
517 public:
518 ArgumentsNode() KJS_FAST_CALL { }
519 ArgumentsNode(ArgumentListNode* l) KJS_FAST_CALL
520 : listNode(l) { }
521 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
522 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
523 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
524
525 void evaluateList(ExecState* exec, List& list) KJS_FAST_CALL { if (listNode) listNode->evaluateList(exec, list); }
526
527 private:
528 RefPtr<ArgumentListNode> listNode;
529 };
530
531 class NewExprNode : public ExpressionNode {
532 public:
533 NewExprNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
534 NewExprNode(ExpressionNode* e, ArgumentsNode* a) KJS_FAST_CALL : expr(e), args(a) {}
535 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
536 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
537 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
538 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
539 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
540 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
541 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
542 virtual Precedence precedence() const { return PrecLeftHandSide; }
543 private:
544 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
545 RefPtr<ExpressionNode> expr;
546 RefPtr<ArgumentsNode> args;
547 };
548
549 class FunctionCallValueNode : public ExpressionNode {
550 public:
551 FunctionCallValueNode(ExpressionNode* e, ArgumentsNode* a) KJS_FAST_CALL : expr(e), args(a) {}
552 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
553 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
554 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
555 virtual Precedence precedence() const { return PrecCall; }
556 private:
557 RefPtr<ExpressionNode> expr;
558 RefPtr<ArgumentsNode> args;
559 };
560
561 class FunctionCallResolveNode : public ExpressionNode {
562 public:
563 FunctionCallResolveNode(const Identifier& i, ArgumentsNode* a) KJS_FAST_CALL
564 : ident(i)
565 , args(a)
566 {
567 }
568
569 FunctionCallResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
570 : ExpressionNode(PlacementNewAdopt)
571 , ident(PlacementNewAdopt)
572 , args(PlacementNewAdopt)
573 {
574 }
575
576 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
577 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
578 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
579 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
580 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
581 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
582 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
583 virtual Precedence precedence() const { return PrecCall; }
584
585 protected:
586 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
587 Identifier ident;
588 RefPtr<ArgumentsNode> args;
589 size_t index; // Used by LocalVarFunctionCallNode.
590 };
591
592 class LocalVarFunctionCallNode : public FunctionCallResolveNode {
593 public:
594 LocalVarFunctionCallNode(size_t i) KJS_FAST_CALL
595 : FunctionCallResolveNode(PlacementNewAdopt)
596 {
597 ASSERT(i != missingSymbolMarker());
598 index = i;
599 }
600
601 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
602 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
603 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
604 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
605 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
606 private:
607 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
608 };
609
610 class FunctionCallBracketNode : public ExpressionNode {
611 public:
612 FunctionCallBracketNode(ExpressionNode* b, ExpressionNode* s, ArgumentsNode* a) KJS_FAST_CALL : base(b), subscript(s), args(a) {}
613 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
614 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
615 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
616 virtual Precedence precedence() const { return PrecCall; }
617 protected:
618 RefPtr<ExpressionNode> base;
619 RefPtr<ExpressionNode> subscript;
620 RefPtr<ArgumentsNode> args;
621 };
622
623 class FunctionCallDotNode : public ExpressionNode {
624 public:
625 FunctionCallDotNode(ExpressionNode* b, const Identifier& i, ArgumentsNode* a) KJS_FAST_CALL : base(b), ident(i), args(a) {}
626 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
627 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
628 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
629 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
630 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
631 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
632 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
633 virtual Precedence precedence() const { return PrecCall; }
634 private:
635 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
636 RefPtr<ExpressionNode> base;
637 Identifier ident;
638 RefPtr<ArgumentsNode> args;
639 };
640
641 class PrePostResolveNode : public ExpressionNode {
642 public:
643 PrePostResolveNode(const Identifier& i) KJS_FAST_CALL : ExpressionNode(NumberType), m_ident(i) {}
644
645 PrePostResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
646 : ExpressionNode(PlacementNewAdopt)
647 , m_ident(PlacementNewAdopt)
648 {
649 }
650
651 protected:
652 Identifier m_ident;
653 size_t m_index; // Used by LocalVarPostfixNode.
654 };
655
656 class PostIncResolveNode : public PrePostResolveNode {
657 public:
658 PostIncResolveNode(const Identifier& i) KJS_FAST_CALL : PrePostResolveNode(i) {}
659
660 PostIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
661 : PrePostResolveNode(PlacementNewAdopt)
662 {
663 }
664
665 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
666 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
667 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
668 virtual Precedence precedence() const { return PrecPostfix; }
669 virtual void optimizeForUnnecessaryResult();
670
671 };
672
673 class PostIncLocalVarNode : public PostIncResolveNode {
674 public:
675 PostIncLocalVarNode(size_t i) KJS_FAST_CALL
676 : PostIncResolveNode(PlacementNewAdopt)
677 {
678 ASSERT(i != missingSymbolMarker());
679 m_index = i;
680 }
681
682 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
683 virtual void optimizeForUnnecessaryResult();
684 };
685
686 class PostDecResolveNode : public PrePostResolveNode {
687 public:
688 PostDecResolveNode(const Identifier& i) KJS_FAST_CALL : PrePostResolveNode(i) {}
689
690 PostDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
691 : PrePostResolveNode(PlacementNewAdopt)
692 {
693 }
694
695 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
696 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
697 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
698 virtual Precedence precedence() const { return PrecPostfix; }
699 virtual void optimizeForUnnecessaryResult();
700 };
701
702 class PostDecLocalVarNode : public PostDecResolveNode {
703 public:
704 PostDecLocalVarNode(size_t i) KJS_FAST_CALL
705 : PostDecResolveNode(PlacementNewAdopt)
706 {
707 ASSERT(i != missingSymbolMarker());
708 m_index = i;
709 }
710
711 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
712 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
713 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
714 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
715 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
716 virtual void optimizeForUnnecessaryResult();
717 private:
718 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
719 };
720
721 class PostfixBracketNode : public ExpressionNode {
722 public:
723 PostfixBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : m_base(b), m_subscript(s) {}
724 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
725 virtual Precedence precedence() const { return PrecPostfix; }
726 protected:
727 RefPtr<ExpressionNode> m_base;
728 RefPtr<ExpressionNode> m_subscript;
729 };
730
731 class PostIncBracketNode : public PostfixBracketNode {
732 public:
733 PostIncBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : PostfixBracketNode(b, s) {}
734 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
735 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
736 };
737
738 class PostDecBracketNode : public PostfixBracketNode {
739 public:
740 PostDecBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : PostfixBracketNode(b, s) {}
741 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
742 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
743 };
744
745 class PostfixDotNode : public ExpressionNode {
746 public:
747 PostfixDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : m_base(b), m_ident(i) {}
748 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
749 virtual Precedence precedence() const { return PrecPostfix; }
750 protected:
751 RefPtr<ExpressionNode> m_base;
752 Identifier m_ident;
753 };
754
755 class PostIncDotNode : public PostfixDotNode {
756 public:
757 PostIncDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : PostfixDotNode(b, i) {}
758 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
759 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
760 };
761
762 class PostDecDotNode : public PostfixDotNode {
763 public:
764 PostDecDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : PostfixDotNode(b, i) {}
765 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
766 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
767 };
768
769 class PostfixErrorNode : public ExpressionNode {
770 public:
771 PostfixErrorNode(ExpressionNode* e, Operator o) KJS_FAST_CALL : m_expr(e), m_oper(o) {}
772 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
773 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
774 virtual Precedence precedence() const { return PrecPostfix; }
775 private:
776 RefPtr<ExpressionNode> m_expr;
777 Operator m_oper;
778 };
779
780 class DeleteResolveNode : public ExpressionNode {
781 public:
782 DeleteResolveNode(const Identifier& i) KJS_FAST_CALL : m_ident(i) {}
783 DeleteResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
784 : ExpressionNode(PlacementNewAdopt)
785 , m_ident(PlacementNewAdopt)
786 {
787 }
788
789 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
790 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
791 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
792 virtual Precedence precedence() const { return PrecUnary; }
793 private:
794 Identifier m_ident;
795 };
796
797 class LocalVarDeleteNode : public DeleteResolveNode {
798 public:
799 LocalVarDeleteNode() KJS_FAST_CALL
800 : DeleteResolveNode(PlacementNewAdopt)
801 {
802 }
803
804 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
805 };
806
807 class DeleteBracketNode : public ExpressionNode {
808 public:
809 DeleteBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL : m_base(base), m_subscript(subscript) {}
810 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
811 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
812 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
813 virtual Precedence precedence() const { return PrecUnary; }
814 private:
815 RefPtr<ExpressionNode> m_base;
816 RefPtr<ExpressionNode> m_subscript;
817 };
818
819 class DeleteDotNode : public ExpressionNode {
820 public:
821 DeleteDotNode(ExpressionNode* base, const Identifier& i) KJS_FAST_CALL : m_base(base), m_ident(i) {}
822 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
823 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
824 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
825 virtual Precedence precedence() const { return PrecUnary; }
826 private:
827 RefPtr<ExpressionNode> m_base;
828 Identifier m_ident;
829 };
830
831 class DeleteValueNode : public ExpressionNode {
832 public:
833 DeleteValueNode(ExpressionNode* e) KJS_FAST_CALL : m_expr(e) {}
834 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
835 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
836 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
837 virtual Precedence precedence() const { return PrecUnary; }
838 private:
839 RefPtr<ExpressionNode> m_expr;
840 };
841
842 class VoidNode : public ExpressionNode {
843 public:
844 VoidNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
845 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
846 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
847 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
848 virtual Precedence precedence() const { return PrecUnary; }
849 private:
850 RefPtr<ExpressionNode> expr;
851 };
852
853 class TypeOfResolveNode : public ExpressionNode {
854 public:
855 TypeOfResolveNode(const Identifier &s) KJS_FAST_CALL
856 : ExpressionNode(StringType), m_ident(s) {}
857
858 TypeOfResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
859 : ExpressionNode(PlacementNewAdopt)
860 , m_ident(PlacementNewAdopt)
861 {
862 m_expectedReturnType = StringType;
863 }
864
865 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
866
867 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
868 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
869 virtual Precedence precedence() const { return PrecUnary; }
870
871 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
872
873 protected:
874 Identifier m_ident;
875 size_t m_index; // Used by LocalTypeOfNode.
876 };
877
878 class LocalVarTypeOfNode : public TypeOfResolveNode {
879 public:
880 LocalVarTypeOfNode(size_t i) KJS_FAST_CALL
881 : TypeOfResolveNode(PlacementNewAdopt)
882 {
883 m_expectedReturnType = StringType;
884 ASSERT(i != missingSymbolMarker());
885 m_index = i;
886 }
887
888 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
889 };
890
891 class TypeOfValueNode : public ExpressionNode {
892 public:
893 TypeOfValueNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(StringType), m_expr(e) {}
894 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
895 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
896 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
897 virtual Precedence precedence() const { return PrecUnary; }
898 private:
899 RefPtr<ExpressionNode> m_expr;
900 };
901
902 class PreIncResolveNode : public PrePostResolveNode {
903 public:
904 PreIncResolveNode(const Identifier &s) KJS_FAST_CALL
905 : PrePostResolveNode(s)
906 {
907 }
908
909 PreIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
910 : PrePostResolveNode(PlacementNewAdopt)
911 {
912 }
913
914 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
915
916 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
917 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
918 virtual Precedence precedence() const { return PrecUnary; }
919 };
920
921 class PreIncLocalVarNode : public PreIncResolveNode {
922 public:
923 PreIncLocalVarNode(size_t i) KJS_FAST_CALL
924 : PreIncResolveNode(PlacementNewAdopt)
925 {
926 ASSERT(i != missingSymbolMarker());
927 m_index = i;
928 }
929
930 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
931 };
932
933 class PreDecResolveNode : public PrePostResolveNode {
934 public:
935 PreDecResolveNode(const Identifier &s) KJS_FAST_CALL
936 : PrePostResolveNode(s)
937 {
938 }
939
940 PreDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
941 : PrePostResolveNode(PlacementNewAdopt)
942 {
943 }
944
945 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
946
947 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
948 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
949 virtual Precedence precedence() const { return PrecUnary; }
950 };
951
952 class PreDecLocalVarNode : public PreDecResolveNode {
953 public:
954 PreDecLocalVarNode(size_t i) KJS_FAST_CALL
955 : PreDecResolveNode(PlacementNewAdopt)
956 {
957 ASSERT(i != missingSymbolMarker());
958 m_index = i;
959 }
960
961 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
962 };
963
964 class PrefixBracketNode : public ExpressionNode {
965 public:
966 PrefixBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : m_base(b), m_subscript(s) {}
967
968 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
969 virtual Precedence precedence() const { return PrecUnary; }
970 protected:
971 RefPtr<ExpressionNode> m_base;
972 RefPtr<ExpressionNode> m_subscript;
973 };
974
975 class PreIncBracketNode : public PrefixBracketNode {
976 public:
977 PreIncBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : PrefixBracketNode(b, s) {}
978 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
979 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
980 };
981
982 class PreDecBracketNode : public PrefixBracketNode {
983 public:
984 PreDecBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : PrefixBracketNode(b, s) {}
985 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
986 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
987 };
988
989 class PrefixDotNode : public ExpressionNode {
990 public:
991 PrefixDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : m_base(b), m_ident(i) {}
992 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
993 virtual Precedence precedence() const { return PrecPostfix; }
994 protected:
995 RefPtr<ExpressionNode> m_base;
996 Identifier m_ident;
997 };
998
999 class PreIncDotNode : public PrefixDotNode {
1000 public:
1001 PreIncDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : PrefixDotNode(b, i) {}
1002 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1003 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1004 };
1005
1006 class PreDecDotNode : public PrefixDotNode {
1007 public:
1008 PreDecDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : PrefixDotNode(b, i) {}
1009 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1010 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1011 };
1012
1013 class PrefixErrorNode : public ExpressionNode {
1014 public:
1015 PrefixErrorNode(ExpressionNode* e, Operator o) KJS_FAST_CALL : m_expr(e), m_oper(o) {}
1016 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1017 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1018 virtual Precedence precedence() const { return PrecUnary; }
1019 private:
1020 RefPtr<ExpressionNode> m_expr;
1021 Operator m_oper;
1022 };
1023
1024 class UnaryPlusNode : public ExpressionNode {
1025 public:
1026 UnaryPlusNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), m_expr(e) {}
1027 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1028 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1029 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1030 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1031 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1032 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1033 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1034 virtual Precedence precedence() const { return PrecUnary; }
1035 private:
1036 RefPtr<ExpressionNode> m_expr;
1037 };
1038
1039 class NegateNode : public ExpressionNode {
1040 public:
1041 NegateNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
1042 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1043 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1044 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1045 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1046 virtual Precedence precedence() const { return PrecUnary; }
1047 private:
1048 RefPtr<ExpressionNode> expr;
1049 };
1050
1051 class BitwiseNotNode : public ExpressionNode {
1052 public:
1053 BitwiseNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
1054 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1055 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1056 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1057 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1058 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1059 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1060 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1061 virtual Precedence precedence() const { return PrecUnary; }
1062 private:
1063 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1064 RefPtr<ExpressionNode> expr;
1065 };
1066
1067 class LogicalNotNode : public ExpressionNode {
1068 public:
1069 LogicalNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(BooleanType), expr(e) {}
1070 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1071 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1072 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1073 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1074 virtual Precedence precedence() const { return PrecUnary; }
1075 private:
1076 RefPtr<ExpressionNode> expr;
1077 };
1078
1079 class MultNode : public ExpressionNode {
1080 public:
1081 MultNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1082 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1083 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1084 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1085 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1086 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1087 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1088 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1089 virtual Precedence precedence() const { return PrecMultiplicitave; }
1090 private:
1091 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1092 RefPtr<ExpressionNode> term1;
1093 RefPtr<ExpressionNode> term2;
1094 };
1095
1096 class DivNode : public ExpressionNode {
1097 public:
1098 DivNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1099 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1100 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1101 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1102 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1103 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1104 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1105 virtual Precedence precedence() const { return PrecMultiplicitave; }
1106 private:
1107 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1108 RefPtr<ExpressionNode> term1;
1109 RefPtr<ExpressionNode> term2;
1110 };
1111
1112 class ModNode : public ExpressionNode {
1113 public:
1114 ModNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1115 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1116 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1117 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1118 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1119 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1120 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1121 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1122 virtual Precedence precedence() const { return PrecMultiplicitave; }
1123 private:
1124 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1125 RefPtr<ExpressionNode> term1;
1126 RefPtr<ExpressionNode> term2;
1127 };
1128
1129 class AddNode : public ExpressionNode {
1130 public:
1131 AddNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
1132 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1133 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1134 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1135 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1136 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1137 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1138 virtual Precedence precedence() const { return PrecAdditive; }
1139 protected:
1140 AddNode(ExpressionNode* t1, ExpressionNode* t2, JSType expectedReturn) KJS_FAST_CALL : ExpressionNode(expectedReturn), term1(t1), term2(t2) {}
1141 RefPtr<ExpressionNode> term1;
1142 RefPtr<ExpressionNode> term2;
1143 private:
1144 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1145 };
1146
1147 class AddNumbersNode : public AddNode {
1148 public:
1149 AddNumbersNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, NumberType) {}
1150 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1151 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1152 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1153 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1154 private:
1155 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*) KJS_FAST_CALL;
1156 };
1157
1158 class AddStringLeftNode : public AddNode {
1159 public:
1160 AddStringLeftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
1161 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1162 };
1163
1164 class AddStringRightNode : public AddNode {
1165 public:
1166 AddStringRightNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
1167 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1168 };
1169
1170 class AddStringsNode : public AddNode {
1171 public:
1172 AddStringsNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
1173 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1174 };
1175
1176 class SubNode : public ExpressionNode {
1177 public:
1178 SubNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1179 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1180 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1181 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1182 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1183 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1184 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1185 virtual Precedence precedence() const { return PrecAdditive; }
1186 private:
1187 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1188 RefPtr<ExpressionNode> term1;
1189 RefPtr<ExpressionNode> term2;
1190 };
1191
1192 class LeftShiftNode : public ExpressionNode {
1193 public:
1194 LeftShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
1195 : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1196 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1197 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1198 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1199 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1200 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1201 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1202 virtual Precedence precedence() const { return PrecShift; }
1203 private:
1204 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1205 RefPtr<ExpressionNode> term1;
1206 RefPtr<ExpressionNode> term2;
1207 };
1208
1209 class RightShiftNode : public ExpressionNode {
1210 public:
1211 RightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
1212 : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1213 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1214 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1215 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1216 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1217 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1218 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1219 virtual Precedence precedence() const { return PrecShift; }
1220 private:
1221 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1222 RefPtr<ExpressionNode> term1;
1223 RefPtr<ExpressionNode> term2;
1224 };
1225
1226 class UnsignedRightShiftNode : public ExpressionNode {
1227 public:
1228 UnsignedRightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
1229 : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1230 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1231 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1232 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1233 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1234 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1235 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1236 virtual Precedence precedence() const { return PrecShift; }
1237 private:
1238 ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(ExecState*);
1239 RefPtr<ExpressionNode> term1;
1240 RefPtr<ExpressionNode> term2;
1241 };
1242
1243 class LessNode : public ExpressionNode {
1244 public:
1245 LessNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1246 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1247 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1248 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1249 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1250 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1251 virtual Precedence precedence() const { return PrecRelational; }
1252 private:
1253 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1254 protected:
1255 RefPtr<ExpressionNode> expr1;
1256 RefPtr<ExpressionNode> expr2;
1257 };
1258
1259 class LessNumbersNode : public LessNode {
1260 public:
1261 LessNumbersNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1262 : LessNode(e1, e2) {}
1263 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1264 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1265 private:
1266 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1267 };
1268
1269 class LessStringsNode : public LessNode {
1270 public:
1271 LessStringsNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1272 : LessNode(e1, e2) {}
1273 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1274 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1275 private:
1276 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1277 };
1278
1279 class GreaterNode : public ExpressionNode {
1280 public:
1281 GreaterNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1282 expr1(e1), expr2(e2) {}
1283 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1284 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1285 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1286 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1287 virtual Precedence precedence() const { return PrecRelational; }
1288 private:
1289 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1290 RefPtr<ExpressionNode> expr1;
1291 RefPtr<ExpressionNode> expr2;
1292 };
1293
1294 class LessEqNode : public ExpressionNode {
1295 public:
1296 LessEqNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1297 expr1(e1), expr2(e2) {}
1298 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1299 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1300 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1301 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1302 virtual Precedence precedence() const { return PrecRelational; }
1303 private:
1304 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1305 RefPtr<ExpressionNode> expr1;
1306 RefPtr<ExpressionNode> expr2;
1307 };
1308
1309 class GreaterEqNode : public ExpressionNode {
1310 public:
1311 GreaterEqNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1312 expr1(e1), expr2(e2) {}
1313 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1314 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1315 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1316 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1317 virtual Precedence precedence() const { return PrecRelational; }
1318 private:
1319 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1320 RefPtr<ExpressionNode> expr1;
1321 RefPtr<ExpressionNode> expr2;
1322 };
1323
1324 class InstanceOfNode : public ExpressionNode {
1325 public:
1326 InstanceOfNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1327 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1328 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1329 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1330 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1331 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1332 virtual Precedence precedence() const { return PrecRelational; }
1333 private:
1334 RefPtr<ExpressionNode> expr1;
1335 RefPtr<ExpressionNode> expr2;
1336 };
1337
1338 class InNode : public ExpressionNode {
1339 public:
1340 InNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1341 expr1(e1), expr2(e2) {}
1342 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1343 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1344 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1345 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1346 virtual Precedence precedence() const { return PrecRelational; }
1347 private:
1348 RefPtr<ExpressionNode> expr1;
1349 RefPtr<ExpressionNode> expr2;
1350 };
1351
1352 class EqualNode : public ExpressionNode {
1353 public:
1354 EqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1355 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1356 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1357 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1358 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1359 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1360 virtual Precedence precedence() const { return PrecEquality; }
1361 private:
1362 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1363 RefPtr<ExpressionNode> expr1;
1364 RefPtr<ExpressionNode> expr2;
1365 };
1366
1367 class NotEqualNode : public ExpressionNode {
1368 public:
1369 NotEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1370 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1371 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1372 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1373 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1374 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1375 virtual Precedence precedence() const { return PrecEquality; }
1376 private:
1377 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1378 RefPtr<ExpressionNode> expr1;
1379 RefPtr<ExpressionNode> expr2;
1380 };
1381
1382 class StrictEqualNode : public ExpressionNode {
1383 public:
1384 StrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1385 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1386 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1387 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1388 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1389 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1390 virtual Precedence precedence() const { return PrecEquality; }
1391 private:
1392 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1393 RefPtr<ExpressionNode> expr1;
1394 RefPtr<ExpressionNode> expr2;
1395 };
1396
1397 class NotStrictEqualNode : public ExpressionNode {
1398 public:
1399 NotStrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1400 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1401 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1402 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1403 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1404 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1405 virtual Precedence precedence() const { return PrecEquality; }
1406 private:
1407 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1408 RefPtr<ExpressionNode> expr1;
1409 RefPtr<ExpressionNode> expr2;
1410 };
1411
1412 class BitAndNode : public ExpressionNode {
1413 public:
1414 BitAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1415 : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
1416 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1417 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1418 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1419 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1420 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1421 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1422 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1423 virtual Precedence precedence() const { return PrecBitwiseAnd; }
1424 private:
1425 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1426 RefPtr<ExpressionNode> expr1;
1427 RefPtr<ExpressionNode> expr2;
1428 };
1429
1430 class BitOrNode : public ExpressionNode {
1431 public:
1432 BitOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1433 : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
1434 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1435 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1436 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1437 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1438 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1439 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1440 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1441 virtual Precedence precedence() const { return PrecBitwiseOr; }
1442 private:
1443 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1444 RefPtr<ExpressionNode> expr1;
1445 RefPtr<ExpressionNode> expr2;
1446 };
1447
1448 class BitXOrNode : public ExpressionNode {
1449 public:
1450 BitXOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1451 : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
1452 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1453 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1454 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1455 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1456 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1457 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1458 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1459 virtual Precedence precedence() const { return PrecBitwiseXor; }
1460 private:
1461 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1462 RefPtr<ExpressionNode> expr1;
1463 RefPtr<ExpressionNode> expr2;
1464 };
1465
1466 /**
1467 * expr1 && expr2, expr1 || expr2
1468 */
1469 class LogicalAndNode : public ExpressionNode {
1470 public:
1471 LogicalAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1472 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1473 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1474 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1475 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1476 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1477 virtual Precedence precedence() const { return PrecLogicalAnd; }
1478 private:
1479 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1480 RefPtr<ExpressionNode> expr1;
1481 RefPtr<ExpressionNode> expr2;
1482 };
1483
1484 class LogicalOrNode : public ExpressionNode {
1485 public:
1486 LogicalOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1487 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1488 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1489 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1490 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1491 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1492 virtual Precedence precedence() const { return PrecLogicalOr; }
1493 private:
1494 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1495 RefPtr<ExpressionNode> expr1;
1496 RefPtr<ExpressionNode> expr2;
1497 };
1498
1499 /**
1500 * The ternary operator, "logical ? expr1 : expr2"
1501 */
1502 class ConditionalNode : public ExpressionNode {
1503 public:
1504 ConditionalNode(ExpressionNode* l, ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1505 logical(l), expr1(e1), expr2(e2) {}
1506 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1507 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1508 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1509 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1510 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1511 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1512 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1513 virtual Precedence precedence() const { return PrecConditional; }
1514 private:
1515 RefPtr<ExpressionNode> logical;
1516 RefPtr<ExpressionNode> expr1;
1517 RefPtr<ExpressionNode> expr2;
1518 };
1519
1520 class ReadModifyResolveNode : public ExpressionNode {
1521 public:
1522 ReadModifyResolveNode(const Identifier &ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL
1523 : m_ident(ident)
1524 , m_oper(oper)
1525 , m_right(right)
1526 {
1527 }
1528
1529 ReadModifyResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1530 : ExpressionNode(PlacementNewAdopt)
1531 , m_ident(PlacementNewAdopt)
1532 , m_right(PlacementNewAdopt)
1533 {
1534 }
1535
1536 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1537 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1538 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1539 virtual Precedence precedence() const { return PrecAssignment; }
1540 protected:
1541 Identifier m_ident;
1542 Operator m_oper;
1543 RefPtr<ExpressionNode> m_right;
1544 size_t m_index; // Used by ReadModifyLocalVarNode.
1545 };
1546
1547 class ReadModifyLocalVarNode : public ReadModifyResolveNode {
1548 public:
1549 ReadModifyLocalVarNode(size_t i) KJS_FAST_CALL
1550 : ReadModifyResolveNode(PlacementNewAdopt)
1551 {
1552 ASSERT(i != missingSymbolMarker());
1553 m_index = i;
1554 }
1555
1556 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1557 };
1558
1559 class AssignResolveNode : public ExpressionNode {
1560 public:
1561 AssignResolveNode(const Identifier &ident, ExpressionNode* right) KJS_FAST_CALL
1562 : m_ident(ident)
1563 , m_right(right)
1564 {
1565 }
1566
1567 AssignResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1568 : ExpressionNode(PlacementNewAdopt)
1569 , m_ident(PlacementNewAdopt)
1570 , m_right(PlacementNewAdopt)
1571 {
1572 }
1573
1574 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1575 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1576 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1577 virtual Precedence precedence() const { return PrecAssignment; }
1578 protected:
1579 Identifier m_ident;
1580 RefPtr<ExpressionNode> m_right;
1581 size_t m_index; // Used by ReadModifyLocalVarNode.
1582 };
1583
1584 class AssignLocalVarNode : public AssignResolveNode {
1585 public:
1586 AssignLocalVarNode(size_t i) KJS_FAST_CALL
1587 : AssignResolveNode(PlacementNewAdopt)
1588 {
1589 ASSERT(i != missingSymbolMarker());
1590 m_index = i;
1591 }
1592
1593 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1594 };
1595
1596 class ReadModifyBracketNode : public ExpressionNode {
1597 public:
1598 ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right) KJS_FAST_CALL
1599 : m_base(base), m_subscript(subscript), m_oper(oper), m_right(right) {}
1600 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1601 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1602 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1603 virtual Precedence precedence() const { return PrecAssignment; }
1604 protected:
1605 RefPtr<ExpressionNode> m_base;
1606 RefPtr<ExpressionNode> m_subscript;
1607 Operator m_oper;
1608 RefPtr<ExpressionNode> m_right;
1609 };
1610
1611 class AssignBracketNode : public ExpressionNode {
1612 public:
1613 AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right) KJS_FAST_CALL
1614 : m_base(base), m_subscript(subscript), m_right(right) {}
1615 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1616 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1617 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1618 virtual Precedence precedence() const { return PrecAssignment; }
1619 protected:
1620 RefPtr<ExpressionNode> m_base;
1621 RefPtr<ExpressionNode> m_subscript;
1622 RefPtr<ExpressionNode> m_right;
1623 };
1624
1625 class AssignDotNode : public ExpressionNode {
1626 public:
1627 AssignDotNode(ExpressionNode* base, const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL
1628 : m_base(base), m_ident(ident), m_right(right) {}
1629 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1630 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1631 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1632 virtual Precedence precedence() const { return PrecAssignment; }
1633 protected:
1634 RefPtr<ExpressionNode> m_base;
1635 Identifier m_ident;
1636 RefPtr<ExpressionNode> m_right;
1637 };
1638
1639 class ReadModifyDotNode : public ExpressionNode {
1640 public:
1641 ReadModifyDotNode(ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL
1642 : m_base(base), m_ident(ident), m_oper(oper), m_right(right) {}
1643 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1644 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1645 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1646 virtual Precedence precedence() const { return PrecAssignment; }
1647 protected:
1648 RefPtr<ExpressionNode> m_base;
1649 Identifier m_ident;
1650 Operator m_oper;
1651 RefPtr<ExpressionNode> m_right;
1652 };
1653
1654 class AssignErrorNode : public ExpressionNode {
1655 public:
1656 AssignErrorNode(ExpressionNode* left, Operator oper, ExpressionNode* right) KJS_FAST_CALL
1657 : m_left(left), m_oper(oper), m_right(right) {}
1658 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1659 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1660 virtual Precedence precedence() const { return PrecAssignment; }
1661 protected:
1662 RefPtr<ExpressionNode> m_left;
1663 Operator m_oper;
1664 RefPtr<ExpressionNode> m_right;
1665 };
1666
1667 class CommaNode : public ExpressionNode {
1668 public:
1669 CommaNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL : expr1(e1), expr2(e2)
1670 {
1671 e1->optimizeForUnnecessaryResult();
1672 }
1673 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1674 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1675 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1676 virtual Precedence precedence() const { return PrecExpression; }
1677 private:
1678 RefPtr<ExpressionNode> expr1;
1679 RefPtr<ExpressionNode> expr2;
1680 };
1681
1682 class ConstDeclNode : public ExpressionNode {
1683 public:
1684 ConstDeclNode(const Identifier& id, ExpressionNode* in) KJS_FAST_CALL;
1685 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1686 virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1687 void evaluateSingle(ExecState*) KJS_FAST_CALL;
1688 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1689 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1690 PassRefPtr<ConstDeclNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1691
1692 Identifier ident;
1693 ListRefPtr<ConstDeclNode> next;
1694 RefPtr<ExpressionNode> init;
1695 private:
1696 void handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL NEVER_INLINE;
1697 };
1698
1699 class ConstStatementNode : public StatementNode {
1700 public:
1701 ConstStatementNode(ConstDeclNode* l) KJS_FAST_CALL : next(l) { }
1702 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1703 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1704 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1705 private:
1706 RefPtr<ConstDeclNode> next;
1707 };
1708
1709 typedef Vector<RefPtr<StatementNode> > StatementVector;
1710
1711 class SourceElements : public ParserRefCounted {
1712 public:
1713 void append(PassRefPtr<StatementNode>);
1714 void releaseContentsIntoVector(StatementVector& destination)
1715 {
1716 ASSERT(destination.isEmpty());
1717 m_statements.swap(destination);
1718 }
1719 private:
1720 StatementVector m_statements;
1721 };
1722
1723 class BlockNode : public StatementNode {
1724 public:
1725 BlockNode(SourceElements* children) KJS_FAST_CALL;
1726 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1727 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1728 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1729 protected:
1730 StatementVector m_children;
1731 };
1732
1733 class EmptyStatementNode : public StatementNode {
1734 public:
1735 EmptyStatementNode() KJS_FAST_CALL { } // debug
1736 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1737 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1738 virtual bool isEmptyStatement() const KJS_FAST_CALL { return true; }
1739 };
1740
1741 class ExprStatementNode : public StatementNode {
1742 public:
1743 ExprStatementNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
1744 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1745 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1746 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1747 private:
1748 RefPtr<ExpressionNode> expr;
1749 };
1750
1751 class VarStatementNode : public StatementNode {
1752 public:
1753 VarStatementNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
1754 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1755 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1756 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1757 private:
1758 RefPtr<ExpressionNode> expr;
1759 };
1760
1761 class IfNode : public StatementNode {
1762 public:
1763 IfNode(ExpressionNode* e, StatementNode *s) KJS_FAST_CALL
1764 : m_condition(e), m_ifBlock(s) { }
1765 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1766 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1767 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1768 protected:
1769 RefPtr<ExpressionNode> m_condition;
1770 RefPtr<StatementNode> m_ifBlock;
1771 };
1772
1773 class IfElseNode : public IfNode {
1774 public:
1775 IfElseNode(ExpressionNode* e, StatementNode* ifBlock, StatementNode* elseBlock) KJS_FAST_CALL
1776 : IfNode(e, ifBlock), m_elseBlock(elseBlock) { }
1777 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1778 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1779 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1780 private:
1781 RefPtr<StatementNode> m_elseBlock;
1782 };
1783
1784 class DoWhileNode : public StatementNode {
1785 public:
1786 DoWhileNode(StatementNode *s, ExpressionNode* e) KJS_FAST_CALL : statement(s), expr(e) { }
1787 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1788 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1789 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1790 private:
1791 RefPtr<StatementNode> statement;
1792 RefPtr<ExpressionNode> expr;
1793 };
1794
1795 class WhileNode : public StatementNode {
1796 public:
1797 WhileNode(ExpressionNode* e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { }
1798 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1799 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1800 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1801 private:
1802 RefPtr<ExpressionNode> expr;
1803 RefPtr<StatementNode> statement;
1804 };
1805
1806 class ForNode : public StatementNode {
1807 public:
1808 ForNode(ExpressionNode* e1, ExpressionNode* e2, ExpressionNode* e3, StatementNode* s, bool e1WasVarDecl) KJS_FAST_CALL
1809 : expr1(e1 ? e1 : new PlaceholderTrueNode)
1810 , expr2(e2 ? e2 : new PlaceholderTrueNode)
1811 , expr3(e3 ? e3 : new PlaceholderTrueNode)
1812 , statement(s)
1813 , expr1WasVarDecl(e1 && e1WasVarDecl)
1814 {
1815 ASSERT(expr1);
1816 ASSERT(expr2);
1817 ASSERT(expr3);
1818 ASSERT(statement);
1819
1820 expr1->optimizeForUnnecessaryResult();
1821 expr3->optimizeForUnnecessaryResult();
1822 }
1823
1824 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1825 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1826 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1827 private:
1828 RefPtr<ExpressionNode> expr1;
1829 RefPtr<ExpressionNode> expr2;
1830 RefPtr<ExpressionNode> expr3;
1831 RefPtr<StatementNode> statement;
1832 bool expr1WasVarDecl;
1833 };
1834
1835 class ForInNode : public StatementNode {
1836 public:
1837 ForInNode(ExpressionNode* l, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
1838 ForInNode(const Identifier &i, ExpressionNode *in, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
1839 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1840 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1841 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1842 private:
1843 Identifier ident;
1844 RefPtr<ExpressionNode> init;
1845 RefPtr<ExpressionNode> lexpr;
1846 RefPtr<ExpressionNode> expr;
1847 RefPtr<StatementNode> statement;
1848 bool identIsVarDecl;
1849 };
1850
1851 class ContinueNode : public StatementNode {
1852 public:
1853 ContinueNode() KJS_FAST_CALL { }
1854 ContinueNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1855 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1856 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1857 private:
1858 Identifier ident;
1859 };
1860
1861 class BreakNode : public StatementNode {
1862 public:
1863 BreakNode() KJS_FAST_CALL { }
1864 BreakNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1865 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1866 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1867 private:
1868 Identifier ident;
1869 };
1870
1871 class ReturnNode : public StatementNode {
1872 public:
1873 ReturnNode(ExpressionNode* v) KJS_FAST_CALL : value(v) {}
1874 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1875 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1876 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1877 private:
1878 RefPtr<ExpressionNode> value;
1879 };
1880
1881 class WithNode : public StatementNode {
1882 public:
1883 WithNode(ExpressionNode* e, StatementNode* s) KJS_FAST_CALL : expr(e), statement(s) { }
1884 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1885 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1886 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1887 private:
1888 RefPtr<ExpressionNode> expr;
1889 RefPtr<StatementNode> statement;
1890 };
1891
1892 class LabelNode : public StatementNode {
1893 public:
1894 LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { }
1895 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1896 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1897 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1898 private:
1899 Identifier label;
1900 RefPtr<StatementNode> statement;
1901 };
1902
1903 class ThrowNode : public StatementNode {
1904 public:
1905 ThrowNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
1906 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1907 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1908 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1909 private:
1910 RefPtr<ExpressionNode> expr;
1911 };
1912
1913 class TryNode : public StatementNode {
1914 public:
1915 TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f) KJS_FAST_CALL
1916 : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { }
1917 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1918 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1919 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1920 private:
1921 RefPtr<StatementNode> tryBlock;
1922 Identifier exceptionIdent;
1923 RefPtr<StatementNode> catchBlock;
1924 RefPtr<StatementNode> finallyBlock;
1925 };
1926
1927 class ParameterNode : public Node {
1928 public:
1929 ParameterNode(const Identifier& i) KJS_FAST_CALL : id(i) { }
1930 ParameterNode(ParameterNode* l, const Identifier& i) KJS_FAST_CALL
1931 : id(i) { l->next = this; }
1932 Identifier ident() KJS_FAST_CALL { return id; }
1933 ParameterNode *nextParam() KJS_FAST_CALL { return next.get(); }
1934 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1935 PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1936 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1937 private:
1938 friend class FuncDeclNode;
1939 friend class FuncExprNode;
1940 Identifier id;
1941 ListRefPtr<ParameterNode> next;
1942 };
1943
1944 class ScopeNode : public BlockNode {
1945 public:
1946 ScopeNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
1947
1948 int sourceId() const KJS_FAST_CALL { return m_sourceId; }
1949 const UString& sourceURL() const KJS_FAST_CALL { return m_sourceURL; }
1950 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1951
1952 protected:
1953 void optimizeVariableAccess(ExecState*) KJS_FAST_CALL;
1954
1955 DeclarationStacks::VarStack m_varStack;
1956 DeclarationStacks::FunctionStack m_functionStack;
1957
1958 private:
1959 UString m_sourceURL;
1960 int m_sourceId;
1961 };
1962
1963 class ProgramNode : public ScopeNode {
1964 public:
1965 static ProgramNode* create(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
1966 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1967
1968 private:
1969 ProgramNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
1970 void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
1971 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
1972
1973 Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.)
1974 Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.)
1975 };
1976
1977 class EvalNode : public ScopeNode {
1978 public:
1979 static EvalNode* create(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
1980 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1981
1982 private:
1983 EvalNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
1984 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
1985 };
1986
1987 class FunctionBodyNode : public ScopeNode {
1988 public:
1989 static FunctionBodyNode* create(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
1990
1991 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
1992
1993 SymbolTable& symbolTable() KJS_FAST_CALL { return m_symbolTable; }
1994
1995 Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
1996 UString paramString() const KJS_FAST_CALL;
1997
1998 protected:
1999 FunctionBodyNode(SourceElements*, DeclarationStacks::VarStack*, DeclarationStacks::FunctionStack*) KJS_FAST_CALL;
2000
2001 private:
2002 void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
2003 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
2004
2005 bool m_initialized;
2006 Vector<Identifier> m_parameters;
2007 SymbolTable m_symbolTable;
2008 };
2009
2010 class FuncExprNode : public ExpressionNode {
2011 public:
2012 FuncExprNode(const Identifier& i, FunctionBodyNode* b, ParameterNode* p = 0) KJS_FAST_CALL
2013 : ident(i), param(p), body(b) { addParams(); }
2014 virtual JSValue *evaluate(ExecState*) KJS_FAST_CALL;
2015 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2016 virtual Precedence precedence() const { return PrecMember; }
2017 virtual bool needsParensIfLeftmost() const { return true; }
2018 private:
2019 void addParams() KJS_FAST_CALL;
2020 // Used for streamTo
2021 friend class PropertyNode;
2022 Identifier ident;
2023 RefPtr<ParameterNode> param;
2024 RefPtr<FunctionBodyNode> body;
2025 };
2026
2027 class FuncDeclNode : public StatementNode {
2028 public:
2029 FuncDeclNode(const Identifier& i, FunctionBodyNode* b) KJS_FAST_CALL
2030 : ident(i), body(b) { addParams(); }
2031 FuncDeclNode(const Identifier& i, ParameterNode* p, FunctionBodyNode* b) KJS_FAST_CALL
2032 : ident(i), param(p), body(b) { addParams(); }
2033 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2034 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2035 ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
2036 Identifier ident;
2037 private:
2038 void addParams() KJS_FAST_CALL;
2039 RefPtr<ParameterNode> param;
2040 RefPtr<FunctionBodyNode> body;
2041 };
2042
2043 class CaseClauseNode : public Node {
2044 public:
2045 CaseClauseNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
2046 CaseClauseNode(ExpressionNode* e, SourceElements* children) KJS_FAST_CALL
2047 : expr(e) { if (children) children->releaseContentsIntoVector(m_children); }
2048 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
2049 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2050 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2051
2052 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2053 JSValue* executeStatements(ExecState*) KJS_FAST_CALL;
2054
2055 private:
2056 RefPtr<ExpressionNode> expr;
2057 StatementVector m_children;
2058 };
2059
2060 class ClauseListNode : public Node {
2061 public:
2062 ClauseListNode(CaseClauseNode* c) KJS_FAST_CALL : clause(c) { }
2063 ClauseListNode(ClauseListNode* n, CaseClauseNode* c) KJS_FAST_CALL
2064 : clause(c) { n->next = this; }
2065 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
2066 CaseClauseNode* getClause() const KJS_FAST_CALL { return clause.get(); }
2067 ClauseListNode* getNext() const KJS_FAST_CALL { return next.get(); }
2068 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2069 PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
2070 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2071 private:
2072 friend class CaseBlockNode;
2073 RefPtr<CaseClauseNode> clause;
2074 ListRefPtr<ClauseListNode> next;
2075 };
2076
2077 class CaseBlockNode : public Node {
2078 public:
2079 CaseBlockNode(ClauseListNode* l1, CaseClauseNode* d, ClauseListNode* l2) KJS_FAST_CALL;
2080 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
2081 JSValue* executeBlock(ExecState*, JSValue *input) KJS_FAST_CALL;
2082 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2083 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2084 private:
2085 RefPtr<ClauseListNode> list1;
2086 RefPtr<CaseClauseNode> def;
2087 RefPtr<ClauseListNode> list2;
2088 };
2089
2090 class SwitchNode : public StatementNode {
2091 public:
2092 SwitchNode(ExpressionNode* e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { }
2093 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
2094 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2095 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2096 private:
2097 RefPtr<ExpressionNode> expr;
2098 RefPtr<CaseBlockNode> block;
2099 };
2100
2101 class BreakpointCheckStatement : public StatementNode {
2102 public:
2103 BreakpointCheckStatement(PassRefPtr<StatementNode>) KJS_FAST_CALL;
2104 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2105 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2106 virtual void optimizeVariableAccess(SymbolTable&, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
2107 private:
2108 RefPtr<StatementNode> m_statement;
2109 };
2110
2111 struct ElementList {
2112 ElementNode* head;
2113 ElementNode* tail;
2114 };
2115
2116 struct PropertyList {
2117 PropertyListNode* head;
2118 PropertyListNode* tail;
2119 };
2120
2121 struct ArgumentList {
2122 ArgumentListNode* head;
2123 ArgumentListNode* tail;
2124 };
2125
2126 struct ConstDeclList {
2127 ConstDeclNode* head;
2128 ConstDeclNode* tail;
2129 };
2130
2131 struct ParameterList {
2132 ParameterNode* head;
2133 ParameterNode* tail;
2134 };
2135
2136 struct ClauseList {
2137 ClauseListNode* head;
2138 ClauseListNode* tail;
2139 };
2140
2141} // namespace
2142
2143#endif
Note: See TracBrowser for help on using the repository browser.