2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6 * Copyright (C) 2007 Maks Orlovich
7 * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
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.
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.
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.
31 #include "SymbolTable.h"
32 #include <wtf/ListRefPtr.h>
33 #include <wtf/OwnPtr.h>
34 #include <wtf/Vector.h>
36 #if PLATFORM(X86) && COMPILER(GCC)
37 #define KJS_FAST_CALL __attribute__((regparm(3)))
43 #define KJS_NO_INLINE __attribute__((noinline))
51 class PropertyListNode;
94 struct DeclarationStacks {
95 typedef Vector<Node*, 16> NodeStack;
96 typedef Vector<VarDeclNode*, 16> VarStack;
97 typedef Vector<FuncDeclNode*, 16> FunctionStack;
99 DeclarationStacks(ExecState* e, NodeStack& n, VarStack& v, FunctionStack& f)
108 NodeStack& nodeStack;
110 FunctionStack& functionStack;
113 class Node : Noncopyable {
115 Node() KJS_FAST_CALL;
116 Node(PlacementNewAdoptType) KJS_FAST_CALL { }
119 UString toString() const KJS_FAST_CALL;
120 int lineNo() const KJS_FAST_CALL { return m_line; }
121 void ref() KJS_FAST_CALL;
122 void deref() KJS_FAST_CALL;
123 unsigned refcount() KJS_FAST_CALL;
124 static void clearNewNodes() KJS_FAST_CALL;
127 virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
128 virtual Precedence precedence() const = 0;
130 // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
131 bool mayHaveDeclarations() const { return m_mayHaveDeclarations; }
132 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL { ASSERT_NOT_REACHED(); }
134 // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
135 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL { }
138 Node(JSType) KJS_FAST_CALL; // used by ExpressionNode
139 Completion createErrorCompletion(ExecState *, ErrorType, const char *msg) KJS_FAST_CALL;
140 Completion createErrorCompletion(ExecState *, ErrorType, const char *msg, const Identifier &) KJS_FAST_CALL;
142 JSValue* throwError(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
143 JSValue* throwError(ExecState*, ErrorType, const char* msg, const char*) KJS_FAST_CALL;
144 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*) KJS_FAST_CALL;
145 JSValue* throwError(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
146 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, const Identifier&) KJS_FAST_CALL;
147 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, Node*) KJS_FAST_CALL;
148 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, const Identifier&) KJS_FAST_CALL;
150 JSValue* throwUndefinedVariableError(ExecState*, const Identifier&) KJS_FAST_CALL;
152 void handleException(ExecState*) KJS_FAST_CALL;
153 void handleException(ExecState*, JSValue*) KJS_FAST_CALL;
155 Completion rethrowException(ExecState*) KJS_FAST_CALL;
158 bool m_mayHaveDeclarations : 1;
159 unsigned m_expectedReturnType : 3; // JSType
162 class ExpressionNode : public Node {
164 ExpressionNode() KJS_FAST_CALL : Node() {}
165 ExpressionNode(JSType expectedReturn) KJS_FAST_CALL
166 : Node(expectedReturn) {}
168 // Special constructor for cases where we overwrite an object in place.
169 ExpressionNode(PlacementNewAdoptType) KJS_FAST_CALL
170 : Node(PlacementNewAdopt) {}
172 virtual bool isNumber() const KJS_FAST_CALL { return false; }
173 virtual bool isLocation() const KJS_FAST_CALL { return false; }
174 virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
175 virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
176 virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
178 JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
180 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
181 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
182 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
184 // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance
185 virtual void optimizeForUnnecessaryResult() { }
188 class StatementNode : public Node {
190 StatementNode() KJS_FAST_CALL;
191 void setLoc(int line0, int line1) KJS_FAST_CALL;
192 int firstLine() const KJS_FAST_CALL { return lineNo(); }
193 int lastLine() const KJS_FAST_CALL { return m_lastLine; }
194 bool hitStatement(ExecState*) KJS_FAST_CALL;
195 virtual Completion execute(ExecState *exec) KJS_FAST_CALL = 0;
196 void pushLabel(const Identifier &id) KJS_FAST_CALL { ls.push(id); }
197 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
204 class NullNode : public ExpressionNode {
206 NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {}
207 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
208 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
209 virtual Precedence precedence() const { return PrecPrimary; }
212 class FalseNode : public ExpressionNode {
214 FalseNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {}
215 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
216 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; }
217 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
218 virtual Precedence precedence() const { return PrecPrimary; }
221 class TrueNode : public ExpressionNode {
223 TrueNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {}
224 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
225 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; }
226 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
227 virtual Precedence precedence() const { return PrecPrimary; }
230 class NumberNode : public ExpressionNode {
232 NumberNode(double v) KJS_FAST_CALL : ExpressionNode(NumberType), m_double(v) {}
233 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
234 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
235 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
236 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
237 virtual Precedence precedence() const { return PrecPrimary; }
239 virtual bool isNumber() const KJS_FAST_CALL { return true; }
240 double value() const KJS_FAST_CALL { return m_double; }
241 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; }
247 class ImmediateNumberNode : public NumberNode {
249 ImmediateNumberNode(JSValue* v, double d) KJS_FAST_CALL : NumberNode(d), m_value(v) { ASSERT(v == JSImmediate::from(d)); }
250 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
252 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
254 JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr
257 class StringNode : public ExpressionNode {
259 StringNode(const UString* v) KJS_FAST_CALL : ExpressionNode(StringType), m_value(*v) {}
260 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
261 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
262 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
263 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
264 virtual Precedence precedence() const { return PrecPrimary; }
270 class RegExpNode : public ExpressionNode {
272 RegExpNode(const UString& pattern, const UString& flags) KJS_FAST_CALL
273 : m_pattern(pattern), m_flags(flags) { }
274 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
275 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
276 virtual Precedence precedence() const { return PrecPrimary; }
282 class ThisNode : public ExpressionNode {
284 ThisNode() KJS_FAST_CALL {}
285 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
286 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
287 virtual Precedence precedence() const { return PrecPrimary; }
290 class ResolveNode : public ExpressionNode {
292 ResolveNode(const Identifier &s) KJS_FAST_CALL
297 // Special constructor for cases where we overwrite an object in place.
298 ResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
299 : ExpressionNode(PlacementNewAdopt)
300 , ident(PlacementNewAdopt)
304 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
306 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
307 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
308 virtual Precedence precedence() const { return PrecPrimary; }
310 virtual bool isLocation() const KJS_FAST_CALL { return true; }
311 virtual bool isResolveNode() const KJS_FAST_CALL { return true; }
312 const Identifier& identifier() const KJS_FAST_CALL { return ident; }
316 size_t index; // Used by LocalVarAccessNode.
319 class LocalVarAccessNode : public ResolveNode {
321 // Overwrites a ResolveNode in place.
322 LocalVarAccessNode(size_t i) KJS_FAST_CALL
323 : ResolveNode(PlacementNewAdopt)
325 ASSERT(i != missingSymbolMarker());
328 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
329 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
330 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
332 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
335 class ElementNode : public Node {
337 ElementNode(int e, ExpressionNode* n) KJS_FAST_CALL : elision(e), node(n) { }
338 ElementNode(ElementNode* l, int e, ExpressionNode* n) KJS_FAST_CALL
339 : elision(e), node(n) { l->next = this; }
340 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
341 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
342 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
344 PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return next.release(); }
346 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
349 friend class ArrayNode;
350 ListRefPtr<ElementNode> next;
352 RefPtr<ExpressionNode> node;
355 class ArrayNode : public ExpressionNode {
357 ArrayNode(int e) KJS_FAST_CALL : elision(e), opt(true) { }
358 ArrayNode(ElementNode* ele) KJS_FAST_CALL
359 : element(ele), elision(0), opt(false) { }
360 ArrayNode(int eli, ElementNode* ele) KJS_FAST_CALL
361 : element(ele), elision(eli), opt(true) { }
362 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
363 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
364 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
365 virtual Precedence precedence() const { return PrecPrimary; }
367 RefPtr<ElementNode> element;
372 class PropertyNode : public Node {
374 enum Type { Constant, Getter, Setter };
375 PropertyNode(const Identifier& n, ExpressionNode* a, Type t) KJS_FAST_CALL
376 : m_name(n), assign(a), type(t) { }
377 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
378 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
379 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
381 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
382 const Identifier& name() const { return m_name; }
385 friend class PropertyListNode;
387 RefPtr<ExpressionNode> assign;
391 class PropertyListNode : public Node {
393 PropertyListNode(PropertyNode* n) KJS_FAST_CALL
395 PropertyListNode(PropertyNode* n, PropertyListNode* l) KJS_FAST_CALL
396 : node(n) { l->next = this; }
397 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
398 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
399 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
401 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
402 PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
405 friend class ObjectLiteralNode;
406 RefPtr<PropertyNode> node;
407 ListRefPtr<PropertyListNode> next;
410 class ObjectLiteralNode : public ExpressionNode {
412 ObjectLiteralNode() KJS_FAST_CALL { }
413 ObjectLiteralNode(PropertyListNode* l) KJS_FAST_CALL : list(l) { }
414 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
415 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
416 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
417 virtual Precedence precedence() const { return PrecPrimary; }
419 RefPtr<PropertyListNode> list;
422 class BracketAccessorNode : public ExpressionNode {
424 BracketAccessorNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
425 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
426 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
427 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
428 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
429 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
430 virtual Precedence precedence() const { return PrecMember; }
432 virtual bool isLocation() const KJS_FAST_CALL { return true; }
433 virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return true; }
434 ExpressionNode* base() KJS_FAST_CALL { return expr1.get(); }
435 ExpressionNode* subscript() KJS_FAST_CALL { return expr2.get(); }
438 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
439 RefPtr<ExpressionNode> expr1;
440 RefPtr<ExpressionNode> expr2;
443 class DotAccessorNode : public ExpressionNode {
445 DotAccessorNode(ExpressionNode* e, const Identifier& s) KJS_FAST_CALL : expr(e), ident(s) { }
446 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
447 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
448 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
449 virtual Precedence precedence() const { return PrecMember; }
451 virtual bool isLocation() const KJS_FAST_CALL { return true; }
452 virtual bool isDotAccessorNode() const KJS_FAST_CALL { return true; }
453 ExpressionNode* base() const KJS_FAST_CALL { return expr.get(); }
454 const Identifier& identifier() const KJS_FAST_CALL { return ident; }
457 RefPtr<ExpressionNode> expr;
461 class ArgumentListNode : public Node {
463 ArgumentListNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
464 ArgumentListNode(ArgumentListNode* l, ExpressionNode* e) KJS_FAST_CALL
465 : expr(e) { l->next = this; }
466 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
467 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
468 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
470 void evaluateList(ExecState*, List&) KJS_FAST_CALL;
471 PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
474 friend class ArgumentsNode;
475 ListRefPtr<ArgumentListNode> next;
476 RefPtr<ExpressionNode> expr;
479 class ArgumentsNode : public Node {
481 ArgumentsNode() KJS_FAST_CALL { }
482 ArgumentsNode(ArgumentListNode* l) KJS_FAST_CALL
484 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
485 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
486 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
488 void evaluateList(ExecState* exec, List& list) KJS_FAST_CALL { if (listNode) listNode->evaluateList(exec, list); }
491 RefPtr<ArgumentListNode> listNode;
494 class NewExprNode : public ExpressionNode {
496 NewExprNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
497 NewExprNode(ExpressionNode* e, ArgumentsNode* a) KJS_FAST_CALL : expr(e), args(a) {}
498 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
499 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
500 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
501 virtual Precedence precedence() const { return PrecLeftHandSide; }
503 RefPtr<ExpressionNode> expr;
504 RefPtr<ArgumentsNode> args;
507 class FunctionCallValueNode : public ExpressionNode {
509 FunctionCallValueNode(ExpressionNode* e, ArgumentsNode* a) KJS_FAST_CALL : expr(e), args(a) {}
510 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
511 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
512 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
513 virtual Precedence precedence() const { return PrecCall; }
515 RefPtr<ExpressionNode> expr;
516 RefPtr<ArgumentsNode> args;
519 class FunctionCallResolveNode : public ExpressionNode {
521 FunctionCallResolveNode(const Identifier& i, ArgumentsNode* a) KJS_FAST_CALL
527 FunctionCallResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
528 : ExpressionNode(PlacementNewAdopt)
529 , ident(PlacementNewAdopt)
530 , args(PlacementNewAdopt)
534 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
535 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
536 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
537 virtual Precedence precedence() const { return PrecCall; }
541 RefPtr<ArgumentsNode> args;
542 size_t index; // Used by LocalVarFunctionCallNode.
545 class LocalVarFunctionCallNode : public FunctionCallResolveNode {
547 LocalVarFunctionCallNode(size_t i) KJS_FAST_CALL
548 : FunctionCallResolveNode(PlacementNewAdopt)
550 ASSERT(i != missingSymbolMarker());
554 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
557 class FunctionCallBracketNode : public ExpressionNode {
559 FunctionCallBracketNode(ExpressionNode* b, ExpressionNode* s, ArgumentsNode* a) KJS_FAST_CALL : base(b), subscript(s), args(a) {}
560 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
561 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
562 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
563 virtual Precedence precedence() const { return PrecCall; }
565 RefPtr<ExpressionNode> base;
566 RefPtr<ExpressionNode> subscript;
567 RefPtr<ArgumentsNode> args;
570 class FunctionCallDotNode : public ExpressionNode {
572 FunctionCallDotNode(ExpressionNode* b, const Identifier& i, ArgumentsNode* a) KJS_FAST_CALL : base(b), ident(i), args(a) {}
573 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
574 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
575 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
576 virtual Precedence precedence() const { return PrecCall; }
578 RefPtr<ExpressionNode> base;
580 RefPtr<ArgumentsNode> args;
583 class PrePostResolveNode : public ExpressionNode {
585 PrePostResolveNode(const Identifier& i) KJS_FAST_CALL : ExpressionNode(NumberType), m_ident(i) {}
587 PrePostResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
588 : ExpressionNode(PlacementNewAdopt)
589 , m_ident(PlacementNewAdopt)
595 size_t m_index; // Used by LocalVarPostfixNode.
598 class PostIncResolveNode : public PrePostResolveNode {
600 PostIncResolveNode(const Identifier& i) KJS_FAST_CALL : PrePostResolveNode(i) {}
602 PostIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
603 : PrePostResolveNode(PlacementNewAdopt)
607 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
608 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
609 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
610 virtual Precedence precedence() const { return PrecPostfix; }
611 virtual void optimizeForUnnecessaryResult();
615 class PostIncLocalVarNode : public PostIncResolveNode {
617 PostIncLocalVarNode(size_t i) KJS_FAST_CALL
618 : PostIncResolveNode(PlacementNewAdopt)
620 ASSERT(i != missingSymbolMarker());
624 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
625 virtual void optimizeForUnnecessaryResult();
628 class PostDecResolveNode : public PrePostResolveNode {
630 PostDecResolveNode(const Identifier& i) KJS_FAST_CALL : PrePostResolveNode(i) {}
632 PostDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
633 : PrePostResolveNode(PlacementNewAdopt)
637 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
638 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
639 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
640 virtual Precedence precedence() const { return PrecPostfix; }
641 virtual void optimizeForUnnecessaryResult();
644 class PostDecLocalVarNode : public PostDecResolveNode {
646 PostDecLocalVarNode(size_t i) KJS_FAST_CALL
647 : PostDecResolveNode(PlacementNewAdopt)
649 ASSERT(i != missingSymbolMarker());
653 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
654 virtual void optimizeForUnnecessaryResult();
657 class PostfixBracketNode : public ExpressionNode {
659 PostfixBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : m_base(b), m_subscript(s) {}
660 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
661 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
662 virtual Precedence precedence() const { return PrecPostfix; }
664 virtual bool isIncrement() const = 0;
665 RefPtr<ExpressionNode> m_base;
666 RefPtr<ExpressionNode> m_subscript;
669 class PostIncBracketNode : public PostfixBracketNode {
671 PostIncBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : PostfixBracketNode(b, s) {}
672 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
674 virtual bool isIncrement() const { return true; }
677 class PostDecBracketNode : public PostfixBracketNode {
679 PostDecBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : PostfixBracketNode(b, s) {}
680 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
682 virtual bool isIncrement() const { return false; }
685 class PostfixDotNode : public ExpressionNode {
687 PostfixDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : m_base(b), m_ident(i) {}
688 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
689 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
690 virtual Precedence precedence() const { return PrecPostfix; }
692 virtual bool isIncrement() const = 0;
693 RefPtr<ExpressionNode> m_base;
697 class PostIncDotNode : public PostfixDotNode {
699 PostIncDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : PostfixDotNode(b, i) {}
700 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
702 virtual bool isIncrement() const { return true; }
705 class PostDecDotNode : public PostfixDotNode {
707 PostDecDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : PostfixDotNode(b, i) {}
708 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
710 virtual bool isIncrement() const { return false; }
713 class PostfixErrorNode : public ExpressionNode {
715 PostfixErrorNode(ExpressionNode* e, Operator o) KJS_FAST_CALL : m_expr(e), m_oper(o) {}
716 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
717 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
718 virtual Precedence precedence() const { return PrecPostfix; }
720 RefPtr<ExpressionNode> m_expr;
724 class DeleteResolveNode : public ExpressionNode {
726 DeleteResolveNode(const Identifier& i) KJS_FAST_CALL : m_ident(i) {}
727 DeleteResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
728 : ExpressionNode(PlacementNewAdopt)
729 , m_ident(PlacementNewAdopt)
733 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
734 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
735 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
736 virtual Precedence precedence() const { return PrecUnary; }
741 class LocalVarDeleteNode : public DeleteResolveNode {
743 LocalVarDeleteNode() KJS_FAST_CALL
744 : DeleteResolveNode(PlacementNewAdopt)
748 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
751 class DeleteBracketNode : public ExpressionNode {
753 DeleteBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL : m_base(base), m_subscript(subscript) {}
754 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
755 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
756 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
757 virtual Precedence precedence() const { return PrecUnary; }
759 RefPtr<ExpressionNode> m_base;
760 RefPtr<ExpressionNode> m_subscript;
763 class DeleteDotNode : public ExpressionNode {
765 DeleteDotNode(ExpressionNode* base, const Identifier& i) KJS_FAST_CALL : m_base(base), m_ident(i) {}
766 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
767 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
768 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
769 virtual Precedence precedence() const { return PrecUnary; }
771 RefPtr<ExpressionNode> m_base;
775 class DeleteValueNode : public ExpressionNode {
777 DeleteValueNode(ExpressionNode* e) KJS_FAST_CALL : m_expr(e) {}
778 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
779 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
780 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
781 virtual Precedence precedence() const { return PrecUnary; }
783 RefPtr<ExpressionNode> m_expr;
786 class VoidNode : public ExpressionNode {
788 VoidNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
789 virtual void optimizeVariableAccess(FunctionBodyNode*, 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; }
794 RefPtr<ExpressionNode> expr;
797 class TypeOfResolveNode : public ExpressionNode {
799 TypeOfResolveNode(const Identifier &s) KJS_FAST_CALL
800 : ExpressionNode(StringType), m_ident(s) {}
802 TypeOfResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
803 : ExpressionNode(PlacementNewAdopt)
804 , m_ident(PlacementNewAdopt)
806 m_expectedReturnType = StringType;
809 virtual void optimizeVariableAccess(FunctionBodyNode*, 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; }
815 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
819 size_t m_index; // Used by LocalTypeOfNode.
822 class LocalVarTypeOfNode : public TypeOfResolveNode {
824 LocalVarTypeOfNode(size_t i) KJS_FAST_CALL
825 : TypeOfResolveNode(PlacementNewAdopt)
827 m_expectedReturnType = StringType;
828 ASSERT(i != missingSymbolMarker());
832 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
835 class TypeOfValueNode : public ExpressionNode {
837 TypeOfValueNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(StringType), m_expr(e) {}
838 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
839 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
840 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
841 virtual Precedence precedence() const { return PrecUnary; }
843 RefPtr<ExpressionNode> m_expr;
846 class PreIncResolveNode : public PrePostResolveNode {
848 PreIncResolveNode(const Identifier &s) KJS_FAST_CALL
849 : PrePostResolveNode(s)
853 PreIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
854 : PrePostResolveNode(PlacementNewAdopt)
858 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
860 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
861 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
862 virtual Precedence precedence() const { return PrecUnary; }
865 class PreIncLocalVarNode : public PreIncResolveNode {
867 PreIncLocalVarNode(size_t i) KJS_FAST_CALL
868 : PreIncResolveNode(PlacementNewAdopt)
870 ASSERT(i != missingSymbolMarker());
874 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
877 class PreDecResolveNode : public PrePostResolveNode {
879 PreDecResolveNode(const Identifier &s) KJS_FAST_CALL
880 : PrePostResolveNode(s)
884 PreDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
885 : PrePostResolveNode(PlacementNewAdopt)
889 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
891 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
892 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
893 virtual Precedence precedence() const { return PrecUnary; }
896 class PreDecLocalVarNode : public PreDecResolveNode {
898 PreDecLocalVarNode(size_t i) KJS_FAST_CALL
899 : PreDecResolveNode(PlacementNewAdopt)
901 ASSERT(i != missingSymbolMarker());
905 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
908 class PrefixBracketNode : public ExpressionNode {
910 PrefixBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : m_base(b), m_subscript(s) {}
912 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
913 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
914 virtual Precedence precedence() const { return PrecUnary; }
916 virtual bool isIncrement() const = 0;
917 RefPtr<ExpressionNode> m_base;
918 RefPtr<ExpressionNode> m_subscript;
921 class PreIncBracketNode : public PrefixBracketNode {
923 PreIncBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : PrefixBracketNode(b, s) {}
924 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
926 bool isIncrement() const { return true; }
929 class PreDecBracketNode : public PrefixBracketNode {
931 PreDecBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : PrefixBracketNode(b, s) {}
932 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
934 bool isIncrement() const { return false; }
937 class PrefixDotNode : public ExpressionNode {
939 PrefixDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : m_base(b), m_ident(i) {}
940 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
941 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
942 virtual Precedence precedence() const { return PrecPostfix; }
944 virtual bool isIncrement() const = 0;
945 RefPtr<ExpressionNode> m_base;
949 class PreIncDotNode : public PrefixDotNode {
951 PreIncDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : PrefixDotNode(b, i) {}
952 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
954 virtual bool isIncrement() const { return true; }
957 class PreDecDotNode : public PrefixDotNode {
959 PreDecDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : PrefixDotNode(b, i) {}
960 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
962 virtual bool isIncrement() const { return false; }
965 class PrefixErrorNode : public ExpressionNode {
967 PrefixErrorNode(ExpressionNode* e, Operator o) KJS_FAST_CALL : m_expr(e), m_oper(o) {}
968 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
969 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
970 virtual Precedence precedence() const { return PrecUnary; }
972 RefPtr<ExpressionNode> m_expr;
976 class UnaryPlusNode : public ExpressionNode {
978 UnaryPlusNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), m_expr(e) {}
979 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
980 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
981 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
982 virtual Precedence precedence() const { return PrecUnary; }
984 RefPtr<ExpressionNode> m_expr;
987 class NegateNode : public ExpressionNode {
989 NegateNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
990 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
991 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
992 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
993 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
994 virtual Precedence precedence() const { return PrecUnary; }
996 RefPtr<ExpressionNode> expr;
999 class BitwiseNotNode : public ExpressionNode {
1001 BitwiseNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
1002 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1003 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1004 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1005 virtual Precedence precedence() const { return PrecUnary; }
1007 RefPtr<ExpressionNode> expr;
1010 class LogicalNotNode : public ExpressionNode {
1012 LogicalNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(BooleanType), expr(e) {}
1013 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1014 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1015 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1016 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1017 virtual Precedence precedence() const { return PrecUnary; }
1019 RefPtr<ExpressionNode> expr;
1022 class MultNode : public ExpressionNode {
1024 MultNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1025 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1026 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1027 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1028 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1029 virtual Precedence precedence() const { return PrecMultiplicitave; }
1031 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1032 RefPtr<ExpressionNode> term1;
1033 RefPtr<ExpressionNode> term2;
1036 class DivNode : public ExpressionNode {
1038 DivNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1039 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1040 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1041 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1042 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1043 virtual Precedence precedence() const { return PrecMultiplicitave; }
1045 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1046 RefPtr<ExpressionNode> term1;
1047 RefPtr<ExpressionNode> term2;
1050 class ModNode : public ExpressionNode {
1052 ModNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1053 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1054 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1055 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1056 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1057 virtual Precedence precedence() const { return PrecMultiplicitave; }
1059 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1060 RefPtr<ExpressionNode> term1;
1061 RefPtr<ExpressionNode> term2;
1064 class AddNode : public ExpressionNode {
1066 AddNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
1067 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1068 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1069 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1070 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1071 virtual Precedence precedence() const { return PrecAdditive; }
1073 AddNode(ExpressionNode* t1, ExpressionNode* t2, JSType expectedReturn) KJS_FAST_CALL : ExpressionNode(expectedReturn), term1(t1), term2(t2) {}
1074 RefPtr<ExpressionNode> term1;
1075 RefPtr<ExpressionNode> term2;
1078 class AddNumbersNode : public AddNode {
1080 AddNumbersNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, NumberType) {}
1081 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1082 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1084 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*) KJS_FAST_CALL;
1087 class AddStringLeftNode : public AddNode {
1089 AddStringLeftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
1090 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1093 class AddStringRightNode : public AddNode {
1095 AddStringRightNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
1096 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1099 class AddStringsNode : public AddNode {
1101 AddStringsNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
1102 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1105 class SubNode : public ExpressionNode {
1107 SubNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1108 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1109 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1110 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1111 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1112 virtual Precedence precedence() const { return PrecAdditive; }
1114 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1115 RefPtr<ExpressionNode> term1;
1116 RefPtr<ExpressionNode> term2;
1119 class LeftShiftNode : public ExpressionNode {
1121 LeftShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
1122 : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1123 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1124 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1125 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1126 virtual Precedence precedence() const { return PrecShift; }
1128 RefPtr<ExpressionNode> term1;
1129 RefPtr<ExpressionNode> term2;
1132 class RightShiftNode : public ExpressionNode {
1134 RightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
1135 : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1136 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1137 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1138 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1139 virtual Precedence precedence() const { return PrecShift; }
1141 RefPtr<ExpressionNode> term1;
1142 RefPtr<ExpressionNode> term2;
1145 class UnsignedRightShiftNode : public ExpressionNode {
1147 UnsignedRightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
1148 : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1149 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1150 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1151 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1152 virtual Precedence precedence() const { return PrecShift; }
1154 RefPtr<ExpressionNode> term1;
1155 RefPtr<ExpressionNode> term2;
1158 class LessNode : public ExpressionNode {
1160 LessNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1161 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1162 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1163 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1164 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1165 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1166 virtual Precedence precedence() const { return PrecRelational; }
1168 RefPtr<ExpressionNode> expr1;
1169 RefPtr<ExpressionNode> expr2;
1172 class LessNumbersNode : public LessNode {
1174 LessNumbersNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1175 : LessNode(e1, e2) {}
1176 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1179 class LessStringsNode : public LessNode {
1181 LessStringsNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1182 : LessNode(e1, e2) {}
1183 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1186 class GreaterNode : public ExpressionNode {
1188 GreaterNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1189 expr1(e1), expr2(e2) {}
1190 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1191 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1192 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1193 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1194 virtual Precedence precedence() const { return PrecRelational; }
1196 RefPtr<ExpressionNode> expr1;
1197 RefPtr<ExpressionNode> expr2;
1200 class LessEqNode : public ExpressionNode {
1202 LessEqNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1203 expr1(e1), expr2(e2) {}
1204 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1205 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1206 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1207 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1208 virtual Precedence precedence() const { return PrecRelational; }
1210 RefPtr<ExpressionNode> expr1;
1211 RefPtr<ExpressionNode> expr2;
1214 class GreaterEqNode : public ExpressionNode {
1216 GreaterEqNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1217 expr1(e1), expr2(e2) {}
1218 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1219 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1220 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1221 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1222 virtual Precedence precedence() const { return PrecRelational; }
1224 RefPtr<ExpressionNode> expr1;
1225 RefPtr<ExpressionNode> expr2;
1228 class InstanceOfNode : public ExpressionNode {
1230 InstanceOfNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1231 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1232 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1233 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1234 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1235 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1236 virtual Precedence precedence() const { return PrecRelational; }
1238 RefPtr<ExpressionNode> expr1;
1239 RefPtr<ExpressionNode> expr2;
1242 class InNode : public ExpressionNode {
1244 InNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1245 expr1(e1), expr2(e2) {}
1246 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1247 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1248 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1249 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1250 virtual Precedence precedence() const { return PrecRelational; }
1252 RefPtr<ExpressionNode> expr1;
1253 RefPtr<ExpressionNode> expr2;
1256 class EqualNode : public ExpressionNode {
1258 EqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1259 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1260 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1261 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1262 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1263 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1264 virtual Precedence precedence() const { return PrecEquality; }
1266 RefPtr<ExpressionNode> expr1;
1267 RefPtr<ExpressionNode> expr2;
1270 class NotEqualNode : public ExpressionNode {
1272 NotEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1273 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1274 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1275 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1276 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1277 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1278 virtual Precedence precedence() const { return PrecEquality; }
1280 RefPtr<ExpressionNode> expr1;
1281 RefPtr<ExpressionNode> expr2;
1284 class StrictEqualNode : public ExpressionNode {
1286 StrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1287 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1288 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1289 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1290 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1291 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1292 virtual Precedence precedence() const { return PrecEquality; }
1294 RefPtr<ExpressionNode> expr1;
1295 RefPtr<ExpressionNode> expr2;
1298 class NotStrictEqualNode : public ExpressionNode {
1300 NotStrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1301 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1302 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1303 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1304 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1305 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1306 virtual Precedence precedence() const { return PrecEquality; }
1308 RefPtr<ExpressionNode> expr1;
1309 RefPtr<ExpressionNode> expr2;
1312 class BitAndNode : public ExpressionNode {
1314 BitAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1315 : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
1316 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1317 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1318 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1319 virtual Precedence precedence() const { return PrecBitwiseAnd; }
1321 RefPtr<ExpressionNode> expr1;
1322 RefPtr<ExpressionNode> expr2;
1325 class BitOrNode : public ExpressionNode {
1327 BitOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1328 : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
1329 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1330 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1331 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1332 virtual Precedence precedence() const { return PrecBitwiseOr; }
1334 RefPtr<ExpressionNode> expr1;
1335 RefPtr<ExpressionNode> expr2;
1338 class BitXOrNode : public ExpressionNode {
1340 BitXOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1341 : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
1342 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1343 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1344 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1345 virtual Precedence precedence() const { return PrecBitwiseXor; }
1347 RefPtr<ExpressionNode> expr1;
1348 RefPtr<ExpressionNode> expr2;
1352 * expr1 && expr2, expr1 || expr2
1354 class LogicalAndNode : public ExpressionNode {
1356 LogicalAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1357 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1358 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1359 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1360 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1361 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1362 virtual Precedence precedence() const { return PrecLogicalAnd; }
1364 RefPtr<ExpressionNode> expr1;
1365 RefPtr<ExpressionNode> expr2;
1368 class LogicalOrNode : public ExpressionNode {
1370 LogicalOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1371 : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1372 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1373 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1374 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1375 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1376 virtual Precedence precedence() const { return PrecLogicalOr; }
1378 RefPtr<ExpressionNode> expr1;
1379 RefPtr<ExpressionNode> expr2;
1383 * The ternary operator, "logical ? expr1 : expr2"
1385 class ConditionalNode : public ExpressionNode {
1387 ConditionalNode(ExpressionNode* l, ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1388 logical(l), expr1(e1), expr2(e2) {}
1389 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1390 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1391 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1392 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1393 virtual Precedence precedence() const { return PrecConditional; }
1395 RefPtr<ExpressionNode> logical;
1396 RefPtr<ExpressionNode> expr1;
1397 RefPtr<ExpressionNode> expr2;
1400 class ReadModifyResolveNode : public ExpressionNode {
1402 ReadModifyResolveNode(const Identifier &ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL
1409 ReadModifyResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1410 : ExpressionNode(PlacementNewAdopt)
1411 , m_ident(PlacementNewAdopt)
1412 , m_right(PlacementNewAdopt)
1416 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1417 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1418 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1419 virtual Precedence precedence() const { return PrecAssignment; }
1423 RefPtr<ExpressionNode> m_right;
1424 size_t m_index; // Used by ReadModifyLocalVarNode.
1427 class ReadModifyLocalVarNode : public ReadModifyResolveNode {
1429 ReadModifyLocalVarNode(size_t i) KJS_FAST_CALL
1430 : ReadModifyResolveNode(PlacementNewAdopt)
1432 ASSERT(i != missingSymbolMarker());
1436 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1439 class AssignResolveNode : public ExpressionNode {
1441 AssignResolveNode(const Identifier &ident, ExpressionNode* right) KJS_FAST_CALL
1447 AssignResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1448 : ExpressionNode(PlacementNewAdopt)
1449 , m_ident(PlacementNewAdopt)
1450 , m_right(PlacementNewAdopt)
1454 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1455 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1456 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1457 virtual Precedence precedence() const { return PrecAssignment; }
1460 RefPtr<ExpressionNode> m_right;
1461 size_t m_index; // Used by ReadModifyLocalVarNode.
1464 class AssignLocalVarNode : public AssignResolveNode {
1466 AssignLocalVarNode(size_t i) KJS_FAST_CALL
1467 : AssignResolveNode(PlacementNewAdopt)
1469 ASSERT(i != missingSymbolMarker());
1473 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1476 class ReadModifyBracketNode : public ExpressionNode {
1478 ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right) KJS_FAST_CALL
1479 : m_base(base), m_subscript(subscript), m_oper(oper), m_right(right) {}
1480 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1481 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1482 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1483 virtual Precedence precedence() const { return PrecAssignment; }
1485 RefPtr<ExpressionNode> m_base;
1486 RefPtr<ExpressionNode> m_subscript;
1488 RefPtr<ExpressionNode> m_right;
1491 class AssignBracketNode : public ExpressionNode {
1493 AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right) KJS_FAST_CALL
1494 : m_base(base), m_subscript(subscript), m_right(right) {}
1495 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1496 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1497 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1498 virtual Precedence precedence() const { return PrecAssignment; }
1500 RefPtr<ExpressionNode> m_base;
1501 RefPtr<ExpressionNode> m_subscript;
1502 RefPtr<ExpressionNode> m_right;
1505 class AssignDotNode : public ExpressionNode {
1507 AssignDotNode(ExpressionNode* base, const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL
1508 : m_base(base), m_ident(ident), m_right(right) {}
1509 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1510 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1511 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1512 virtual Precedence precedence() const { return PrecAssignment; }
1514 RefPtr<ExpressionNode> m_base;
1516 RefPtr<ExpressionNode> m_right;
1519 class ReadModifyDotNode : public ExpressionNode {
1521 ReadModifyDotNode(ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL
1522 : m_base(base), m_ident(ident), m_oper(oper), m_right(right) {}
1523 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1524 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1525 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1526 virtual Precedence precedence() const { return PrecAssignment; }
1528 RefPtr<ExpressionNode> m_base;
1531 RefPtr<ExpressionNode> m_right;
1534 class AssignErrorNode : public ExpressionNode {
1536 AssignErrorNode(ExpressionNode* left, Operator oper, ExpressionNode* right) KJS_FAST_CALL
1537 : m_left(left), m_oper(oper), m_right(right) {}
1538 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1539 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1540 virtual Precedence precedence() const { return PrecAssignment; }
1542 RefPtr<ExpressionNode> m_left;
1544 RefPtr<ExpressionNode> m_right;
1547 class CommaNode : public ExpressionNode {
1549 CommaNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL : expr1(e1), expr2(e2)
1551 e1->optimizeForUnnecessaryResult();
1553 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1554 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1555 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1556 virtual Precedence precedence() const { return PrecExpression; }
1558 RefPtr<ExpressionNode> expr1;
1559 RefPtr<ExpressionNode> expr2;
1562 class AssignExprNode : public ExpressionNode {
1564 AssignExprNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
1565 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1566 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1567 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1568 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1570 RefPtr<ExpressionNode> expr;
1573 class VarDeclNode : public ExpressionNode {
1575 enum Type { Variable, Constant };
1576 VarDeclNode(const Identifier &id, AssignExprNode *in, Type t) KJS_FAST_CALL;
1577 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1578 virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1579 void evaluateSingle(ExecState*) KJS_FAST_CALL;
1580 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1581 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1582 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1583 PassRefPtr<VarDeclNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1587 ListRefPtr<VarDeclNode> next;
1589 void handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL KJS_NO_INLINE;
1590 RefPtr<AssignExprNode> init;
1593 class VarStatementNode : public StatementNode {
1595 VarStatementNode(VarDeclNode* l) KJS_FAST_CALL : next(l) { m_mayHaveDeclarations = true; }
1596 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1597 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1598 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1599 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1601 RefPtr<VarDeclNode> next;
1604 typedef Vector<RefPtr<StatementNode> > SourceElements;
1606 class BlockNode : public StatementNode {
1608 BlockNode(SourceElements* children) KJS_FAST_CALL;
1609 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1610 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1611 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1612 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1614 OwnPtr<SourceElements> m_children;
1617 class EmptyStatementNode : public StatementNode {
1619 EmptyStatementNode() KJS_FAST_CALL { } // debug
1620 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1621 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1624 class ExprStatementNode : public StatementNode {
1626 ExprStatementNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
1627 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1628 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1629 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1631 RefPtr<ExpressionNode> expr;
1634 class IfNode : public StatementNode {
1636 IfNode(ExpressionNode* e, StatementNode *s1, StatementNode *s2) KJS_FAST_CALL
1637 : expr(e), statement1(s1), statement2(s2) { m_mayHaveDeclarations = statement1->mayHaveDeclarations() || (statement2 && statement2->mayHaveDeclarations()); }
1638 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1639 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1640 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1641 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1643 RefPtr<ExpressionNode> expr;
1644 RefPtr<StatementNode> statement1;
1645 RefPtr<StatementNode> statement2;
1648 class DoWhileNode : public StatementNode {
1650 DoWhileNode(StatementNode *s, ExpressionNode* e) KJS_FAST_CALL : statement(s), expr(e) { m_mayHaveDeclarations = true; }
1651 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1652 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1653 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1654 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1656 RefPtr<StatementNode> statement;
1657 RefPtr<ExpressionNode> expr;
1660 class WhileNode : public StatementNode {
1662 WhileNode(ExpressionNode* e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
1663 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1664 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1665 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1666 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1668 RefPtr<ExpressionNode> expr;
1669 RefPtr<StatementNode> statement;
1672 class ForNode : public StatementNode {
1674 ForNode(ExpressionNode* e1, ExpressionNode* e2, ExpressionNode* e3, StatementNode* s) KJS_FAST_CALL :
1675 expr1(e1), expr2(e2), expr3(e3), statement(s)
1677 m_mayHaveDeclarations = true;
1679 expr1->optimizeForUnnecessaryResult();
1681 expr3->optimizeForUnnecessaryResult();
1684 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1685 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1686 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1687 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1689 RefPtr<ExpressionNode> expr1;
1690 RefPtr<ExpressionNode> expr2;
1691 RefPtr<ExpressionNode> expr3;
1692 RefPtr<StatementNode> statement;
1695 class ForInNode : public StatementNode {
1697 ForInNode(ExpressionNode* l, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
1698 ForInNode(const Identifier &i, AssignExprNode *in, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
1699 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1700 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1701 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1702 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1705 RefPtr<AssignExprNode> init;
1706 RefPtr<ExpressionNode> lexpr;
1707 RefPtr<ExpressionNode> expr;
1708 RefPtr<VarDeclNode> varDecl;
1709 RefPtr<StatementNode> statement;
1712 class ContinueNode : public StatementNode {
1714 ContinueNode() KJS_FAST_CALL { }
1715 ContinueNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1716 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1717 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1722 class BreakNode : public StatementNode {
1724 BreakNode() KJS_FAST_CALL { }
1725 BreakNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1726 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1727 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1732 class ReturnNode : public StatementNode {
1734 ReturnNode(ExpressionNode* v) KJS_FAST_CALL : value(v) {}
1735 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1736 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1737 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1739 RefPtr<ExpressionNode> value;
1742 class WithNode : public StatementNode {
1744 WithNode(ExpressionNode* e, StatementNode* s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
1745 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1746 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1747 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1748 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1750 RefPtr<ExpressionNode> expr;
1751 RefPtr<StatementNode> statement;
1754 class LabelNode : public StatementNode {
1756 LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { m_mayHaveDeclarations = true; }
1757 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1758 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1759 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1760 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1763 RefPtr<StatementNode> statement;
1766 class ThrowNode : public StatementNode {
1768 ThrowNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
1769 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1770 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1771 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1773 RefPtr<ExpressionNode> expr;
1776 class TryNode : public StatementNode {
1778 TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f) KJS_FAST_CALL
1779 : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { m_mayHaveDeclarations = true; }
1780 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1781 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1782 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1783 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1785 RefPtr<StatementNode> tryBlock;
1786 Identifier exceptionIdent;
1787 RefPtr<StatementNode> catchBlock;
1788 RefPtr<StatementNode> finallyBlock;
1791 class ParameterNode : public Node {
1793 ParameterNode(const Identifier& i) KJS_FAST_CALL : id(i) { }
1794 ParameterNode(ParameterNode* l, const Identifier& i) KJS_FAST_CALL
1795 : id(i) { l->next = this; }
1796 Identifier ident() KJS_FAST_CALL { return id; }
1797 ParameterNode *nextParam() KJS_FAST_CALL { return next.get(); }
1798 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1799 PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1800 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1802 friend class FuncDeclNode;
1803 friend class FuncExprNode;
1805 ListRefPtr<ParameterNode> next;
1808 // inherited by ProgramNode
1809 class FunctionBodyNode : public BlockNode {
1811 FunctionBodyNode(SourceElements* children) KJS_FAST_CALL;
1812 int sourceId() KJS_FAST_CALL { return m_sourceId; }
1813 const UString& sourceURL() KJS_FAST_CALL { return m_sourceURL; }
1815 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1817 SymbolTable& symbolTable() { return m_symbolTable; }
1819 void addParam(const Identifier& ident) KJS_FAST_CALL;
1820 size_t numParams() const KJS_FAST_CALL { return m_parameters.size(); }
1821 Identifier paramName(size_t pos) const KJS_FAST_CALL { return m_parameters[pos]; }
1822 UString paramString() const KJS_FAST_CALL;
1823 Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
1824 ALWAYS_INLINE void processDeclarations(ExecState*);
1825 ALWAYS_INLINE void processDeclarationsForFunctionCode(ExecState*);
1826 ALWAYS_INLINE void processDeclarationsForProgramCode(ExecState*);
1828 UString m_sourceURL;
1831 void initializeDeclarationStacks(ExecState*);
1832 bool m_initializedDeclarationStacks;
1834 void initializeSymbolTable();
1835 bool m_initializedSymbolTable;
1837 void optimizeVariableAccess();
1838 bool m_optimizedResolveNodes;
1840 // Properties that will go into the ActivationImp's local storage. (Used for initializing the ActivationImp.)
1841 DeclarationStacks::VarStack m_varStack;
1842 DeclarationStacks::FunctionStack m_functionStack;
1843 Vector<Identifier> m_parameters;
1845 // Mapping from property name -> local storage index. (Used once to transform the AST, and subsequently for residual slow case lookups.)
1846 SymbolTable m_symbolTable;
1849 class FuncExprNode : public ExpressionNode {
1851 FuncExprNode(const Identifier& i, FunctionBodyNode* b, ParameterNode* p = 0) KJS_FAST_CALL
1852 : ident(i), param(p), body(b) { addParams(); }
1853 virtual JSValue *evaluate(ExecState*) KJS_FAST_CALL;
1854 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1855 virtual Precedence precedence() const { return PrecMember; }
1857 void addParams() KJS_FAST_CALL;
1858 // Used for streamTo
1859 friend class PropertyNode;
1861 RefPtr<ParameterNode> param;
1862 RefPtr<FunctionBodyNode> body;
1865 class FuncDeclNode : public StatementNode {
1867 FuncDeclNode(const Identifier& i, FunctionBodyNode* b) KJS_FAST_CALL
1868 : ident(i), body(b) { addParams(); m_mayHaveDeclarations = true; }
1869 FuncDeclNode(const Identifier& i, ParameterNode* p, FunctionBodyNode* b) KJS_FAST_CALL
1870 : ident(i), param(p), body(b) { addParams(); m_mayHaveDeclarations = true; }
1871 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1872 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1873 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1874 ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
1877 void addParams() KJS_FAST_CALL;
1878 RefPtr<ParameterNode> param;
1879 RefPtr<FunctionBodyNode> body;
1882 class CaseClauseNode : public Node {
1884 CaseClauseNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { m_mayHaveDeclarations = true; }
1885 CaseClauseNode(ExpressionNode* e, SourceElements* children) KJS_FAST_CALL
1886 : expr(e), m_children(children) { m_mayHaveDeclarations = true; }
1887 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1888 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1889 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1890 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1892 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1893 Completion evalStatements(ExecState*) KJS_FAST_CALL;
1896 RefPtr<ExpressionNode> expr;
1897 OwnPtr<SourceElements> m_children;
1900 class ClauseListNode : public Node {
1902 ClauseListNode(CaseClauseNode* c) KJS_FAST_CALL : clause(c) { m_mayHaveDeclarations = true; }
1903 ClauseListNode(ClauseListNode* n, CaseClauseNode* c) KJS_FAST_CALL
1904 : clause(c) { n->next = this; m_mayHaveDeclarations = true; }
1905 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1906 CaseClauseNode* getClause() const KJS_FAST_CALL { return clause.get(); }
1907 ClauseListNode* getNext() const KJS_FAST_CALL { return next.get(); }
1908 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1909 PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1910 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1911 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1913 friend class CaseBlockNode;
1914 RefPtr<CaseClauseNode> clause;
1915 ListRefPtr<ClauseListNode> next;
1918 class CaseBlockNode : public Node {
1920 CaseBlockNode(ClauseListNode* l1, CaseClauseNode* d, ClauseListNode* l2) KJS_FAST_CALL;
1921 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1922 Completion evalBlock(ExecState *exec, JSValue *input) KJS_FAST_CALL;
1923 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1924 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1925 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1927 RefPtr<ClauseListNode> list1;
1928 RefPtr<CaseClauseNode> def;
1929 RefPtr<ClauseListNode> list2;
1932 class SwitchNode : public StatementNode {
1934 SwitchNode(ExpressionNode* e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { m_mayHaveDeclarations = true; }
1935 virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1936 virtual Completion execute(ExecState*) KJS_FAST_CALL;
1937 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1938 virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1940 RefPtr<ExpressionNode> expr;
1941 RefPtr<CaseBlockNode> block;
1944 class ProgramNode : public FunctionBodyNode {
1946 ProgramNode(SourceElements* children) KJS_FAST_CALL;
1949 struct ElementList {
1954 struct PropertyList {
1955 PropertyListNode* head;
1956 PropertyListNode* tail;
1959 struct ArgumentList {
1960 ArgumentListNode* head;
1961 ArgumentListNode* tail;
1964 struct VarDeclList {
1969 struct ParameterList {
1970 ParameterNode* head;
1971 ParameterNode* tail;
1975 ClauseListNode* head;
1976 ClauseListNode* tail;