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

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

Optimise multi-scope function call resolution

Reviewed by Geoff

Refactor multiscope variable resolution and use to add
optimised FunctionCallResolveNode subclasses.

2.6% gain in sunspider performance, *25%* gain in controlflow-recursive

  • Property svn:eol-style set to native
File size: 103.9 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich ([email protected])
6 * Copyright (C) 2007 Maks Orlovich
7 * Copyright (C) 2007 Eric Seidel <[email protected]>
8 *
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public License
20 * along with this library; see the file COPYING.LIB. If not, write to
21 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22 * Boston, MA 02110-1301, USA.
23 *
24 */
25
26#ifndef NODES_H_
27#define NODES_H_
28
29#include "internal.h"
30#include "regexp.h"
31#include "SymbolTable.h"
32#include <wtf/ListRefPtr.h>
33#include <wtf/MathExtras.h>
34#include <wtf/OwnPtr.h>
35#include <wtf/Vector.h>
36
37#if PLATFORM(X86) && COMPILER(GCC)
38#define KJS_FAST_CALL __attribute__((regparm(3)))
39#else
40#define KJS_FAST_CALL
41#endif
42
43namespace KJS {
44
45 class ArgumentsNode;
46 class ConstDeclNode;
47 class FuncDeclNode;
48 class Node;
49 class PropertyListNode;
50 class SourceStream;
51
52 enum Operator {
53 OpEqual,
54 OpPlusEq,
55 OpMinusEq,
56 OpMultEq,
57 OpDivEq,
58 OpPlusPlus,
59 OpMinusMinus,
60 OpAndEq,
61 OpXOrEq,
62 OpOrEq,
63 OpModEq,
64 OpLShift,
65 OpRShift,
66 OpURShift,
67 };
68
69 enum Precedence {
70 PrecPrimary,
71 PrecMember,
72 PrecCall,
73 PrecLeftHandSide,
74 PrecPostfix,
75 PrecUnary,
76 PrecMultiplicitave,
77 PrecAdditive,
78 PrecShift,
79 PrecRelational,
80 PrecEquality,
81 PrecBitwiseAnd,
82 PrecBitwiseXor,
83 PrecBitwiseOr,
84 PrecLogicalAnd,
85 PrecLogicalOr,
86 PrecConditional,
87 PrecAssignment,
88 PrecExpression
89 };
90
91 struct DeclarationStacks {
92 typedef Vector<Node*, 16> NodeStack;
93 enum { IsConstant = 1, HasInitializer = 2 } VarAttrs;
94 typedef Vector<std::pair<Identifier, unsigned>, 16> VarStack;
95 typedef Vector<FuncDeclNode*, 16> FunctionStack;
96
97 DeclarationStacks(ExecState* e, NodeStack& n, VarStack& v, FunctionStack& f)
98 : exec(e)
99 , nodeStack(n)
100 , varStack(v)
101 , functionStack(f)
102 {
103 }
104
105 ExecState* exec;
106 NodeStack& nodeStack;
107 VarStack& varStack;
108 FunctionStack& functionStack;
109 };
110
111 class ParserRefCounted : Noncopyable {
112 protected:
113 ParserRefCounted() KJS_FAST_CALL;
114 ParserRefCounted(PlacementNewAdoptType) KJS_FAST_CALL
115 {
116 }
117
118 public:
119 void ref() KJS_FAST_CALL;
120 void deref() KJS_FAST_CALL;
121 unsigned refcount() KJS_FAST_CALL;
122
123 static void deleteNewObjects() KJS_FAST_CALL;
124
125 virtual ~ParserRefCounted();
126 };
127
128 class Node : public ParserRefCounted {
129 public:
130 typedef DeclarationStacks::NodeStack NodeStack;
131 typedef DeclarationStacks::VarStack VarStack;
132 typedef DeclarationStacks::FunctionStack FunctionStack;
133
134 Node() KJS_FAST_CALL;
135 Node(PlacementNewAdoptType placementAdopt) KJS_FAST_CALL
136 : ParserRefCounted(placementAdopt)
137 {
138 }
139
140 UString toString() const KJS_FAST_CALL;
141 int lineNo() const KJS_FAST_CALL { return m_line; }
142
143 // Serialization.
144 virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
145 virtual Precedence precedence() const = 0;
146 virtual bool needsParensIfLeftmost() const { return false; }
147
148 // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
149 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL { }
150
151 protected:
152 Node(JSType) KJS_FAST_CALL; // used by ExpressionNode
153
154 // for use in execute()
155 JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
156 JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
157
158 // for use in evaluate()
159 JSValue* throwError(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
160 JSValue* throwError(ExecState*, ErrorType, const char* msg, const char*) KJS_FAST_CALL;
161 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*) KJS_FAST_CALL;
162 JSValue* throwError(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
163 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, const Identifier&) KJS_FAST_CALL;
164 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, Node*) KJS_FAST_CALL;
165 JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, const Identifier&) KJS_FAST_CALL;
166
167 JSValue* throwUndefinedVariableError(ExecState*, const Identifier&) KJS_FAST_CALL;
168
169 void handleException(ExecState*) KJS_FAST_CALL;
170 void handleException(ExecState*, JSValue*) KJS_FAST_CALL;
171
172 // for use in execute()
173 JSValue* rethrowException(ExecState*) KJS_FAST_CALL;
174
175 int m_line : 28;
176 unsigned m_expectedReturnType : 3; // JSType
177 };
178
179 class ExpressionNode : public Node {
180 public:
181 ExpressionNode() KJS_FAST_CALL : Node() {}
182 ExpressionNode(JSType expectedReturn) KJS_FAST_CALL
183 : Node(expectedReturn)
184 {
185 }
186
187 // Special constructor for cases where we overwrite an object in place.
188 ExpressionNode(PlacementNewAdoptType) KJS_FAST_CALL
189 : Node(PlacementNewAdopt)
190 {
191 }
192
193 virtual bool isNumber() const KJS_FAST_CALL { return false; }
194 virtual bool isLocation() const KJS_FAST_CALL { return false; }
195 virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
196 virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
197 virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
198
199 JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
200
201 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
202 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
203 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
204 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
205 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
206
207 // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance
208 virtual void optimizeForUnnecessaryResult() { }
209
210 protected:
211 typedef enum { EvalOperator, FunctionCall } CallerType;
212 template <CallerType, bool> inline JSValue* resolveAndCall(ExecState*, const Identifier&, ArgumentsNode*, size_t = 0);
213 };
214
215 class StatementNode : public Node {
216 public:
217 StatementNode() KJS_FAST_CALL;
218 void setLoc(int line0, int line1) KJS_FAST_CALL;
219 int firstLine() const KJS_FAST_CALL { return lineNo(); }
220 int lastLine() const KJS_FAST_CALL { return m_lastLine; }
221 virtual JSValue* execute(ExecState *exec) KJS_FAST_CALL = 0;
222 virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_labelStack.push(ident); }
223 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
224 virtual bool isEmptyStatement() const KJS_FAST_CALL { return false; }
225
226 protected:
227 LabelStack m_labelStack;
228
229 private:
230 int m_lastLine;
231 };
232
233 class NullNode : public ExpressionNode {
234 public:
235 NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {}
236 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
237 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
238 virtual Precedence precedence() const { return PrecPrimary; }
239 };
240
241 class FalseNode : public ExpressionNode {
242 public:
243 FalseNode() KJS_FAST_CALL
244 : ExpressionNode(BooleanType)
245 {
246 }
247
248 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
249 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; }
250 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
251 virtual Precedence precedence() const { return PrecPrimary; }
252 };
253
254 class TrueNode : public ExpressionNode {
255 public:
256 TrueNode() KJS_FAST_CALL
257 : ExpressionNode(BooleanType)
258 {
259 }
260
261 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
262 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; }
263 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
264 virtual Precedence precedence() const { return PrecPrimary; }
265 };
266
267 class PlaceholderTrueNode : public TrueNode {
268 public:
269 // Like TrueNode, but does not serialize as "true".
270 PlaceholderTrueNode() KJS_FAST_CALL
271 : TrueNode()
272 {
273 }
274
275 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
276 };
277
278 class NumberNode : public ExpressionNode {
279 public:
280 NumberNode(double v) KJS_FAST_CALL
281 : ExpressionNode(NumberType)
282 , m_double(v)
283 {
284 }
285
286 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
287 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
288 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
289 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
290 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
291 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
292 virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; }
293
294 virtual bool isNumber() const KJS_FAST_CALL { return true; }
295 double value() const KJS_FAST_CALL { return m_double; }
296 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; }
297
298 protected:
299 double m_double;
300 };
301
302 class ImmediateNumberNode : public NumberNode {
303 public:
304 ImmediateNumberNode(JSValue* v, double d) KJS_FAST_CALL
305 : NumberNode(d)
306 , m_value(v)
307 {
308 ASSERT(v == JSImmediate::from(d));
309 }
310
311 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
312 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
313 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
314
315 virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
316
317 private:
318 JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr
319 };
320
321 class StringNode : public ExpressionNode {
322 public:
323 StringNode(const UString* v) KJS_FAST_CALL
324 : ExpressionNode(StringType)
325 , m_value(*v)
326 {
327 }
328
329 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
330 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
331 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
332 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
333 virtual Precedence precedence() const { return PrecPrimary; }
334
335 private:
336 UString m_value;
337 };
338
339 class RegExpNode : public ExpressionNode {
340 public:
341 RegExpNode(const UString& pattern, const UString& flags) KJS_FAST_CALL
342 : m_regExp(RegExp::create(pattern, flags))
343 {
344 }
345
346 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
347 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
348 virtual Precedence precedence() const { return PrecPrimary; }
349
350 private:
351 RefPtr<RegExp> m_regExp;
352 };
353
354 class ThisNode : public ExpressionNode {
355 public:
356 ThisNode() KJS_FAST_CALL
357 {
358 }
359
360 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
361 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
362 virtual Precedence precedence() const { return PrecPrimary; }
363 };
364
365 class ResolveNode : public ExpressionNode {
366 public:
367 ResolveNode(const Identifier& ident) KJS_FAST_CALL
368 : m_ident(ident)
369 {
370 }
371
372 // Special constructor for cases where we overwrite an object in place.
373 ResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
374 : ExpressionNode(PlacementNewAdopt)
375 , m_ident(PlacementNewAdopt)
376 {
377 }
378
379 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
380
381 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
382 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
383 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
384 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
385 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
386 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
387 virtual Precedence precedence() const { return PrecPrimary; }
388
389 virtual bool isLocation() const KJS_FAST_CALL { return true; }
390 virtual bool isResolveNode() const KJS_FAST_CALL { return true; }
391 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
392
393 protected:
394 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
395 Identifier m_ident;
396 size_t m_index; // Used by LocalVarAccessNode and ScopedVarAccessNode.
397 size_t m_scopeDepth; // Used by ScopedVarAccessNode
398 };
399
400 class LocalVarAccessNode : public ResolveNode {
401 public:
402 // Overwrites a ResolveNode in place.
403 LocalVarAccessNode(size_t i) KJS_FAST_CALL
404 : ResolveNode(PlacementNewAdopt)
405 {
406 ASSERT(i != missingSymbolMarker());
407 m_index = i;
408 }
409
410 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
411 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
412 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
413 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
414 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
415
416 private:
417 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
418 };
419
420 class ScopedVarAccessNode : public ResolveNode {
421 public:
422 // Overwrites a ResolveNode in place.
423 ScopedVarAccessNode(size_t i, size_t scopeDepth) KJS_FAST_CALL
424 : ResolveNode(PlacementNewAdopt)
425 {
426 ASSERT(i != missingSymbolMarker());
427 m_index = i;
428 m_scopeDepth = scopeDepth;
429 }
430
431 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
432 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
433 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
434 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
435 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
436
437 private:
438 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
439 };
440
441 class NonLocalVarAccessNode : public ResolveNode {
442 public:
443 // Overwrites a ResolveNode in place.
444 NonLocalVarAccessNode(size_t scopeDepth) KJS_FAST_CALL
445 : ResolveNode(PlacementNewAdopt)
446 {
447 ASSERT(scopeDepth != 0);
448 m_scopeDepth = scopeDepth;
449 }
450
451 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
452 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
453 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
454 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
455 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
456
457 private:
458 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
459 };
460
461 class ElementNode : public Node {
462 public:
463 ElementNode(int elision, ExpressionNode* node) KJS_FAST_CALL
464 : m_elision(elision)
465 , m_node(node)
466 {
467 }
468
469 ElementNode(ElementNode* l, int elision, ExpressionNode* node) KJS_FAST_CALL
470 : m_elision(elision)
471 , m_node(node)
472 {
473 l->m_next = this;
474 }
475
476 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
477 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
478 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
479
480 PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
481
482 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
483
484 private:
485 friend class ArrayNode;
486 ListRefPtr<ElementNode> m_next;
487 int m_elision;
488 RefPtr<ExpressionNode> m_node;
489 };
490
491 class ArrayNode : public ExpressionNode {
492 public:
493 ArrayNode(int elision) KJS_FAST_CALL
494 : m_elision(elision)
495 , m_optional(true)
496 {
497 }
498
499 ArrayNode(ElementNode* element) KJS_FAST_CALL
500 : m_element(element)
501 , m_elision(0)
502 , m_optional(false)
503 {
504 }
505
506 ArrayNode(int elision, ElementNode* element) KJS_FAST_CALL
507 : m_element(element)
508 , m_elision(elision)
509 , m_optional(true)
510 {
511 }
512
513 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
514 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
515 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
516 virtual Precedence precedence() const { return PrecPrimary; }
517
518 private:
519 RefPtr<ElementNode> m_element;
520 int m_elision;
521 bool m_optional;
522 };
523
524 class PropertyNode : public Node {
525 public:
526 enum Type { Constant, Getter, Setter };
527
528 PropertyNode(const Identifier& name, ExpressionNode* assign, Type type) KJS_FAST_CALL
529 : m_name(name)
530 , m_assign(assign)
531 , m_type(type)
532 {
533 }
534
535 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
536 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
537 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
538
539 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
540 const Identifier& name() const { return m_name; }
541
542 private:
543 friend class PropertyListNode;
544 Identifier m_name;
545 RefPtr<ExpressionNode> m_assign;
546 Type m_type;
547 };
548
549 class PropertyListNode : public Node {
550 public:
551 PropertyListNode(PropertyNode* node) KJS_FAST_CALL
552 : m_node(node)
553 {
554 }
555
556 PropertyListNode(PropertyNode* node, PropertyListNode* list) KJS_FAST_CALL
557 : m_node(node)
558 {
559 list->m_next = this;
560 }
561
562 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
563 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
564 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
565
566 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
567 PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
568
569 private:
570 friend class ObjectLiteralNode;
571 RefPtr<PropertyNode> m_node;
572 ListRefPtr<PropertyListNode> m_next;
573 };
574
575 class ObjectLiteralNode : public ExpressionNode {
576 public:
577 ObjectLiteralNode() KJS_FAST_CALL
578 {
579 }
580
581 ObjectLiteralNode(PropertyListNode* list) KJS_FAST_CALL
582 : m_list(list)
583 {
584 }
585
586 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
587 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
588 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
589 virtual Precedence precedence() const { return PrecPrimary; }
590 virtual bool needsParensIfLeftmost() const { return true; }
591
592 private:
593 RefPtr<PropertyListNode> m_list;
594 };
595
596 class BracketAccessorNode : public ExpressionNode {
597 public:
598 BracketAccessorNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
599 : m_base(base)
600 , m_subscript(subscript)
601 {
602 }
603
604 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
605 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
606 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
607 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
608 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
609 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
610 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
611 virtual Precedence precedence() const { return PrecMember; }
612
613 virtual bool isLocation() const KJS_FAST_CALL { return true; }
614 virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return true; }
615 ExpressionNode* base() KJS_FAST_CALL { return m_base.get(); }
616 ExpressionNode* subscript() KJS_FAST_CALL { return m_subscript.get(); }
617
618 private:
619 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
620
621 RefPtr<ExpressionNode> m_base;
622 RefPtr<ExpressionNode> m_subscript;
623 };
624
625 class DotAccessorNode : public ExpressionNode {
626 public:
627 DotAccessorNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
628 : m_base(base)
629 , m_ident(ident)
630 {
631 }
632
633 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
634 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
635 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
636 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
637 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
638 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
639 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
640 virtual Precedence precedence() const { return PrecMember; }
641
642 virtual bool isLocation() const KJS_FAST_CALL { return true; }
643 virtual bool isDotAccessorNode() const KJS_FAST_CALL { return true; }
644 ExpressionNode* base() const KJS_FAST_CALL { return m_base.get(); }
645 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
646
647 private:
648 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
649
650 RefPtr<ExpressionNode> m_base;
651 Identifier m_ident;
652 };
653
654 class ArgumentListNode : public Node {
655 public:
656 ArgumentListNode(ExpressionNode* expr) KJS_FAST_CALL
657 : m_expr(expr)
658 {
659 }
660
661 ArgumentListNode(ArgumentListNode* listNode, ExpressionNode* expr) KJS_FAST_CALL
662 : m_expr(expr)
663 {
664 listNode->m_next = this;
665 }
666
667 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
668 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
669 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
670
671 void evaluateList(ExecState*, List&) KJS_FAST_CALL;
672 PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
673
674 private:
675 friend class ArgumentsNode;
676 ListRefPtr<ArgumentListNode> m_next;
677 RefPtr<ExpressionNode> m_expr;
678 };
679
680 class ArgumentsNode : public Node {
681 public:
682 ArgumentsNode() KJS_FAST_CALL
683 {
684 }
685
686 ArgumentsNode(ArgumentListNode* listNode) KJS_FAST_CALL
687 : m_listNode(listNode)
688 {
689 }
690
691 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
692 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
693 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
694
695 void evaluateList(ExecState* exec, List& list) KJS_FAST_CALL { if (m_listNode) m_listNode->evaluateList(exec, list); }
696
697 private:
698 RefPtr<ArgumentListNode> m_listNode;
699 };
700
701 class NewExprNode : public ExpressionNode {
702 public:
703 NewExprNode(ExpressionNode* expr) KJS_FAST_CALL
704 : m_expr(expr)
705 {
706 }
707
708 NewExprNode(ExpressionNode* expr, ArgumentsNode* args) KJS_FAST_CALL
709 : m_expr(expr)
710 , m_args(args)
711 {
712 }
713
714 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
715 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
716 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
717 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
718 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
719 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
720 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
721 virtual Precedence precedence() const { return PrecLeftHandSide; }
722
723 private:
724 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
725
726 RefPtr<ExpressionNode> m_expr;
727 RefPtr<ArgumentsNode> m_args;
728 };
729
730 class EvalFunctionCallNode : public ExpressionNode {
731 public:
732 EvalFunctionCallNode(ArgumentsNode* args) KJS_FAST_CALL
733 : m_args(args)
734 {
735 }
736
737 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
738 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
739 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
740 virtual Precedence precedence() const { return PrecCall; }
741
742 private:
743 RefPtr<ArgumentsNode> m_args;
744 };
745
746 class FunctionCallValueNode : public ExpressionNode {
747 public:
748 FunctionCallValueNode(ExpressionNode* expr, ArgumentsNode* args) KJS_FAST_CALL
749 : m_expr(expr)
750 , m_args(args)
751 {
752 }
753
754 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, 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 PrecCall; }
758
759 private:
760 RefPtr<ExpressionNode> m_expr;
761 RefPtr<ArgumentsNode> m_args;
762 };
763
764 class FunctionCallResolveNode : public ExpressionNode {
765 public:
766 FunctionCallResolveNode(const Identifier& ident, ArgumentsNode* args) KJS_FAST_CALL
767 : m_ident(ident)
768 , m_args(args)
769 {
770 }
771
772 FunctionCallResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
773 : ExpressionNode(PlacementNewAdopt)
774 , m_ident(PlacementNewAdopt)
775 , m_args(PlacementNewAdopt)
776 {
777 }
778
779 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
780 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
781 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
782 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
783 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
784 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
785 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
786 virtual Precedence precedence() const { return PrecCall; }
787
788 protected:
789 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
790
791 Identifier m_ident;
792 RefPtr<ArgumentsNode> m_args;
793 size_t m_index; // Used by LocalVarFunctionCallNode.
794 size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
795 };
796
797 class LocalVarFunctionCallNode : public FunctionCallResolveNode {
798 public:
799 LocalVarFunctionCallNode(size_t i) KJS_FAST_CALL
800 : FunctionCallResolveNode(PlacementNewAdopt)
801 {
802 ASSERT(i != missingSymbolMarker());
803 m_index = i;
804 }
805
806 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
807 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
808 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
809 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
810 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
811
812 private:
813 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
814 };
815
816 class ScopedVarFunctionCallNode : public FunctionCallResolveNode {
817 public:
818 ScopedVarFunctionCallNode(size_t i, size_t depth) KJS_FAST_CALL
819 : FunctionCallResolveNode(PlacementNewAdopt)
820 {
821 ASSERT(i != missingSymbolMarker());
822 m_index = i;
823 m_scopeDepth = depth;
824 }
825
826 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
827 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
828 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
829 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
830 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
831
832 private:
833 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
834 };
835
836 class NonLocalVarFunctionCallNode : public FunctionCallResolveNode {
837 public:
838 NonLocalVarFunctionCallNode(size_t depth) KJS_FAST_CALL
839 : FunctionCallResolveNode(PlacementNewAdopt)
840 {
841 m_scopeDepth = depth;
842 }
843
844 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
845 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
846 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
847 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
848 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
849
850 private:
851 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
852 };
853
854 class FunctionCallBracketNode : public ExpressionNode {
855 public:
856 FunctionCallBracketNode(ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args) KJS_FAST_CALL
857 : m_base(base)
858 , m_subscript(subscript)
859 , m_args(args)
860 {
861 }
862
863 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
864 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
865 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
866 virtual Precedence precedence() const { return PrecCall; }
867
868 protected:
869 RefPtr<ExpressionNode> m_base;
870 RefPtr<ExpressionNode> m_subscript;
871 RefPtr<ArgumentsNode> m_args;
872 };
873
874 class FunctionCallDotNode : public ExpressionNode {
875 public:
876 FunctionCallDotNode(ExpressionNode* base, const Identifier& ident, ArgumentsNode* args) KJS_FAST_CALL
877 : m_base(base)
878 , m_ident(ident)
879 , m_args(args)
880 {
881 }
882
883 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
884 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
885 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
886 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
887 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
888 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
889 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
890 virtual Precedence precedence() const { return PrecCall; }
891
892 private:
893 ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
894
895 RefPtr<ExpressionNode> m_base;
896 Identifier m_ident;
897 RefPtr<ArgumentsNode> m_args;
898 };
899
900 class PrePostResolveNode : public ExpressionNode {
901 public:
902 PrePostResolveNode(const Identifier& ident) KJS_FAST_CALL
903 : ExpressionNode(NumberType)
904 , m_ident(ident)
905 {
906 }
907
908 PrePostResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
909 : ExpressionNode(PlacementNewAdopt)
910 , m_ident(PlacementNewAdopt)
911 {
912 }
913
914 protected:
915 Identifier m_ident;
916 size_t m_index; // Used by LocalVarPostfixNode.
917 };
918
919 class PostIncResolveNode : public PrePostResolveNode {
920 public:
921 PostIncResolveNode(const Identifier& ident) KJS_FAST_CALL
922 : PrePostResolveNode(ident)
923 {
924 }
925
926 PostIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
927 : PrePostResolveNode(PlacementNewAdopt)
928 {
929 }
930
931 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
932 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
933 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
934 virtual Precedence precedence() const { return PrecPostfix; }
935 virtual void optimizeForUnnecessaryResult();
936 };
937
938 class PostIncLocalVarNode : public PostIncResolveNode {
939 public:
940 PostIncLocalVarNode(size_t i) KJS_FAST_CALL
941 : PostIncResolveNode(PlacementNewAdopt)
942 {
943 ASSERT(i != missingSymbolMarker());
944 m_index = i;
945 }
946
947 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
948 virtual void optimizeForUnnecessaryResult();
949 };
950
951 class PostIncConstNode : public PostIncResolveNode {
952 public:
953 PostIncConstNode(size_t i) KJS_FAST_CALL
954 : PostIncResolveNode(PlacementNewAdopt)
955 {
956 ASSERT(i != missingSymbolMarker());
957 m_index = i;
958 }
959
960 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
961 };
962
963 class PostDecResolveNode : public PrePostResolveNode {
964 public:
965 PostDecResolveNode(const Identifier& ident) KJS_FAST_CALL
966 : PrePostResolveNode(ident)
967 {
968 }
969
970 PostDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
971 : PrePostResolveNode(PlacementNewAdopt)
972 {
973 }
974
975 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
976 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
977 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
978 virtual Precedence precedence() const { return PrecPostfix; }
979 virtual void optimizeForUnnecessaryResult();
980 };
981
982 class PostDecLocalVarNode : public PostDecResolveNode {
983 public:
984 PostDecLocalVarNode(size_t i) KJS_FAST_CALL
985 : PostDecResolveNode(PlacementNewAdopt)
986 {
987 ASSERT(i != missingSymbolMarker());
988 m_index = i;
989 }
990
991 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
992 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
993 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
994 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
995 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
996 virtual void optimizeForUnnecessaryResult();
997
998 private:
999 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1000 };
1001
1002 class PostDecConstNode : public PostDecResolveNode {
1003 public:
1004 PostDecConstNode(size_t i) KJS_FAST_CALL
1005 : PostDecResolveNode(PlacementNewAdopt)
1006 {
1007 ASSERT(i != missingSymbolMarker());
1008 m_index = i;
1009 }
1010
1011 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1012 };
1013
1014 class PostfixBracketNode : public ExpressionNode {
1015 public:
1016 PostfixBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1017 : m_base(base)
1018 , m_subscript(subscript)
1019 {
1020 }
1021
1022 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1023 virtual Precedence precedence() const { return PrecPostfix; }
1024
1025 protected:
1026 RefPtr<ExpressionNode> m_base;
1027 RefPtr<ExpressionNode> m_subscript;
1028 };
1029
1030 class PostIncBracketNode : public PostfixBracketNode {
1031 public:
1032 PostIncBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1033 : PostfixBracketNode(base, subscript)
1034 {
1035 }
1036
1037 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1038 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1039 };
1040
1041 class PostDecBracketNode : public PostfixBracketNode {
1042 public:
1043 PostDecBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1044 : PostfixBracketNode(base, subscript)
1045 {
1046 }
1047
1048 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1049 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1050 };
1051
1052 class PostfixDotNode : public ExpressionNode {
1053 public:
1054 PostfixDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1055 : m_base(base)
1056 , m_ident(ident)
1057 {
1058 }
1059
1060 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1061 virtual Precedence precedence() const { return PrecPostfix; }
1062
1063 protected:
1064 RefPtr<ExpressionNode> m_base;
1065 Identifier m_ident;
1066 };
1067
1068 class PostIncDotNode : public PostfixDotNode {
1069 public:
1070 PostIncDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1071 : PostfixDotNode(base, ident)
1072 {
1073 }
1074
1075 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1076 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1077 };
1078
1079 class PostDecDotNode : public PostfixDotNode {
1080 public:
1081 PostDecDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1082 : PostfixDotNode(base, ident)
1083 {
1084 }
1085
1086 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1087 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1088 };
1089
1090 class PostfixErrorNode : public ExpressionNode {
1091 public:
1092 PostfixErrorNode(ExpressionNode* expr, Operator oper) KJS_FAST_CALL
1093 : m_expr(expr)
1094 , m_operator(oper)
1095 {
1096 }
1097
1098 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1099 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1100 virtual Precedence precedence() const { return PrecPostfix; }
1101
1102 private:
1103 RefPtr<ExpressionNode> m_expr;
1104 Operator m_operator;
1105 };
1106
1107 class DeleteResolveNode : public ExpressionNode {
1108 public:
1109 DeleteResolveNode(const Identifier& ident) KJS_FAST_CALL
1110 : m_ident(ident)
1111 {
1112 }
1113
1114 DeleteResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1115 : ExpressionNode(PlacementNewAdopt)
1116 , m_ident(PlacementNewAdopt)
1117 {
1118 }
1119
1120 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1121 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1122 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1123 virtual Precedence precedence() const { return PrecUnary; }
1124
1125 private:
1126 Identifier m_ident;
1127 };
1128
1129 class LocalVarDeleteNode : public DeleteResolveNode {
1130 public:
1131 LocalVarDeleteNode() KJS_FAST_CALL
1132 : DeleteResolveNode(PlacementNewAdopt)
1133 {
1134 }
1135
1136 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1137 };
1138
1139 class DeleteBracketNode : public ExpressionNode {
1140 public:
1141 DeleteBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1142 : m_base(base)
1143 , m_subscript(subscript)
1144 {
1145 }
1146
1147 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1148 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1149 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1150 virtual Precedence precedence() const { return PrecUnary; }
1151
1152 private:
1153 RefPtr<ExpressionNode> m_base;
1154 RefPtr<ExpressionNode> m_subscript;
1155 };
1156
1157 class DeleteDotNode : public ExpressionNode {
1158 public:
1159 DeleteDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1160 : m_base(base)
1161 , m_ident(ident)
1162 {
1163 }
1164
1165 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1166 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1167 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1168 virtual Precedence precedence() const { return PrecUnary; }
1169
1170 private:
1171 RefPtr<ExpressionNode> m_base;
1172 Identifier m_ident;
1173 };
1174
1175 class DeleteValueNode : public ExpressionNode {
1176 public:
1177 DeleteValueNode(ExpressionNode* expr) KJS_FAST_CALL
1178 : m_expr(expr)
1179 {
1180 }
1181
1182 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1183 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1184 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1185 virtual Precedence precedence() const { return PrecUnary; }
1186
1187 private:
1188 RefPtr<ExpressionNode> m_expr;
1189 };
1190
1191 class VoidNode : public ExpressionNode {
1192 public:
1193 VoidNode(ExpressionNode* expr) KJS_FAST_CALL
1194 : m_expr(expr)
1195 {
1196 }
1197
1198 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1199 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1200 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1201 virtual Precedence precedence() const { return PrecUnary; }
1202
1203 private:
1204 RefPtr<ExpressionNode> m_expr;
1205 };
1206
1207 class TypeOfResolveNode : public ExpressionNode {
1208 public:
1209 TypeOfResolveNode(const Identifier& ident) KJS_FAST_CALL
1210 : ExpressionNode(StringType)
1211 , m_ident(ident)
1212 {
1213 }
1214
1215 TypeOfResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1216 : ExpressionNode(PlacementNewAdopt)
1217 , m_ident(PlacementNewAdopt)
1218 {
1219 m_expectedReturnType = StringType;
1220 }
1221
1222 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1223
1224 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1225 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1226 virtual Precedence precedence() const { return PrecUnary; }
1227
1228 const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
1229
1230 protected:
1231 Identifier m_ident;
1232 size_t m_index; // Used by LocalTypeOfNode.
1233 };
1234
1235 class LocalVarTypeOfNode : public TypeOfResolveNode {
1236 public:
1237 LocalVarTypeOfNode(size_t i) KJS_FAST_CALL
1238 : TypeOfResolveNode(PlacementNewAdopt)
1239 {
1240 m_expectedReturnType = StringType;
1241 ASSERT(i != missingSymbolMarker());
1242 m_index = i;
1243 }
1244
1245 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1246 };
1247
1248 class TypeOfValueNode : public ExpressionNode {
1249 public:
1250 TypeOfValueNode(ExpressionNode* expr) KJS_FAST_CALL
1251 : ExpressionNode(StringType)
1252 , m_expr(expr)
1253 {
1254 }
1255
1256 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1257 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1258 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1259 virtual Precedence precedence() const { return PrecUnary; }
1260
1261 private:
1262 RefPtr<ExpressionNode> m_expr;
1263 };
1264
1265 class PreIncResolveNode : public PrePostResolveNode {
1266 public:
1267 PreIncResolveNode(const Identifier& ident) KJS_FAST_CALL
1268 : PrePostResolveNode(ident)
1269 {
1270 }
1271
1272 PreIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1273 : PrePostResolveNode(PlacementNewAdopt)
1274 {
1275 }
1276
1277 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1278
1279 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1280 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1281 virtual Precedence precedence() const { return PrecUnary; }
1282 };
1283
1284 class PreIncLocalVarNode : public PreIncResolveNode {
1285 public:
1286 PreIncLocalVarNode(size_t i) KJS_FAST_CALL
1287 : PreIncResolveNode(PlacementNewAdopt)
1288 {
1289 ASSERT(i != missingSymbolMarker());
1290 m_index = i;
1291 }
1292
1293 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1294 };
1295
1296 class PreIncConstNode : public PreIncResolveNode {
1297 public:
1298 PreIncConstNode(size_t i) KJS_FAST_CALL
1299 : PreIncResolveNode(PlacementNewAdopt)
1300 {
1301 ASSERT(i != missingSymbolMarker());
1302 m_index = i;
1303 }
1304
1305 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1306 };
1307
1308 class PreDecResolveNode : public PrePostResolveNode {
1309 public:
1310 PreDecResolveNode(const Identifier& ident) KJS_FAST_CALL
1311 : PrePostResolveNode(ident)
1312 {
1313 }
1314
1315 PreDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1316 : PrePostResolveNode(PlacementNewAdopt)
1317 {
1318 }
1319
1320 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1321
1322 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1323 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1324 virtual Precedence precedence() const { return PrecUnary; }
1325 };
1326
1327 class PreDecLocalVarNode : public PreDecResolveNode {
1328 public:
1329 PreDecLocalVarNode(size_t i) KJS_FAST_CALL
1330 : PreDecResolveNode(PlacementNewAdopt)
1331 {
1332 ASSERT(i != missingSymbolMarker());
1333 m_index = i;
1334 }
1335
1336 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1337 };
1338
1339 class PreDecConstNode : public PreDecResolveNode {
1340 public:
1341 PreDecConstNode(size_t i) KJS_FAST_CALL
1342 : PreDecResolveNode(PlacementNewAdopt)
1343 {
1344 ASSERT(i != missingSymbolMarker());
1345 m_index = i;
1346 }
1347
1348 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1349 };
1350
1351 class PrefixBracketNode : public ExpressionNode {
1352 public:
1353 PrefixBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1354 : m_base(base)
1355 , m_subscript(subscript)
1356 {
1357 }
1358
1359 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1360 virtual Precedence precedence() const { return PrecUnary; }
1361
1362 protected:
1363 RefPtr<ExpressionNode> m_base;
1364 RefPtr<ExpressionNode> m_subscript;
1365 };
1366
1367 class PreIncBracketNode : public PrefixBracketNode {
1368 public:
1369 PreIncBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1370 : PrefixBracketNode(base, subscript)
1371 {
1372 }
1373
1374 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1375 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1376 };
1377
1378 class PreDecBracketNode : public PrefixBracketNode {
1379 public:
1380 PreDecBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1381 : PrefixBracketNode(base, subscript)
1382 {
1383 }
1384
1385 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1386 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1387 };
1388
1389 class PrefixDotNode : public ExpressionNode {
1390 public:
1391 PrefixDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1392 : m_base(base)
1393 , m_ident(ident)
1394 {
1395 }
1396
1397 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1398 virtual Precedence precedence() const { return PrecPostfix; }
1399
1400 protected:
1401 RefPtr<ExpressionNode> m_base;
1402 Identifier m_ident;
1403 };
1404
1405 class PreIncDotNode : public PrefixDotNode {
1406 public:
1407 PreIncDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1408 : PrefixDotNode(base, ident)
1409 {
1410 }
1411
1412 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1413 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1414 };
1415
1416 class PreDecDotNode : public PrefixDotNode {
1417 public:
1418 PreDecDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1419 : PrefixDotNode(base, ident)
1420 {
1421 }
1422
1423 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1424 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1425 };
1426
1427 class PrefixErrorNode : public ExpressionNode {
1428 public:
1429 PrefixErrorNode(ExpressionNode* expr, Operator oper) KJS_FAST_CALL
1430 : m_expr(expr)
1431 , m_operator(oper)
1432 {
1433 }
1434
1435 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1436 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1437 virtual Precedence precedence() const { return PrecUnary; }
1438
1439 private:
1440 RefPtr<ExpressionNode> m_expr;
1441 Operator m_operator;
1442 };
1443
1444 class UnaryPlusNode : public ExpressionNode {
1445 public:
1446 UnaryPlusNode(ExpressionNode* expr) KJS_FAST_CALL
1447 : ExpressionNode(NumberType)
1448 , m_expr(expr)
1449 {
1450 }
1451
1452 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1453 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1454 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1455 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1456 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1457 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1458 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1459 virtual Precedence precedence() const { return PrecUnary; }
1460
1461 private:
1462 RefPtr<ExpressionNode> m_expr;
1463 };
1464
1465 class NegateNode : public ExpressionNode {
1466 public:
1467 NegateNode(ExpressionNode* expr) KJS_FAST_CALL
1468 : ExpressionNode(NumberType)
1469 , m_expr(expr)
1470 {
1471 }
1472
1473 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1474 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1475 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1476 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1477 virtual Precedence precedence() const { return PrecUnary; }
1478
1479 private:
1480 RefPtr<ExpressionNode> m_expr;
1481 };
1482
1483 class BitwiseNotNode : public ExpressionNode {
1484 public:
1485 BitwiseNotNode(ExpressionNode* expr) KJS_FAST_CALL
1486 : ExpressionNode(NumberType)
1487 , m_expr(expr)
1488 {
1489 }
1490
1491 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1492 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1493 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1494 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1495 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1496 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1497 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1498 virtual Precedence precedence() const { return PrecUnary; }
1499
1500 private:
1501 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1502
1503 RefPtr<ExpressionNode> m_expr;
1504 };
1505
1506 class LogicalNotNode : public ExpressionNode {
1507 public:
1508 LogicalNotNode(ExpressionNode* expr) KJS_FAST_CALL
1509 : ExpressionNode(BooleanType)
1510 , m_expr(expr)
1511 {
1512 }
1513
1514 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1515 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1516 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1517 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1518 virtual Precedence precedence() const { return PrecUnary; }
1519
1520 private:
1521 RefPtr<ExpressionNode> m_expr;
1522 };
1523
1524 class MultNode : public ExpressionNode {
1525 public:
1526 MultNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1527 : ExpressionNode(NumberType)
1528 , m_term1(term1)
1529 , m_term2(term2)
1530 {
1531 }
1532
1533 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1534 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1535 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1536 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1537 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1538 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1539 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1540 virtual Precedence precedence() const { return PrecMultiplicitave; }
1541
1542 private:
1543 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1544
1545 RefPtr<ExpressionNode> m_term1;
1546 RefPtr<ExpressionNode> m_term2;
1547 };
1548
1549 class DivNode : public ExpressionNode {
1550 public:
1551 DivNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1552 : ExpressionNode(NumberType)
1553 , m_term1(term1)
1554 , m_term2(term2)
1555 {
1556 }
1557
1558 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1559 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1560 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1561 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1562 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1563 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1564 virtual Precedence precedence() const { return PrecMultiplicitave; }
1565
1566 private:
1567 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1568
1569 RefPtr<ExpressionNode> m_term1;
1570 RefPtr<ExpressionNode> m_term2;
1571 };
1572
1573 class ModNode : public ExpressionNode {
1574 public:
1575 ModNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1576 : ExpressionNode(NumberType)
1577 , m_term1(term1)
1578 , m_term2(term2)
1579 {
1580 }
1581
1582 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1583 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1584 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1585 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1586 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1587 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1588 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1589 virtual Precedence precedence() const { return PrecMultiplicitave; }
1590
1591 private:
1592 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1593
1594 RefPtr<ExpressionNode> m_term1;
1595 RefPtr<ExpressionNode> m_term2;
1596 };
1597
1598 class AddNode : public ExpressionNode {
1599 public:
1600 AddNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1601 : m_term1(term1)
1602 , m_term2(term2)
1603 {
1604 }
1605
1606 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1607 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1608 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1609 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1610 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1611 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1612 virtual Precedence precedence() const { return PrecAdditive; }
1613
1614 protected:
1615 AddNode(ExpressionNode* term1, ExpressionNode* term2, JSType expectedReturn) KJS_FAST_CALL
1616 : ExpressionNode(expectedReturn)
1617 , m_term1(term1)
1618 , m_term2(term2)
1619 {
1620 }
1621
1622 RefPtr<ExpressionNode> m_term1;
1623 RefPtr<ExpressionNode> m_term2;
1624
1625 private:
1626 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1627 };
1628
1629 class AddNumbersNode : public AddNode {
1630 public:
1631 AddNumbersNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1632 : AddNode(term1, term2, NumberType)
1633 {
1634 }
1635
1636 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1637 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1638 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1639 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1640
1641 private:
1642 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*) KJS_FAST_CALL;
1643 };
1644
1645 class AddStringLeftNode : public AddNode {
1646 public:
1647 AddStringLeftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1648 : AddNode(term1, term2, StringType)
1649 {
1650 }
1651
1652 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1653 };
1654
1655 class AddStringRightNode : public AddNode {
1656 public:
1657 AddStringRightNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1658 : AddNode(term1, term2, StringType)
1659 {
1660 }
1661
1662 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1663 };
1664
1665 class AddStringsNode : public AddNode {
1666 public:
1667 AddStringsNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1668 : AddNode(term1, term2, StringType)
1669 {
1670 }
1671
1672 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1673 };
1674
1675 class SubNode : public ExpressionNode {
1676 public:
1677 SubNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1678 : ExpressionNode(NumberType)
1679 , m_term1(term1)
1680 , m_term2(term2)
1681 {
1682 }
1683
1684 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1685 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1686 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1687 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1688 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1689 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1690 virtual Precedence precedence() const { return PrecAdditive; }
1691
1692 private:
1693 ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1694
1695 RefPtr<ExpressionNode> m_term1;
1696 RefPtr<ExpressionNode> m_term2;
1697 };
1698
1699 class LeftShiftNode : public ExpressionNode {
1700 public:
1701 LeftShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1702 : ExpressionNode(NumberType)
1703 , m_term1(term1)
1704 , m_term2(term2)
1705 {
1706 }
1707
1708 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1709 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1710 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1711 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1712 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1713 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1714 virtual Precedence precedence() const { return PrecShift; }
1715
1716 private:
1717 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1718
1719 RefPtr<ExpressionNode> m_term1;
1720 RefPtr<ExpressionNode> m_term2;
1721 };
1722
1723 class RightShiftNode : public ExpressionNode {
1724 public:
1725 RightShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1726 : ExpressionNode(NumberType)
1727 , m_term1(term1)
1728 , m_term2(term2)
1729 {
1730 }
1731
1732 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1733 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1734 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1735 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1736 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1737 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1738 virtual Precedence precedence() const { return PrecShift; }
1739
1740 private:
1741 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1742
1743 RefPtr<ExpressionNode> m_term1;
1744 RefPtr<ExpressionNode> m_term2;
1745 };
1746
1747 class UnsignedRightShiftNode : public ExpressionNode {
1748 public:
1749 UnsignedRightShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1750 : ExpressionNode(NumberType)
1751 , m_term1(term1)
1752 , m_term2(term2)
1753 {
1754 }
1755
1756 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1757 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1758 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1759 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1760 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1761 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1762 virtual Precedence precedence() const { return PrecShift; }
1763 private:
1764 ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(ExecState*);
1765
1766 RefPtr<ExpressionNode> m_term1;
1767 RefPtr<ExpressionNode> m_term2;
1768 };
1769
1770 class LessNode : public ExpressionNode {
1771 public:
1772 LessNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1773 : ExpressionNode(BooleanType)
1774 , m_expr1(expr1)
1775 , m_expr2(expr2)
1776 {
1777 }
1778
1779 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1780 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1781 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1782 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1783 virtual Precedence precedence() const { return PrecRelational; }
1784
1785 private:
1786 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1787
1788 protected:
1789 RefPtr<ExpressionNode> m_expr1;
1790 RefPtr<ExpressionNode> m_expr2;
1791 };
1792
1793 class LessNumbersNode : public LessNode {
1794 public:
1795 LessNumbersNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1796 : LessNode(expr1, expr2)
1797 {
1798 }
1799
1800 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1801 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1802
1803 private:
1804 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1805 };
1806
1807 class LessStringsNode : public LessNode {
1808 public:
1809 LessStringsNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1810 : LessNode(expr1, expr2)
1811 {
1812 }
1813
1814 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1815 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1816
1817 private:
1818 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1819 };
1820
1821 class GreaterNode : public ExpressionNode {
1822 public:
1823 GreaterNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1824 : m_expr1(expr1)
1825 , m_expr2(expr2)
1826 {
1827 }
1828
1829 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1830 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1831 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1832 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1833 virtual Precedence precedence() const { return PrecRelational; }
1834
1835 private:
1836 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1837
1838 RefPtr<ExpressionNode> m_expr1;
1839 RefPtr<ExpressionNode> m_expr2;
1840 };
1841
1842 class LessEqNode : public ExpressionNode {
1843 public:
1844 LessEqNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1845 : m_expr1(expr1)
1846 , m_expr2(expr2)
1847 {
1848 }
1849
1850 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1851 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1852 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1853 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1854 virtual Precedence precedence() const { return PrecRelational; }
1855
1856 private:
1857 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1858
1859 RefPtr<ExpressionNode> m_expr1;
1860 RefPtr<ExpressionNode> m_expr2;
1861 };
1862
1863 class GreaterEqNode : public ExpressionNode {
1864 public:
1865 GreaterEqNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1866 : m_expr1(expr1)
1867 , m_expr2(expr2)
1868 {
1869 }
1870
1871 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1872 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1873 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1874 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1875 virtual Precedence precedence() const { return PrecRelational; }
1876
1877 private:
1878 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1879
1880 RefPtr<ExpressionNode> m_expr1;
1881 RefPtr<ExpressionNode> m_expr2;
1882 };
1883
1884 class InstanceOfNode : public ExpressionNode {
1885 public:
1886 InstanceOfNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1887 : ExpressionNode(BooleanType)
1888 , m_expr1(expr1)
1889 , m_expr2(expr2)
1890 {
1891 }
1892
1893 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1894 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1895 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1896 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1897 virtual Precedence precedence() const { return PrecRelational; }
1898
1899 private:
1900 RefPtr<ExpressionNode> m_expr1;
1901 RefPtr<ExpressionNode> m_expr2;
1902 };
1903
1904 class InNode : public ExpressionNode {
1905 public:
1906 InNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1907 : m_expr1(expr1)
1908 , m_expr2(expr2)
1909 {
1910 }
1911
1912 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1913 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1914 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1915 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1916 virtual Precedence precedence() const { return PrecRelational; }
1917
1918 private:
1919 RefPtr<ExpressionNode> m_expr1;
1920 RefPtr<ExpressionNode> m_expr2;
1921 };
1922
1923 class EqualNode : public ExpressionNode {
1924 public:
1925 EqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1926 : ExpressionNode(BooleanType)
1927 , m_expr1(expr1)
1928 , m_expr2(expr2)
1929 {
1930 }
1931
1932 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1933 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1934 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1935 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1936 virtual Precedence precedence() const { return PrecEquality; }
1937
1938 private:
1939 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1940
1941 RefPtr<ExpressionNode> m_expr1;
1942 RefPtr<ExpressionNode> m_expr2;
1943 };
1944
1945 class NotEqualNode : public ExpressionNode {
1946 public:
1947 NotEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1948 : ExpressionNode(BooleanType)
1949 , m_expr1(expr1)
1950 , m_expr2(expr2)
1951 {
1952 }
1953
1954 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1955 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1956 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1957 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1958 virtual Precedence precedence() const { return PrecEquality; }
1959
1960 private:
1961 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1962
1963 RefPtr<ExpressionNode> m_expr1;
1964 RefPtr<ExpressionNode> m_expr2;
1965 };
1966
1967 class StrictEqualNode : public ExpressionNode {
1968 public:
1969 StrictEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1970 : ExpressionNode(BooleanType)
1971 , m_expr1(expr1)
1972 , m_expr2(expr2)
1973 {
1974 }
1975
1976 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1977 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1978 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1979 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1980 virtual Precedence precedence() const { return PrecEquality; }
1981
1982 private:
1983 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1984
1985 RefPtr<ExpressionNode> m_expr1;
1986 RefPtr<ExpressionNode> m_expr2;
1987 };
1988
1989 class NotStrictEqualNode : public ExpressionNode {
1990 public:
1991 NotStrictEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1992 : ExpressionNode(BooleanType)
1993 , m_expr1(expr1)
1994 , m_expr2(expr2)
1995 {
1996 }
1997
1998 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1999 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2000 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2001 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2002 virtual Precedence precedence() const { return PrecEquality; }
2003
2004 private:
2005 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
2006
2007 RefPtr<ExpressionNode> m_expr1;
2008 RefPtr<ExpressionNode> m_expr2;
2009 };
2010
2011 class BitAndNode : public ExpressionNode {
2012 public:
2013 BitAndNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2014 : ExpressionNode(NumberType)
2015 , m_expr1(expr1)
2016 , m_expr2(expr2)
2017 {
2018 }
2019
2020 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2021 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2022 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
2023 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2024 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
2025 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
2026 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2027 virtual Precedence precedence() const { return PrecBitwiseAnd; }
2028
2029 private:
2030 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
2031
2032 RefPtr<ExpressionNode> m_expr1;
2033 RefPtr<ExpressionNode> m_expr2;
2034 };
2035
2036 class BitOrNode : public ExpressionNode {
2037 public:
2038 BitOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2039 : ExpressionNode(NumberType)
2040 , m_expr1(expr1)
2041 , m_expr2(expr2)
2042 {
2043 }
2044
2045 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2046 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2047 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
2048 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2049 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
2050 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
2051 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2052 virtual Precedence precedence() const { return PrecBitwiseOr; }
2053
2054 private:
2055 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
2056
2057 RefPtr<ExpressionNode> m_expr1;
2058 RefPtr<ExpressionNode> m_expr2;
2059 };
2060
2061 class BitXOrNode : public ExpressionNode {
2062 public:
2063 BitXOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2064 : ExpressionNode(NumberType)
2065 , m_expr1(expr1)
2066 , m_expr2(expr2)
2067 {
2068 }
2069
2070 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2071 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2072 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
2073 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2074 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
2075 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
2076 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2077 virtual Precedence precedence() const { return PrecBitwiseXor; }
2078
2079 private:
2080 ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
2081
2082 RefPtr<ExpressionNode> m_expr1;
2083 RefPtr<ExpressionNode> m_expr2;
2084 };
2085
2086 /**
2087 * m_expr1 && m_expr2, m_expr1 || m_expr2
2088 */
2089 class LogicalAndNode : public ExpressionNode {
2090 public:
2091 LogicalAndNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2092 : ExpressionNode(BooleanType)
2093 , m_expr1(expr1)
2094 , m_expr2(expr2)
2095 {
2096 }
2097
2098 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2099 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2100 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2101 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2102 virtual Precedence precedence() const { return PrecLogicalAnd; }
2103
2104 private:
2105 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
2106
2107 RefPtr<ExpressionNode> m_expr1;
2108 RefPtr<ExpressionNode> m_expr2;
2109 };
2110
2111 class LogicalOrNode : public ExpressionNode {
2112 public:
2113 LogicalOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2114 : ExpressionNode(BooleanType)
2115 , m_expr1(expr1)
2116 , m_expr2(expr2)
2117 {
2118 }
2119
2120 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2121 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2122 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2123 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2124 virtual Precedence precedence() const { return PrecLogicalOr; }
2125
2126 private:
2127 ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
2128
2129 RefPtr<ExpressionNode> m_expr1;
2130 RefPtr<ExpressionNode> m_expr2;
2131 };
2132
2133 /**
2134 * The ternary operator, "m_logical ? m_expr1 : m_expr2"
2135 */
2136 class ConditionalNode : public ExpressionNode {
2137 public:
2138 ConditionalNode(ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2139 : m_logical(logical)
2140 , m_expr1(expr1)
2141 , m_expr2(expr2)
2142 {
2143 }
2144
2145 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2146 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2147 virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2148 virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
2149 virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
2150 virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
2151 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2152 virtual Precedence precedence() const { return PrecConditional; }
2153
2154 private:
2155 RefPtr<ExpressionNode> m_logical;
2156 RefPtr<ExpressionNode> m_expr1;
2157 RefPtr<ExpressionNode> m_expr2;
2158 };
2159
2160 class ReadModifyResolveNode : public ExpressionNode {
2161 public:
2162 ReadModifyResolveNode(const Identifier& ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL
2163 : m_ident(ident)
2164 , m_operator(oper)
2165 , m_right(right)
2166 {
2167 }
2168
2169 ReadModifyResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
2170 : ExpressionNode(PlacementNewAdopt)
2171 , m_ident(PlacementNewAdopt)
2172 , m_right(PlacementNewAdopt)
2173 {
2174 }
2175
2176 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2177 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2178 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2179 virtual Precedence precedence() const { return PrecAssignment; }
2180
2181 protected:
2182 Identifier m_ident;
2183 Operator m_operator;
2184 RefPtr<ExpressionNode> m_right;
2185 size_t m_index; // Used by ReadModifyLocalVarNode.
2186 };
2187
2188 class ReadModifyLocalVarNode : public ReadModifyResolveNode {
2189 public:
2190 ReadModifyLocalVarNode(size_t i) KJS_FAST_CALL
2191 : ReadModifyResolveNode(PlacementNewAdopt)
2192 {
2193 ASSERT(i != missingSymbolMarker());
2194 m_index = i;
2195 }
2196
2197 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2198 };
2199
2200 class ReadModifyConstNode : public ReadModifyResolveNode {
2201 public:
2202 ReadModifyConstNode(size_t i) KJS_FAST_CALL
2203 : ReadModifyResolveNode(PlacementNewAdopt)
2204 {
2205 ASSERT(i != missingSymbolMarker());
2206 m_index = i;
2207 }
2208
2209 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2210 };
2211
2212 class AssignResolveNode : public ExpressionNode {
2213 public:
2214 AssignResolveNode(const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL
2215 : m_ident(ident)
2216 , m_right(right)
2217 {
2218 }
2219
2220 AssignResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
2221 : ExpressionNode(PlacementNewAdopt)
2222 , m_ident(PlacementNewAdopt)
2223 , m_right(PlacementNewAdopt)
2224 {
2225 }
2226
2227 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2228 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2229 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2230 virtual Precedence precedence() const { return PrecAssignment; }
2231
2232 protected:
2233 Identifier m_ident;
2234 RefPtr<ExpressionNode> m_right;
2235 size_t m_index; // Used by ReadModifyLocalVarNode.
2236 };
2237
2238 class AssignLocalVarNode : public AssignResolveNode {
2239 public:
2240 AssignLocalVarNode(size_t i) KJS_FAST_CALL
2241 : AssignResolveNode(PlacementNewAdopt)
2242 {
2243 ASSERT(i != missingSymbolMarker());
2244 m_index = i;
2245 }
2246
2247 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2248 };
2249
2250 class AssignConstNode : public AssignResolveNode {
2251 public:
2252 AssignConstNode() KJS_FAST_CALL
2253 : AssignResolveNode(PlacementNewAdopt)
2254 {
2255 }
2256
2257 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2258 };
2259
2260 class ReadModifyBracketNode : public ExpressionNode {
2261 public:
2262 ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right) KJS_FAST_CALL
2263 : m_base(base)
2264 , m_subscript(subscript)
2265 , m_operator(oper)
2266 , m_right(right)
2267 {
2268 }
2269
2270 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2271 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2272 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2273 virtual Precedence precedence() const { return PrecAssignment; }
2274
2275 protected:
2276 RefPtr<ExpressionNode> m_base;
2277 RefPtr<ExpressionNode> m_subscript;
2278 Operator m_operator;
2279 RefPtr<ExpressionNode> m_right;
2280 };
2281
2282 class AssignBracketNode : public ExpressionNode {
2283 public:
2284 AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right) KJS_FAST_CALL
2285 : m_base(base)
2286 , m_subscript(subscript)
2287 , m_right(right)
2288 {
2289 }
2290
2291 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2292 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2293 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2294 virtual Precedence precedence() const { return PrecAssignment; }
2295
2296 protected:
2297 RefPtr<ExpressionNode> m_base;
2298 RefPtr<ExpressionNode> m_subscript;
2299 RefPtr<ExpressionNode> m_right;
2300 };
2301
2302 class AssignDotNode : public ExpressionNode {
2303 public:
2304 AssignDotNode(ExpressionNode* base, const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL
2305 : m_base(base)
2306 , m_ident(ident)
2307 , m_right(right)
2308 {
2309 }
2310
2311 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2312 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2313 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2314 virtual Precedence precedence() const { return PrecAssignment; }
2315
2316 protected:
2317 RefPtr<ExpressionNode> m_base;
2318 Identifier m_ident;
2319 RefPtr<ExpressionNode> m_right;
2320 };
2321
2322 class ReadModifyDotNode : public ExpressionNode {
2323 public:
2324 ReadModifyDotNode(ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL
2325 : m_base(base)
2326 , m_ident(ident)
2327 , m_operator(oper)
2328 , m_right(right)
2329 {
2330 }
2331
2332 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2333 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2334 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2335 virtual Precedence precedence() const { return PrecAssignment; }
2336
2337 protected:
2338 RefPtr<ExpressionNode> m_base;
2339 Identifier m_ident;
2340 Operator m_operator;
2341 RefPtr<ExpressionNode> m_right;
2342 };
2343
2344 class AssignErrorNode : public ExpressionNode {
2345 public:
2346 AssignErrorNode(ExpressionNode* left, Operator oper, ExpressionNode* right) KJS_FAST_CALL
2347 : m_left(left)
2348 , m_operator(oper)
2349 , m_right(right)
2350 {
2351 }
2352
2353 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2354 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2355 virtual Precedence precedence() const { return PrecAssignment; }
2356
2357 protected:
2358 RefPtr<ExpressionNode> m_left;
2359 Operator m_operator;
2360 RefPtr<ExpressionNode> m_right;
2361 };
2362
2363 class CommaNode : public ExpressionNode {
2364 public:
2365 CommaNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2366 : m_expr1(expr1)
2367 , m_expr2(expr2)
2368 {
2369 m_expr1->optimizeForUnnecessaryResult();
2370 }
2371
2372 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2373 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2374 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2375 virtual Precedence precedence() const { return PrecExpression; }
2376
2377 private:
2378 RefPtr<ExpressionNode> m_expr1;
2379 RefPtr<ExpressionNode> m_expr2;
2380 };
2381
2382 class VarDeclCommaNode : public CommaNode {
2383 public:
2384 VarDeclCommaNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2385 : CommaNode(expr1, expr2)
2386 {
2387 }
2388 virtual Precedence precedence() const { return PrecAssignment; }
2389 };
2390
2391 class ConstDeclNode : public ExpressionNode {
2392 public:
2393 ConstDeclNode(const Identifier& ident, ExpressionNode* in) KJS_FAST_CALL;
2394
2395 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2396 virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2397 void evaluateSingle(ExecState*) KJS_FAST_CALL;
2398 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2399 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2400 PassRefPtr<ConstDeclNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
2401
2402 Identifier m_ident;
2403 ListRefPtr<ConstDeclNode> m_next;
2404 RefPtr<ExpressionNode> m_init;
2405
2406 private:
2407 void handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL NEVER_INLINE;
2408 };
2409
2410 class ConstStatementNode : public StatementNode {
2411 public:
2412 ConstStatementNode(ConstDeclNode* next) KJS_FAST_CALL
2413 : m_next(next)
2414 {
2415 }
2416
2417 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2418 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2419 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2420
2421 private:
2422 RefPtr<ConstDeclNode> m_next;
2423 };
2424
2425 typedef Vector<RefPtr<StatementNode> > StatementVector;
2426
2427 class SourceElements : public ParserRefCounted {
2428 public:
2429 void append(PassRefPtr<StatementNode>);
2430 void releaseContentsIntoVector(StatementVector& destination)
2431 {
2432 ASSERT(destination.isEmpty());
2433 m_statements.swap(destination);
2434 }
2435
2436 private:
2437 StatementVector m_statements;
2438 };
2439
2440 class BlockNode : public StatementNode {
2441 public:
2442 BlockNode(SourceElements* children) KJS_FAST_CALL;
2443
2444 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2445 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2446 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2447
2448 protected:
2449 StatementVector m_children;
2450 };
2451
2452 class EmptyStatementNode : public StatementNode {
2453 public:
2454 EmptyStatementNode() KJS_FAST_CALL // debug
2455 {
2456 }
2457
2458 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2459 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2460 virtual bool isEmptyStatement() const KJS_FAST_CALL { return true; }
2461 };
2462
2463 class ExprStatementNode : public StatementNode {
2464 public:
2465 ExprStatementNode(ExpressionNode* expr) KJS_FAST_CALL
2466 : m_expr(expr)
2467 {
2468 }
2469
2470 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2471 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2472 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2473
2474 private:
2475 RefPtr<ExpressionNode> m_expr;
2476 };
2477
2478 class VarStatementNode : public StatementNode {
2479 public:
2480 VarStatementNode(ExpressionNode* expr) KJS_FAST_CALL
2481 : m_expr(expr)
2482 {
2483 }
2484
2485 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2486 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2487 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2488
2489 private:
2490 RefPtr<ExpressionNode> m_expr;
2491 };
2492
2493 class IfNode : public StatementNode {
2494 public:
2495 IfNode(ExpressionNode* condition, StatementNode* ifBlock) KJS_FAST_CALL
2496 : m_condition(condition)
2497 , m_ifBlock(ifBlock)
2498 {
2499 }
2500
2501 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2502 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2503 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2504
2505 protected:
2506 RefPtr<ExpressionNode> m_condition;
2507 RefPtr<StatementNode> m_ifBlock;
2508 };
2509
2510 class IfElseNode : public IfNode {
2511 public:
2512 IfElseNode(ExpressionNode* condtion, StatementNode* ifBlock, StatementNode* elseBlock) KJS_FAST_CALL
2513 : IfNode(condtion, ifBlock)
2514 , m_elseBlock(elseBlock)
2515 {
2516 }
2517
2518 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2519 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2520 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2521
2522 private:
2523 RefPtr<StatementNode> m_elseBlock;
2524 };
2525
2526 class DoWhileNode : public StatementNode {
2527 public:
2528 DoWhileNode(StatementNode* statement, ExpressionNode* expr) KJS_FAST_CALL
2529 : m_statement(statement)
2530 , m_expr(expr)
2531 {
2532 }
2533
2534 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2535 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2536 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2537
2538 private:
2539 RefPtr<StatementNode> m_statement;
2540 RefPtr<ExpressionNode> m_expr;
2541 };
2542
2543 class WhileNode : public StatementNode {
2544 public:
2545 WhileNode(ExpressionNode* expr, StatementNode* statement) KJS_FAST_CALL
2546 : m_expr(expr)
2547 , m_statement(statement)
2548 {
2549 }
2550
2551 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2552 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2553 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2554
2555 private:
2556 RefPtr<ExpressionNode> m_expr;
2557 RefPtr<StatementNode> m_statement;
2558 };
2559
2560 class ForNode : public StatementNode {
2561 public:
2562 ForNode(ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl) KJS_FAST_CALL
2563 : m_expr1(expr1 ? expr1 : new PlaceholderTrueNode)
2564 , m_expr2(expr2 ? expr2 : new PlaceholderTrueNode)
2565 , m_expr3(expr3 ? expr3 : new PlaceholderTrueNode)
2566 , m_statement(statement)
2567 , m_expr1WasVarDecl(expr1 && expr1WasVarDecl)
2568 {
2569 ASSERT(m_expr1);
2570 ASSERT(m_expr2);
2571 ASSERT(m_expr3);
2572 ASSERT(statement);
2573
2574 m_expr1->optimizeForUnnecessaryResult();
2575 m_expr3->optimizeForUnnecessaryResult();
2576 }
2577
2578 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2579 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2580 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2581
2582 private:
2583 RefPtr<ExpressionNode> m_expr1;
2584 RefPtr<ExpressionNode> m_expr2;
2585 RefPtr<ExpressionNode> m_expr3;
2586 RefPtr<StatementNode> m_statement;
2587 bool m_expr1WasVarDecl;
2588 };
2589
2590 class ForInNode : public StatementNode {
2591 public:
2592 ForInNode(ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL;
2593 ForInNode(const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL;
2594
2595 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2596 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2597 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2598
2599 private:
2600 Identifier m_ident;
2601 RefPtr<ExpressionNode> m_init;
2602 RefPtr<ExpressionNode> m_lexpr;
2603 RefPtr<ExpressionNode> m_expr;
2604 RefPtr<StatementNode> m_statement;
2605 bool m_identIsVarDecl;
2606 };
2607
2608 class ContinueNode : public StatementNode {
2609 public:
2610 ContinueNode() KJS_FAST_CALL
2611 {
2612 }
2613
2614 ContinueNode(const Identifier& ident) KJS_FAST_CALL
2615 : m_ident(ident)
2616 {
2617 }
2618
2619 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2620 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2621
2622 private:
2623 Identifier m_ident;
2624 };
2625
2626 class BreakNode : public StatementNode {
2627 public:
2628 BreakNode() KJS_FAST_CALL
2629 {
2630 }
2631
2632 BreakNode(const Identifier& ident) KJS_FAST_CALL
2633 : m_ident(ident)
2634 {
2635 }
2636
2637 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2638 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2639
2640 private:
2641 Identifier m_ident;
2642 };
2643
2644 class ReturnNode : public StatementNode {
2645 public:
2646 ReturnNode(ExpressionNode* value) KJS_FAST_CALL
2647 : m_value(value)
2648 {
2649 }
2650
2651 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2652 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2653 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2654
2655 private:
2656 RefPtr<ExpressionNode> m_value;
2657 };
2658
2659 class WithNode : public StatementNode {
2660 public:
2661 WithNode(ExpressionNode* expr, StatementNode* statement) KJS_FAST_CALL
2662 : m_expr(expr)
2663 , m_statement(statement)
2664 {
2665 }
2666
2667 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2668 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2669 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2670
2671 private:
2672 RefPtr<ExpressionNode> m_expr;
2673 RefPtr<StatementNode> m_statement;
2674 };
2675
2676 class LabelNode : public StatementNode {
2677 public:
2678 LabelNode(const Identifier& label, StatementNode* statement) KJS_FAST_CALL
2679 : m_label(label)
2680 , m_statement(statement)
2681 {
2682 }
2683
2684 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2685 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2686 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2687 virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_statement->pushLabel(ident); }
2688
2689 private:
2690 Identifier m_label;
2691 RefPtr<StatementNode> m_statement;
2692 };
2693
2694 class ThrowNode : public StatementNode {
2695 public:
2696 ThrowNode(ExpressionNode* expr) KJS_FAST_CALL
2697 : m_expr(expr)
2698 {
2699 }
2700
2701 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2702 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2703 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2704
2705 private:
2706 RefPtr<ExpressionNode> m_expr;
2707 };
2708
2709 class TryNode : public StatementNode {
2710 public:
2711 TryNode(StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock) KJS_FAST_CALL
2712 : m_tryBlock(tryBlock)
2713 , m_exceptionIdent(exceptionIdent)
2714 , m_catchBlock(catchBlock)
2715 , m_finallyBlock(finallyBlock)
2716 {
2717 }
2718
2719 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2720 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2721 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2722
2723 private:
2724 RefPtr<StatementNode> m_tryBlock;
2725 Identifier m_exceptionIdent;
2726 RefPtr<StatementNode> m_catchBlock;
2727 RefPtr<StatementNode> m_finallyBlock;
2728 };
2729
2730 class ParameterNode : public Node {
2731 public:
2732 ParameterNode(const Identifier& ident) KJS_FAST_CALL
2733 : m_ident(ident)
2734 {
2735 }
2736
2737 ParameterNode(ParameterNode* l, const Identifier& ident) KJS_FAST_CALL
2738 : m_ident(ident)
2739 {
2740 l->m_next = this;
2741 }
2742
2743 Identifier ident() KJS_FAST_CALL { return m_ident; }
2744 ParameterNode *nextParam() KJS_FAST_CALL { return m_next.get(); }
2745 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2746 PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
2747 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2748
2749 private:
2750 friend class FuncDeclNode;
2751 friend class FuncExprNode;
2752 Identifier m_ident;
2753 ListRefPtr<ParameterNode> m_next;
2754 };
2755
2756 class ScopeNode : public BlockNode {
2757 public:
2758 ScopeNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2759
2760 int sourceId() const KJS_FAST_CALL { return m_sourceId; }
2761 const UString& sourceURL() const KJS_FAST_CALL { return m_sourceURL; }
2762 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2763
2764 bool usesEval() const { return m_usesEval; }
2765 bool needsClosure() const { return m_needsClosure; }
2766
2767 protected:
2768 void optimizeVariableAccess(ExecState*) KJS_FAST_CALL;
2769
2770 VarStack m_varStack;
2771 FunctionStack m_functionStack;
2772 private:
2773 UString m_sourceURL;
2774 int m_sourceId;
2775 bool m_usesEval;
2776 bool m_needsClosure;
2777 };
2778
2779 class ProgramNode : public ScopeNode {
2780 public:
2781 static ProgramNode* create(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2782
2783 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2784
2785 private:
2786 ProgramNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2787
2788 void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
2789 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
2790
2791 Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.)
2792 Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.)
2793 };
2794
2795 class EvalNode : public ScopeNode {
2796 public:
2797 static EvalNode* create(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2798
2799 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2800
2801 private:
2802 EvalNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2803
2804 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
2805 };
2806
2807 class FunctionBodyNode : public ScopeNode {
2808 public:
2809 static FunctionBodyNode* create(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2810
2811 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2812
2813 SymbolTable& symbolTable() KJS_FAST_CALL { return m_symbolTable; }
2814
2815 Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
2816 UString paramString() const KJS_FAST_CALL;
2817
2818 protected:
2819 FunctionBodyNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2820
2821 private:
2822 void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
2823 ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
2824
2825 bool m_initialized;
2826 Vector<Identifier> m_parameters;
2827 SymbolTable m_symbolTable;
2828 };
2829
2830 class FuncExprNode : public ExpressionNode {
2831 public:
2832 FuncExprNode(const Identifier& ident, FunctionBodyNode* body, ParameterNode* parameter = 0) KJS_FAST_CALL
2833 : m_ident(ident)
2834 , m_parameter(parameter)
2835 , m_body(body)
2836 {
2837 addParams();
2838 }
2839
2840 virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2841 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2842 virtual Precedence precedence() const { return PrecMember; }
2843 virtual bool needsParensIfLeftmost() const { return true; }
2844
2845 private:
2846 void addParams() KJS_FAST_CALL;
2847
2848 // Used for streamTo
2849 friend class PropertyNode;
2850 Identifier m_ident;
2851 RefPtr<ParameterNode> m_parameter;
2852 RefPtr<FunctionBodyNode> m_body;
2853 };
2854
2855 class FuncDeclNode : public StatementNode {
2856 public:
2857 FuncDeclNode(const Identifier& ident, FunctionBodyNode* body) KJS_FAST_CALL
2858 : m_ident(ident)
2859 , m_body(body)
2860 {
2861 addParams();
2862 }
2863
2864 FuncDeclNode(const Identifier& ident, ParameterNode* parameter, FunctionBodyNode* body) KJS_FAST_CALL
2865 : m_ident(ident)
2866 , m_parameter(parameter)
2867 , m_body(body)
2868 {
2869 addParams();
2870 }
2871
2872 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2873 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2874 ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
2875
2876 Identifier m_ident;
2877
2878 private:
2879 void addParams() KJS_FAST_CALL;
2880
2881 RefPtr<ParameterNode> m_parameter;
2882 RefPtr<FunctionBodyNode> m_body;
2883 };
2884
2885 class CaseClauseNode : public Node {
2886 public:
2887 CaseClauseNode(ExpressionNode* expr) KJS_FAST_CALL
2888 : m_expr(expr)
2889 {
2890 }
2891
2892 CaseClauseNode(ExpressionNode* expr, SourceElements* children) KJS_FAST_CALL
2893 : m_expr(expr)
2894 {
2895 if (children)
2896 children->releaseContentsIntoVector(m_children);
2897 }
2898
2899 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2900 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2901 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2902
2903 JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2904 JSValue* executeStatements(ExecState*) KJS_FAST_CALL;
2905
2906 private:
2907 RefPtr<ExpressionNode> m_expr;
2908 StatementVector m_children;
2909 };
2910
2911 class ClauseListNode : public Node {
2912 public:
2913 ClauseListNode(CaseClauseNode* clause) KJS_FAST_CALL
2914 : m_clause(clause)
2915 {
2916 }
2917
2918 ClauseListNode(ClauseListNode* clauseList, CaseClauseNode* clause) KJS_FAST_CALL
2919 : m_clause(clause)
2920 {
2921 clauseList->m_next = this;
2922 }
2923
2924 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2925 CaseClauseNode* getClause() const KJS_FAST_CALL { return m_clause.get(); }
2926 ClauseListNode* getNext() const KJS_FAST_CALL { return m_next.get(); }
2927 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2928 PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
2929 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2930
2931 private:
2932 friend class CaseBlockNode;
2933 RefPtr<CaseClauseNode> m_clause;
2934 ListRefPtr<ClauseListNode> m_next;
2935 };
2936
2937 class CaseBlockNode : public Node {
2938 public:
2939 CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) KJS_FAST_CALL;
2940
2941 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2942 JSValue* executeBlock(ExecState*, JSValue *input) KJS_FAST_CALL;
2943 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2944 virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2945
2946 private:
2947 RefPtr<ClauseListNode> m_list1;
2948 RefPtr<CaseClauseNode> m_defaultClause;
2949 RefPtr<ClauseListNode> m_list2;
2950 };
2951
2952 class SwitchNode : public StatementNode {
2953 public:
2954 SwitchNode(ExpressionNode* expr, CaseBlockNode* block) KJS_FAST_CALL
2955 : m_expr(expr)
2956 , m_block(block)
2957 {
2958 }
2959
2960 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2961 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2962 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2963
2964 private:
2965 RefPtr<ExpressionNode> m_expr;
2966 RefPtr<CaseBlockNode> m_block;
2967 };
2968
2969 class BreakpointCheckStatement : public StatementNode {
2970 public:
2971 BreakpointCheckStatement(PassRefPtr<StatementNode>) KJS_FAST_CALL;
2972
2973 virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2974 virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2975 virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2976
2977 private:
2978 RefPtr<StatementNode> m_statement;
2979 };
2980
2981 struct ElementList {
2982 ElementNode* head;
2983 ElementNode* tail;
2984 };
2985
2986 struct PropertyList {
2987 PropertyListNode* head;
2988 PropertyListNode* tail;
2989 };
2990
2991 struct ArgumentList {
2992 ArgumentListNode* head;
2993 ArgumentListNode* tail;
2994 };
2995
2996 struct ConstDeclList {
2997 ConstDeclNode* head;
2998 ConstDeclNode* tail;
2999 };
3000
3001 struct ParameterList {
3002 ParameterNode* head;
3003 ParameterNode* tail;
3004 };
3005
3006 struct ClauseList {
3007 ClauseListNode* head;
3008 ClauseListNode* tail;
3009 };
3010
3011} // namespace KJS
3012
3013#endif // NODES_H_
Note: See TracBrowser for help on using the repository browser.