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

Last change on this file since 27413 was 27394, checked in by mjs, 18 years ago

Reviewed by Oliver.


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