]>
Commit | Line | Data |
---|---|---|
9dae56ea A |
1 | /* |
2 | * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) | |
3 | * Copyright (C) 2001 Peter Kelly (pmk@post.com) | |
4 | * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. | |
5 | * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca) | |
6 | * Copyright (C) 2007 Maks Orlovich | |
7 | * Copyright (C) 2007 Eric Seidel <eric@webkit.org> | |
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 | ||
ba379fdc A |
26 | #ifndef Nodes_h |
27 | #define Nodes_h | |
9dae56ea A |
28 | |
29 | #include "Error.h" | |
ba379fdc | 30 | #include "JITCode.h" |
9dae56ea | 31 | #include "Opcode.h" |
ba379fdc | 32 | #include "ParserArena.h" |
9dae56ea A |
33 | #include "ResultType.h" |
34 | #include "SourceCode.h" | |
35 | #include "SymbolTable.h" | |
36 | #include <wtf/MathExtras.h> | |
9dae56ea A |
37 | |
38 | namespace JSC { | |
39 | ||
ba379fdc | 40 | class ArgumentListNode; |
9dae56ea | 41 | class BytecodeGenerator; |
f9bf01c6 A |
42 | class FunctionBodyNode; |
43 | class Label; | |
9dae56ea | 44 | class PropertyListNode; |
ba379fdc | 45 | class ReadModifyResolveNode; |
9dae56ea A |
46 | class RegisterID; |
47 | class ScopeChainNode; | |
f9bf01c6 | 48 | class ScopeNode; |
9dae56ea A |
49 | |
50 | typedef unsigned CodeFeatures; | |
51 | ||
52 | const CodeFeatures NoFeatures = 0; | |
53 | const CodeFeatures EvalFeature = 1 << 0; | |
54 | const CodeFeatures ClosureFeature = 1 << 1; | |
55 | const CodeFeatures AssignFeature = 1 << 2; | |
56 | const CodeFeatures ArgumentsFeature = 1 << 3; | |
57 | const CodeFeatures WithFeature = 1 << 4; | |
58 | const CodeFeatures CatchFeature = 1 << 5; | |
59 | const CodeFeatures ThisFeature = 1 << 6; | |
60 | const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature; | |
61 | ||
62 | enum Operator { | |
63 | OpEqual, | |
64 | OpPlusEq, | |
65 | OpMinusEq, | |
66 | OpMultEq, | |
67 | OpDivEq, | |
68 | OpPlusPlus, | |
69 | OpMinusMinus, | |
70 | OpAndEq, | |
71 | OpXOrEq, | |
72 | OpOrEq, | |
73 | OpModEq, | |
74 | OpLShift, | |
75 | OpRShift, | |
76 | OpURShift | |
77 | }; | |
78 | ||
79 | enum LogicalOperator { | |
80 | OpLogicalAnd, | |
81 | OpLogicalOr | |
82 | }; | |
83 | ||
84 | namespace DeclarationStacks { | |
85 | enum VarAttrs { IsConstant = 1, HasInitializer = 2 }; | |
f9bf01c6 A |
86 | typedef Vector<std::pair<const Identifier*, unsigned> > VarStack; |
87 | typedef Vector<FunctionBodyNode*> FunctionStack; | |
9dae56ea A |
88 | } |
89 | ||
90 | struct SwitchInfo { | |
91 | enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString }; | |
92 | uint32_t bytecodeOffset; | |
93 | SwitchType switchType; | |
94 | }; | |
95 | ||
f9bf01c6 A |
96 | class ParserArenaFreeable { |
97 | public: | |
98 | // ParserArenaFreeable objects are are freed when the arena is deleted. | |
99 | // Destructors are not called. Clients must not call delete on such objects. | |
100 | void* operator new(size_t, JSGlobalData*); | |
101 | }; | |
9dae56ea | 102 | |
f9bf01c6 | 103 | class ParserArenaDeletable { |
9dae56ea | 104 | public: |
ba379fdc | 105 | virtual ~ParserArenaDeletable() { } |
9dae56ea | 106 | |
f9bf01c6 A |
107 | // ParserArenaDeletable objects are deleted when the arena is deleted. |
108 | // Clients must not call delete directly on such objects. | |
ba379fdc | 109 | void* operator new(size_t, JSGlobalData*); |
ba379fdc | 110 | }; |
9dae56ea | 111 | |
ba379fdc A |
112 | class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> { |
113 | protected: | |
114 | ParserArenaRefCounted(JSGlobalData*); | |
9dae56ea | 115 | |
ba379fdc A |
116 | public: |
117 | virtual ~ParserArenaRefCounted() | |
118 | { | |
119 | ASSERT(deletionHasBegun()); | |
120 | } | |
9dae56ea A |
121 | }; |
122 | ||
f9bf01c6 | 123 | class Node : public ParserArenaFreeable { |
ba379fdc A |
124 | protected: |
125 | Node(JSGlobalData*); | |
9dae56ea | 126 | |
ba379fdc | 127 | public: |
f9bf01c6 | 128 | virtual ~Node() { } |
9dae56ea | 129 | |
f9bf01c6 | 130 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0; |
9dae56ea A |
131 | |
132 | int lineNo() const { return m_line; } | |
133 | ||
134 | protected: | |
135 | int m_line; | |
136 | }; | |
137 | ||
138 | class ExpressionNode : public Node { | |
f9bf01c6 | 139 | protected: |
ba379fdc A |
140 | ExpressionNode(JSGlobalData*, ResultType = ResultType::unknownType()); |
141 | ||
f9bf01c6 | 142 | public: |
ba379fdc A |
143 | virtual bool isNumber() const { return false; } |
144 | virtual bool isString() const { return false; } | |
145 | virtual bool isNull() const { return false; } | |
146 | virtual bool isPure(BytecodeGenerator&) const { return false; } | |
147 | virtual bool isLocation() const { return false; } | |
148 | virtual bool isResolveNode() const { return false; } | |
149 | virtual bool isBracketAccessorNode() const { return false; } | |
150 | virtual bool isDotAccessorNode() const { return false; } | |
151 | virtual bool isFuncExprNode() const { return false; } | |
152 | virtual bool isCommaNode() const { return false; } | |
153 | virtual bool isSimpleArray() const { return false; } | |
154 | virtual bool isAdd() const { return false; } | |
f9bf01c6 A |
155 | virtual bool hasConditionContextCodegen() const { return false; } |
156 | ||
157 | virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, bool) { ASSERT_NOT_REACHED(); } | |
9dae56ea A |
158 | |
159 | virtual ExpressionNode* stripUnaryPlus() { return this; } | |
160 | ||
ba379fdc | 161 | ResultType resultDescriptor() const { return m_resultType; } |
9dae56ea | 162 | |
9dae56ea | 163 | private: |
ba379fdc | 164 | ResultType m_resultType; |
9dae56ea A |
165 | }; |
166 | ||
167 | class StatementNode : public Node { | |
f9bf01c6 | 168 | protected: |
ba379fdc | 169 | StatementNode(JSGlobalData*); |
9dae56ea | 170 | |
f9bf01c6 A |
171 | public: |
172 | void setLoc(int firstLine, int lastLine); | |
ba379fdc A |
173 | int firstLine() const { return lineNo(); } |
174 | int lastLine() const { return m_lastLine; } | |
9dae56ea | 175 | |
ba379fdc A |
176 | virtual bool isEmptyStatement() const { return false; } |
177 | virtual bool isReturnNode() const { return false; } | |
178 | virtual bool isExprStatement() const { return false; } | |
179 | ||
180 | virtual bool isBlock() const { return false; } | |
9dae56ea A |
181 | |
182 | private: | |
183 | int m_lastLine; | |
184 | }; | |
185 | ||
186 | class NullNode : public ExpressionNode { | |
187 | public: | |
ba379fdc | 188 | NullNode(JSGlobalData*); |
9dae56ea | 189 | |
ba379fdc A |
190 | private: |
191 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea | 192 | |
ba379fdc | 193 | virtual bool isNull() const { return true; } |
9dae56ea A |
194 | }; |
195 | ||
196 | class BooleanNode : public ExpressionNode { | |
197 | public: | |
ba379fdc | 198 | BooleanNode(JSGlobalData*, bool value); |
9dae56ea | 199 | |
ba379fdc A |
200 | private: |
201 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea | 202 | |
ba379fdc | 203 | virtual bool isPure(BytecodeGenerator&) const { return true; } |
9dae56ea | 204 | |
9dae56ea A |
205 | bool m_value; |
206 | }; | |
207 | ||
208 | class NumberNode : public ExpressionNode { | |
209 | public: | |
f9bf01c6 | 210 | NumberNode(JSGlobalData*, double value); |
9dae56ea | 211 | |
f9bf01c6 A |
212 | double value() const { return m_value; } |
213 | void setValue(double value) { m_value = value; } | |
9dae56ea A |
214 | |
215 | private: | |
ba379fdc A |
216 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
217 | ||
218 | virtual bool isNumber() const { return true; } | |
219 | virtual bool isPure(BytecodeGenerator&) const { return true; } | |
220 | ||
f9bf01c6 | 221 | double m_value; |
9dae56ea A |
222 | }; |
223 | ||
224 | class StringNode : public ExpressionNode { | |
225 | public: | |
f9bf01c6 | 226 | StringNode(JSGlobalData*, const Identifier&); |
9dae56ea | 227 | |
9dae56ea | 228 | const Identifier& value() { return m_value; } |
9dae56ea A |
229 | |
230 | private: | |
f9bf01c6 A |
231 | virtual bool isPure(BytecodeGenerator&) const { return true; } |
232 | ||
ba379fdc A |
233 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
234 | ||
235 | virtual bool isString() const { return true; } | |
236 | ||
f9bf01c6 | 237 | const Identifier& m_value; |
9dae56ea A |
238 | }; |
239 | ||
240 | class ThrowableExpressionData { | |
241 | public: | |
242 | ThrowableExpressionData() | |
243 | : m_divot(static_cast<uint32_t>(-1)) | |
244 | , m_startOffset(static_cast<uint16_t>(-1)) | |
245 | , m_endOffset(static_cast<uint16_t>(-1)) | |
246 | { | |
247 | } | |
248 | ||
249 | ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset) | |
250 | : m_divot(divot) | |
251 | , m_startOffset(startOffset) | |
252 | , m_endOffset(endOffset) | |
253 | { | |
254 | } | |
255 | ||
256 | void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset) | |
257 | { | |
258 | m_divot = divot; | |
259 | m_startOffset = startOffset; | |
260 | m_endOffset = endOffset; | |
261 | } | |
262 | ||
263 | uint32_t divot() const { return m_divot; } | |
264 | uint16_t startOffset() const { return m_startOffset; } | |
265 | uint16_t endOffset() const { return m_endOffset; } | |
266 | ||
267 | protected: | |
f9bf01c6 A |
268 | RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message); |
269 | RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message, const UString&); | |
270 | RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message, const Identifier&); | |
9dae56ea A |
271 | |
272 | private: | |
273 | uint32_t m_divot; | |
274 | uint16_t m_startOffset; | |
275 | uint16_t m_endOffset; | |
276 | }; | |
277 | ||
278 | class ThrowableSubExpressionData : public ThrowableExpressionData { | |
279 | public: | |
280 | ThrowableSubExpressionData() | |
f9bf01c6 | 281 | : m_subexpressionDivotOffset(0) |
9dae56ea A |
282 | , m_subexpressionEndOffset(0) |
283 | { | |
284 | } | |
285 | ||
286 | ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset) | |
287 | : ThrowableExpressionData(divot, startOffset, endOffset) | |
288 | , m_subexpressionDivotOffset(0) | |
289 | , m_subexpressionEndOffset(0) | |
290 | { | |
291 | } | |
292 | ||
293 | void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) | |
294 | { | |
295 | ASSERT(subexpressionDivot <= divot()); | |
296 | if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot | |
297 | return; | |
298 | m_subexpressionDivotOffset = divot() - subexpressionDivot; | |
299 | m_subexpressionEndOffset = subexpressionOffset; | |
300 | } | |
301 | ||
302 | protected: | |
303 | uint16_t m_subexpressionDivotOffset; | |
304 | uint16_t m_subexpressionEndOffset; | |
305 | }; | |
306 | ||
307 | class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData { | |
308 | public: | |
309 | ThrowablePrefixedSubExpressionData() | |
f9bf01c6 | 310 | : m_subexpressionDivotOffset(0) |
9dae56ea A |
311 | , m_subexpressionStartOffset(0) |
312 | { | |
313 | } | |
314 | ||
315 | ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset) | |
316 | : ThrowableExpressionData(divot, startOffset, endOffset) | |
317 | , m_subexpressionDivotOffset(0) | |
318 | , m_subexpressionStartOffset(0) | |
319 | { | |
320 | } | |
321 | ||
322 | void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) | |
323 | { | |
324 | ASSERT(subexpressionDivot >= divot()); | |
325 | if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot | |
326 | return; | |
327 | m_subexpressionDivotOffset = subexpressionDivot - divot(); | |
328 | m_subexpressionStartOffset = subexpressionOffset; | |
329 | } | |
330 | ||
331 | protected: | |
332 | uint16_t m_subexpressionDivotOffset; | |
333 | uint16_t m_subexpressionStartOffset; | |
334 | }; | |
335 | ||
336 | class RegExpNode : public ExpressionNode, public ThrowableExpressionData { | |
337 | public: | |
f9bf01c6 | 338 | RegExpNode(JSGlobalData*, const Identifier& pattern, const Identifier& flags); |
9dae56ea A |
339 | |
340 | private: | |
ba379fdc A |
341 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
342 | ||
f9bf01c6 A |
343 | const Identifier& m_pattern; |
344 | const Identifier& m_flags; | |
9dae56ea A |
345 | }; |
346 | ||
347 | class ThisNode : public ExpressionNode { | |
348 | public: | |
ba379fdc | 349 | ThisNode(JSGlobalData*); |
9dae56ea | 350 | |
ba379fdc A |
351 | private: |
352 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea A |
353 | }; |
354 | ||
355 | class ResolveNode : public ExpressionNode { | |
356 | public: | |
ba379fdc | 357 | ResolveNode(JSGlobalData*, const Identifier&, int startOffset); |
9dae56ea | 358 | |
ba379fdc | 359 | const Identifier& identifier() const { return m_ident; } |
9dae56ea A |
360 | |
361 | private: | |
ba379fdc A |
362 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
363 | ||
364 | virtual bool isPure(BytecodeGenerator&) const ; | |
365 | virtual bool isLocation() const { return true; } | |
366 | virtual bool isResolveNode() const { return true; } | |
367 | ||
f9bf01c6 | 368 | const Identifier& m_ident; |
9dae56ea A |
369 | int32_t m_startOffset; |
370 | }; | |
371 | ||
f9bf01c6 | 372 | class ElementNode : public ParserArenaFreeable { |
9dae56ea | 373 | public: |
ba379fdc A |
374 | ElementNode(JSGlobalData*, int elision, ExpressionNode*); |
375 | ElementNode(JSGlobalData*, ElementNode*, int elision, ExpressionNode*); | |
9dae56ea A |
376 | |
377 | int elision() const { return m_elision; } | |
ba379fdc A |
378 | ExpressionNode* value() { return m_node; } |
379 | ElementNode* next() { return m_next; } | |
9dae56ea A |
380 | |
381 | private: | |
ba379fdc | 382 | ElementNode* m_next; |
9dae56ea | 383 | int m_elision; |
ba379fdc | 384 | ExpressionNode* m_node; |
9dae56ea A |
385 | }; |
386 | ||
387 | class ArrayNode : public ExpressionNode { | |
388 | public: | |
ba379fdc A |
389 | ArrayNode(JSGlobalData*, int elision); |
390 | ArrayNode(JSGlobalData*, ElementNode*); | |
391 | ArrayNode(JSGlobalData*, int elision, ElementNode*); | |
9dae56ea | 392 | |
ba379fdc | 393 | ArgumentListNode* toArgumentList(JSGlobalData*) const; |
9dae56ea | 394 | |
ba379fdc A |
395 | private: |
396 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea | 397 | |
ba379fdc | 398 | virtual bool isSimpleArray() const ; |
9dae56ea | 399 | |
ba379fdc | 400 | ElementNode* m_element; |
9dae56ea A |
401 | int m_elision; |
402 | bool m_optional; | |
403 | }; | |
404 | ||
f9bf01c6 | 405 | class PropertyNode : public ParserArenaFreeable { |
9dae56ea A |
406 | public: |
407 | enum Type { Constant, Getter, Setter }; | |
408 | ||
ba379fdc | 409 | PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type); |
f9bf01c6 | 410 | PropertyNode(JSGlobalData*, double name, ExpressionNode* value, Type); |
9dae56ea A |
411 | |
412 | const Identifier& name() const { return m_name; } | |
413 | ||
414 | private: | |
415 | friend class PropertyListNode; | |
f9bf01c6 | 416 | const Identifier& m_name; |
ba379fdc | 417 | ExpressionNode* m_assign; |
9dae56ea A |
418 | Type m_type; |
419 | }; | |
420 | ||
421 | class PropertyListNode : public Node { | |
422 | public: | |
ba379fdc A |
423 | PropertyListNode(JSGlobalData*, PropertyNode*); |
424 | PropertyListNode(JSGlobalData*, PropertyNode*, PropertyListNode*); | |
9dae56ea | 425 | |
ba379fdc | 426 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
9dae56ea A |
427 | |
428 | private: | |
ba379fdc A |
429 | PropertyNode* m_node; |
430 | PropertyListNode* m_next; | |
9dae56ea A |
431 | }; |
432 | ||
433 | class ObjectLiteralNode : public ExpressionNode { | |
434 | public: | |
ba379fdc A |
435 | ObjectLiteralNode(JSGlobalData*); |
436 | ObjectLiteralNode(JSGlobalData*, PropertyListNode*); | |
9dae56ea A |
437 | |
438 | private: | |
ba379fdc A |
439 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
440 | ||
441 | PropertyListNode* m_list; | |
9dae56ea A |
442 | }; |
443 | ||
444 | class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData { | |
445 | public: | |
ba379fdc | 446 | BracketAccessorNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments); |
9dae56ea | 447 | |
ba379fdc A |
448 | ExpressionNode* base() const { return m_base; } |
449 | ExpressionNode* subscript() const { return m_subscript; } | |
9dae56ea | 450 | |
ba379fdc A |
451 | private: |
452 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea | 453 | |
ba379fdc A |
454 | virtual bool isLocation() const { return true; } |
455 | virtual bool isBracketAccessorNode() const { return true; } | |
9dae56ea | 456 | |
ba379fdc A |
457 | ExpressionNode* m_base; |
458 | ExpressionNode* m_subscript; | |
9dae56ea A |
459 | bool m_subscriptHasAssignments; |
460 | }; | |
461 | ||
462 | class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData { | |
463 | public: | |
ba379fdc | 464 | DotAccessorNode(JSGlobalData*, ExpressionNode* base, const Identifier&); |
9dae56ea | 465 | |
ba379fdc A |
466 | ExpressionNode* base() const { return m_base; } |
467 | const Identifier& identifier() const { return m_ident; } | |
9dae56ea | 468 | |
ba379fdc A |
469 | private: |
470 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea | 471 | |
ba379fdc A |
472 | virtual bool isLocation() const { return true; } |
473 | virtual bool isDotAccessorNode() const { return true; } | |
9dae56ea | 474 | |
ba379fdc | 475 | ExpressionNode* m_base; |
f9bf01c6 | 476 | const Identifier& m_ident; |
9dae56ea A |
477 | }; |
478 | ||
479 | class ArgumentListNode : public Node { | |
480 | public: | |
ba379fdc A |
481 | ArgumentListNode(JSGlobalData*, ExpressionNode*); |
482 | ArgumentListNode(JSGlobalData*, ArgumentListNode*, ExpressionNode*); | |
9dae56ea | 483 | |
ba379fdc A |
484 | ArgumentListNode* m_next; |
485 | ExpressionNode* m_expr; | |
9dae56ea | 486 | |
ba379fdc A |
487 | private: |
488 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea A |
489 | }; |
490 | ||
f9bf01c6 | 491 | class ArgumentsNode : public ParserArenaFreeable { |
9dae56ea | 492 | public: |
ba379fdc A |
493 | ArgumentsNode(JSGlobalData*); |
494 | ArgumentsNode(JSGlobalData*, ArgumentListNode*); | |
9dae56ea | 495 | |
ba379fdc | 496 | ArgumentListNode* m_listNode; |
9dae56ea A |
497 | }; |
498 | ||
499 | class NewExprNode : public ExpressionNode, public ThrowableExpressionData { | |
500 | public: | |
ba379fdc A |
501 | NewExprNode(JSGlobalData*, ExpressionNode*); |
502 | NewExprNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*); | |
9dae56ea A |
503 | |
504 | private: | |
ba379fdc A |
505 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
506 | ||
507 | ExpressionNode* m_expr; | |
508 | ArgumentsNode* m_args; | |
9dae56ea A |
509 | }; |
510 | ||
511 | class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData { | |
512 | public: | |
ba379fdc | 513 | EvalFunctionCallNode(JSGlobalData*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
514 | |
515 | private: | |
ba379fdc A |
516 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
517 | ||
518 | ArgumentsNode* m_args; | |
9dae56ea A |
519 | }; |
520 | ||
521 | class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData { | |
522 | public: | |
ba379fdc | 523 | FunctionCallValueNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
524 | |
525 | private: | |
ba379fdc A |
526 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
527 | ||
528 | ExpressionNode* m_expr; | |
529 | ArgumentsNode* m_args; | |
9dae56ea A |
530 | }; |
531 | ||
532 | class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData { | |
533 | public: | |
ba379fdc | 534 | FunctionCallResolveNode(JSGlobalData*, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
535 | |
536 | private: | |
ba379fdc A |
537 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
538 | ||
f9bf01c6 | 539 | const Identifier& m_ident; |
ba379fdc | 540 | ArgumentsNode* m_args; |
9dae56ea A |
541 | size_t m_index; // Used by LocalVarFunctionCallNode. |
542 | size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode | |
543 | }; | |
544 | ||
545 | class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData { | |
546 | public: | |
ba379fdc | 547 | FunctionCallBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
548 | |
549 | private: | |
ba379fdc A |
550 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
551 | ||
552 | ExpressionNode* m_base; | |
553 | ExpressionNode* m_subscript; | |
554 | ArgumentsNode* m_args; | |
9dae56ea A |
555 | }; |
556 | ||
557 | class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData { | |
558 | public: | |
ba379fdc A |
559 | FunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); |
560 | ||
561 | private: | |
562 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea | 563 | |
ba379fdc A |
564 | protected: |
565 | ExpressionNode* m_base; | |
f9bf01c6 | 566 | const Identifier& m_ident; |
ba379fdc A |
567 | ArgumentsNode* m_args; |
568 | }; | |
9dae56ea | 569 | |
ba379fdc A |
570 | class CallFunctionCallDotNode : public FunctionCallDotNode { |
571 | public: | |
572 | CallFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); | |
9dae56ea A |
573 | |
574 | private: | |
ba379fdc A |
575 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
576 | }; | |
577 | ||
578 | class ApplyFunctionCallDotNode : public FunctionCallDotNode { | |
579 | public: | |
580 | ApplyFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset); | |
581 | ||
582 | private: | |
583 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea A |
584 | }; |
585 | ||
586 | class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData { | |
587 | public: | |
ba379fdc | 588 | PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
589 | |
590 | protected: | |
f9bf01c6 | 591 | const Identifier& m_ident; |
9dae56ea A |
592 | }; |
593 | ||
594 | class PostfixResolveNode : public PrePostResolveNode { | |
595 | public: | |
ba379fdc | 596 | PostfixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
597 | |
598 | private: | |
ba379fdc A |
599 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
600 | ||
9dae56ea A |
601 | Operator m_operator; |
602 | }; | |
603 | ||
604 | class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData { | |
605 | public: | |
ba379fdc | 606 | PostfixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
607 | |
608 | private: | |
ba379fdc A |
609 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
610 | ||
611 | ExpressionNode* m_base; | |
612 | ExpressionNode* m_subscript; | |
9dae56ea A |
613 | Operator m_operator; |
614 | }; | |
615 | ||
616 | class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData { | |
617 | public: | |
ba379fdc | 618 | PostfixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
619 | |
620 | private: | |
ba379fdc A |
621 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
622 | ||
623 | ExpressionNode* m_base; | |
f9bf01c6 | 624 | const Identifier& m_ident; |
9dae56ea A |
625 | Operator m_operator; |
626 | }; | |
627 | ||
628 | class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData { | |
629 | public: | |
ba379fdc | 630 | PostfixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
631 | |
632 | private: | |
ba379fdc A |
633 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
634 | ||
635 | ExpressionNode* m_expr; | |
9dae56ea A |
636 | Operator m_operator; |
637 | }; | |
638 | ||
639 | class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData { | |
640 | public: | |
ba379fdc | 641 | DeleteResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
642 | |
643 | private: | |
ba379fdc A |
644 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
645 | ||
f9bf01c6 | 646 | const Identifier& m_ident; |
9dae56ea A |
647 | }; |
648 | ||
649 | class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData { | |
650 | public: | |
ba379fdc | 651 | DeleteBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
652 | |
653 | private: | |
ba379fdc A |
654 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
655 | ||
656 | ExpressionNode* m_base; | |
657 | ExpressionNode* m_subscript; | |
9dae56ea A |
658 | }; |
659 | ||
660 | class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData { | |
661 | public: | |
ba379fdc | 662 | DeleteDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
663 | |
664 | private: | |
ba379fdc A |
665 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
666 | ||
667 | ExpressionNode* m_base; | |
f9bf01c6 | 668 | const Identifier& m_ident; |
9dae56ea A |
669 | }; |
670 | ||
671 | class DeleteValueNode : public ExpressionNode { | |
672 | public: | |
ba379fdc | 673 | DeleteValueNode(JSGlobalData*, ExpressionNode*); |
9dae56ea A |
674 | |
675 | private: | |
ba379fdc A |
676 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
677 | ||
678 | ExpressionNode* m_expr; | |
9dae56ea A |
679 | }; |
680 | ||
681 | class VoidNode : public ExpressionNode { | |
682 | public: | |
ba379fdc | 683 | VoidNode(JSGlobalData*, ExpressionNode*); |
9dae56ea A |
684 | |
685 | private: | |
ba379fdc A |
686 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
687 | ||
688 | ExpressionNode* m_expr; | |
9dae56ea A |
689 | }; |
690 | ||
691 | class TypeOfResolveNode : public ExpressionNode { | |
692 | public: | |
ba379fdc | 693 | TypeOfResolveNode(JSGlobalData*, const Identifier&); |
9dae56ea | 694 | |
ba379fdc | 695 | const Identifier& identifier() const { return m_ident; } |
9dae56ea A |
696 | |
697 | private: | |
ba379fdc A |
698 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
699 | ||
f9bf01c6 | 700 | const Identifier& m_ident; |
9dae56ea A |
701 | }; |
702 | ||
703 | class TypeOfValueNode : public ExpressionNode { | |
704 | public: | |
ba379fdc | 705 | TypeOfValueNode(JSGlobalData*, ExpressionNode*); |
9dae56ea A |
706 | |
707 | private: | |
ba379fdc A |
708 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
709 | ||
710 | ExpressionNode* m_expr; | |
9dae56ea A |
711 | }; |
712 | ||
713 | class PrefixResolveNode : public PrePostResolveNode { | |
714 | public: | |
ba379fdc | 715 | PrefixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
716 | |
717 | private: | |
ba379fdc A |
718 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
719 | ||
9dae56ea A |
720 | Operator m_operator; |
721 | }; | |
722 | ||
723 | class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData { | |
724 | public: | |
ba379fdc | 725 | PrefixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
726 | |
727 | private: | |
ba379fdc A |
728 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
729 | ||
730 | ExpressionNode* m_base; | |
731 | ExpressionNode* m_subscript; | |
9dae56ea A |
732 | Operator m_operator; |
733 | }; | |
734 | ||
735 | class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData { | |
736 | public: | |
ba379fdc | 737 | PrefixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
738 | |
739 | private: | |
ba379fdc A |
740 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
741 | ||
742 | ExpressionNode* m_base; | |
f9bf01c6 | 743 | const Identifier& m_ident; |
9dae56ea A |
744 | Operator m_operator; |
745 | }; | |
746 | ||
747 | class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData { | |
748 | public: | |
ba379fdc | 749 | PrefixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
750 | |
751 | private: | |
ba379fdc A |
752 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
753 | ||
754 | ExpressionNode* m_expr; | |
9dae56ea A |
755 | Operator m_operator; |
756 | }; | |
757 | ||
758 | class UnaryOpNode : public ExpressionNode { | |
759 | public: | |
ba379fdc | 760 | UnaryOpNode(JSGlobalData*, ResultType, ExpressionNode*, OpcodeID); |
9dae56ea | 761 | |
ba379fdc A |
762 | protected: |
763 | ExpressionNode* expr() { return m_expr; } | |
f9bf01c6 | 764 | const ExpressionNode* expr() const { return m_expr; } |
9dae56ea | 765 | |
ba379fdc A |
766 | private: |
767 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea | 768 | |
ba379fdc | 769 | OpcodeID opcodeID() const { return m_opcodeID; } |
9dae56ea | 770 | |
ba379fdc A |
771 | ExpressionNode* m_expr; |
772 | OpcodeID m_opcodeID; | |
9dae56ea A |
773 | }; |
774 | ||
775 | class UnaryPlusNode : public UnaryOpNode { | |
776 | public: | |
ba379fdc | 777 | UnaryPlusNode(JSGlobalData*, ExpressionNode*); |
9dae56ea | 778 | |
ba379fdc A |
779 | private: |
780 | virtual ExpressionNode* stripUnaryPlus() { return expr(); } | |
9dae56ea A |
781 | }; |
782 | ||
783 | class NegateNode : public UnaryOpNode { | |
784 | public: | |
ba379fdc | 785 | NegateNode(JSGlobalData*, ExpressionNode*); |
9dae56ea A |
786 | }; |
787 | ||
788 | class BitwiseNotNode : public UnaryOpNode { | |
789 | public: | |
ba379fdc | 790 | BitwiseNotNode(JSGlobalData*, ExpressionNode*); |
9dae56ea A |
791 | }; |
792 | ||
793 | class LogicalNotNode : public UnaryOpNode { | |
794 | public: | |
ba379fdc | 795 | LogicalNotNode(JSGlobalData*, ExpressionNode*); |
f9bf01c6 A |
796 | private: |
797 | void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue); | |
798 | virtual bool hasConditionContextCodegen() const { return expr()->hasConditionContextCodegen(); } | |
9dae56ea A |
799 | }; |
800 | ||
801 | class BinaryOpNode : public ExpressionNode { | |
802 | public: | |
ba379fdc A |
803 | BinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); |
804 | BinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); | |
9dae56ea | 805 | |
f9bf01c6 | 806 | RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0); |
9dae56ea | 807 | |
ba379fdc A |
808 | private: |
809 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea | 810 | |
ba379fdc A |
811 | protected: |
812 | OpcodeID opcodeID() const { return m_opcodeID; } | |
9dae56ea A |
813 | |
814 | protected: | |
ba379fdc A |
815 | ExpressionNode* m_expr1; |
816 | ExpressionNode* m_expr2; | |
817 | private: | |
818 | OpcodeID m_opcodeID; | |
819 | protected: | |
9dae56ea A |
820 | bool m_rightHasAssignments; |
821 | }; | |
822 | ||
823 | class ReverseBinaryOpNode : public BinaryOpNode { | |
824 | public: | |
ba379fdc A |
825 | ReverseBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); |
826 | ReverseBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); | |
9dae56ea | 827 | |
ba379fdc | 828 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
9dae56ea A |
829 | }; |
830 | ||
831 | class MultNode : public BinaryOpNode { | |
832 | public: | |
ba379fdc | 833 | MultNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
834 | }; |
835 | ||
836 | class DivNode : public BinaryOpNode { | |
837 | public: | |
ba379fdc | 838 | DivNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
839 | }; |
840 | ||
841 | class ModNode : public BinaryOpNode { | |
842 | public: | |
ba379fdc | 843 | ModNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
844 | }; |
845 | ||
846 | class AddNode : public BinaryOpNode { | |
847 | public: | |
ba379fdc | 848 | AddNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea | 849 | |
ba379fdc | 850 | virtual bool isAdd() const { return true; } |
9dae56ea A |
851 | }; |
852 | ||
853 | class SubNode : public BinaryOpNode { | |
854 | public: | |
ba379fdc | 855 | SubNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
856 | }; |
857 | ||
858 | class LeftShiftNode : public BinaryOpNode { | |
859 | public: | |
ba379fdc | 860 | LeftShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
861 | }; |
862 | ||
863 | class RightShiftNode : public BinaryOpNode { | |
864 | public: | |
ba379fdc | 865 | RightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
866 | }; |
867 | ||
868 | class UnsignedRightShiftNode : public BinaryOpNode { | |
869 | public: | |
ba379fdc | 870 | UnsignedRightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
871 | }; |
872 | ||
873 | class LessNode : public BinaryOpNode { | |
874 | public: | |
ba379fdc | 875 | LessNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
876 | }; |
877 | ||
878 | class GreaterNode : public ReverseBinaryOpNode { | |
879 | public: | |
ba379fdc | 880 | GreaterNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
881 | }; |
882 | ||
883 | class LessEqNode : public BinaryOpNode { | |
884 | public: | |
ba379fdc | 885 | LessEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
886 | }; |
887 | ||
888 | class GreaterEqNode : public ReverseBinaryOpNode { | |
889 | public: | |
ba379fdc | 890 | GreaterEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
891 | }; |
892 | ||
893 | class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData { | |
894 | public: | |
ba379fdc A |
895 | ThrowableBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); |
896 | ThrowableBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); | |
897 | ||
898 | private: | |
899 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea A |
900 | }; |
901 | ||
902 | class InstanceOfNode : public ThrowableBinaryOpNode { | |
903 | public: | |
ba379fdc | 904 | InstanceOfNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea | 905 | |
ba379fdc A |
906 | private: |
907 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea A |
908 | }; |
909 | ||
910 | class InNode : public ThrowableBinaryOpNode { | |
911 | public: | |
ba379fdc | 912 | InNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
913 | }; |
914 | ||
915 | class EqualNode : public BinaryOpNode { | |
916 | public: | |
ba379fdc | 917 | EqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea | 918 | |
ba379fdc A |
919 | private: |
920 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea A |
921 | }; |
922 | ||
923 | class NotEqualNode : public BinaryOpNode { | |
924 | public: | |
ba379fdc | 925 | NotEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
926 | }; |
927 | ||
928 | class StrictEqualNode : public BinaryOpNode { | |
929 | public: | |
ba379fdc | 930 | StrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea | 931 | |
ba379fdc A |
932 | private: |
933 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea A |
934 | }; |
935 | ||
936 | class NotStrictEqualNode : public BinaryOpNode { | |
937 | public: | |
ba379fdc | 938 | NotStrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
939 | }; |
940 | ||
941 | class BitAndNode : public BinaryOpNode { | |
942 | public: | |
ba379fdc | 943 | BitAndNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
944 | }; |
945 | ||
946 | class BitOrNode : public BinaryOpNode { | |
947 | public: | |
ba379fdc | 948 | BitOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
949 | }; |
950 | ||
951 | class BitXOrNode : public BinaryOpNode { | |
952 | public: | |
ba379fdc | 953 | BitXOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
9dae56ea A |
954 | }; |
955 | ||
ba379fdc | 956 | // m_expr1 && m_expr2, m_expr1 || m_expr2 |
9dae56ea A |
957 | class LogicalOpNode : public ExpressionNode { |
958 | public: | |
ba379fdc | 959 | LogicalOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator); |
9dae56ea A |
960 | |
961 | private: | |
ba379fdc | 962 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
f9bf01c6 A |
963 | void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue); |
964 | virtual bool hasConditionContextCodegen() const { return true; } | |
ba379fdc A |
965 | |
966 | ExpressionNode* m_expr1; | |
967 | ExpressionNode* m_expr2; | |
9dae56ea A |
968 | LogicalOperator m_operator; |
969 | }; | |
970 | ||
ba379fdc | 971 | // The ternary operator, "m_logical ? m_expr1 : m_expr2" |
9dae56ea A |
972 | class ConditionalNode : public ExpressionNode { |
973 | public: | |
ba379fdc | 974 | ConditionalNode(JSGlobalData*, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2); |
9dae56ea A |
975 | |
976 | private: | |
ba379fdc A |
977 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
978 | ||
979 | ExpressionNode* m_logical; | |
980 | ExpressionNode* m_expr1; | |
981 | ExpressionNode* m_expr2; | |
9dae56ea A |
982 | }; |
983 | ||
984 | class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData { | |
985 | public: | |
ba379fdc | 986 | ReadModifyResolveNode(JSGlobalData*, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
987 | |
988 | private: | |
ba379fdc A |
989 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
990 | ||
f9bf01c6 | 991 | const Identifier& m_ident; |
ba379fdc | 992 | ExpressionNode* m_right; |
9dae56ea | 993 | size_t m_index; // Used by ReadModifyLocalVarNode. |
ba379fdc A |
994 | Operator m_operator; |
995 | bool m_rightHasAssignments; | |
9dae56ea A |
996 | }; |
997 | ||
998 | class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData { | |
999 | public: | |
ba379fdc | 1000 | AssignResolveNode(JSGlobalData*, const Identifier&, ExpressionNode* right, bool rightHasAssignments); |
9dae56ea A |
1001 | |
1002 | private: | |
ba379fdc A |
1003 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1004 | ||
f9bf01c6 | 1005 | const Identifier& m_ident; |
ba379fdc | 1006 | ExpressionNode* m_right; |
9dae56ea A |
1007 | size_t m_index; // Used by ReadModifyLocalVarNode. |
1008 | bool m_rightHasAssignments; | |
1009 | }; | |
1010 | ||
1011 | class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData { | |
1012 | public: | |
ba379fdc | 1013 | ReadModifyBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
1014 | |
1015 | private: | |
ba379fdc A |
1016 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1017 | ||
1018 | ExpressionNode* m_base; | |
1019 | ExpressionNode* m_subscript; | |
1020 | ExpressionNode* m_right; | |
9dae56ea A |
1021 | Operator m_operator : 30; |
1022 | bool m_subscriptHasAssignments : 1; | |
1023 | bool m_rightHasAssignments : 1; | |
1024 | }; | |
1025 | ||
1026 | class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData { | |
1027 | public: | |
ba379fdc | 1028 | AssignBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
1029 | |
1030 | private: | |
ba379fdc A |
1031 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1032 | ||
1033 | ExpressionNode* m_base; | |
1034 | ExpressionNode* m_subscript; | |
1035 | ExpressionNode* m_right; | |
9dae56ea A |
1036 | bool m_subscriptHasAssignments : 1; |
1037 | bool m_rightHasAssignments : 1; | |
1038 | }; | |
1039 | ||
1040 | class AssignDotNode : public ExpressionNode, public ThrowableExpressionData { | |
1041 | public: | |
ba379fdc | 1042 | AssignDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
1043 | |
1044 | private: | |
ba379fdc A |
1045 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1046 | ||
1047 | ExpressionNode* m_base; | |
f9bf01c6 | 1048 | const Identifier& m_ident; |
ba379fdc | 1049 | ExpressionNode* m_right; |
9dae56ea A |
1050 | bool m_rightHasAssignments; |
1051 | }; | |
1052 | ||
1053 | class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData { | |
1054 | public: | |
ba379fdc | 1055 | ReadModifyDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
1056 | |
1057 | private: | |
ba379fdc A |
1058 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1059 | ||
1060 | ExpressionNode* m_base; | |
f9bf01c6 | 1061 | const Identifier& m_ident; |
ba379fdc | 1062 | ExpressionNode* m_right; |
9dae56ea A |
1063 | Operator m_operator : 31; |
1064 | bool m_rightHasAssignments : 1; | |
1065 | }; | |
1066 | ||
1067 | class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData { | |
1068 | public: | |
ba379fdc | 1069 | AssignErrorNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset); |
9dae56ea A |
1070 | |
1071 | private: | |
ba379fdc A |
1072 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1073 | ||
1074 | ExpressionNode* m_left; | |
9dae56ea | 1075 | Operator m_operator; |
ba379fdc | 1076 | ExpressionNode* m_right; |
9dae56ea | 1077 | }; |
ba379fdc A |
1078 | |
1079 | typedef Vector<ExpressionNode*, 8> ExpressionVector; | |
9dae56ea | 1080 | |
f9bf01c6 | 1081 | class CommaNode : public ExpressionNode, public ParserArenaDeletable { |
9dae56ea | 1082 | public: |
ba379fdc | 1083 | CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2); |
9dae56ea | 1084 | |
f9bf01c6 A |
1085 | using ParserArenaDeletable::operator new; |
1086 | ||
ba379fdc | 1087 | void append(ExpressionNode* expr) { m_expressions.append(expr); } |
9dae56ea A |
1088 | |
1089 | private: | |
ba379fdc A |
1090 | virtual bool isCommaNode() const { return true; } |
1091 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
1092 | ||
1093 | ExpressionVector m_expressions; | |
9dae56ea A |
1094 | }; |
1095 | ||
9dae56ea A |
1096 | class ConstDeclNode : public ExpressionNode { |
1097 | public: | |
ba379fdc A |
1098 | ConstDeclNode(JSGlobalData*, const Identifier&, ExpressionNode*); |
1099 | ||
1100 | bool hasInitializer() const { return m_init; } | |
1101 | const Identifier& ident() { return m_ident; } | |
9dae56ea | 1102 | |
ba379fdc A |
1103 | private: |
1104 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
1105 | virtual RegisterID* emitCodeSingle(BytecodeGenerator&); | |
9dae56ea | 1106 | |
f9bf01c6 | 1107 | const Identifier& m_ident; |
9dae56ea | 1108 | |
9dae56ea | 1109 | public: |
ba379fdc | 1110 | ConstDeclNode* m_next; |
9dae56ea | 1111 | |
ba379fdc A |
1112 | private: |
1113 | ExpressionNode* m_init; | |
1114 | }; | |
9dae56ea | 1115 | |
ba379fdc A |
1116 | class ConstStatementNode : public StatementNode { |
1117 | public: | |
1118 | ConstStatementNode(JSGlobalData*, ConstDeclNode* next); | |
9dae56ea A |
1119 | |
1120 | private: | |
ba379fdc A |
1121 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1122 | ||
1123 | ConstDeclNode* m_next; | |
9dae56ea A |
1124 | }; |
1125 | ||
ba379fdc | 1126 | class SourceElements : public ParserArenaDeletable { |
9dae56ea | 1127 | public: |
ba379fdc | 1128 | SourceElements(JSGlobalData*); |
9dae56ea | 1129 | |
ba379fdc | 1130 | void append(StatementNode*); |
f9bf01c6 A |
1131 | |
1132 | StatementNode* singleStatement() const; | |
1133 | StatementNode* lastStatement() const; | |
1134 | ||
1135 | void emitBytecode(BytecodeGenerator&, RegisterID* destination); | |
9dae56ea A |
1136 | |
1137 | private: | |
f9bf01c6 | 1138 | Vector<StatementNode*> m_statements; |
9dae56ea A |
1139 | }; |
1140 | ||
1141 | class BlockNode : public StatementNode { | |
1142 | public: | |
f9bf01c6 | 1143 | BlockNode(JSGlobalData*, SourceElements* = 0); |
9dae56ea | 1144 | |
f9bf01c6 | 1145 | StatementNode* lastStatement() const; |
9dae56ea | 1146 | |
9dae56ea | 1147 | private: |
ba379fdc A |
1148 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1149 | ||
1150 | virtual bool isBlock() const { return true; } | |
1151 | ||
f9bf01c6 | 1152 | SourceElements* m_statements; |
9dae56ea A |
1153 | }; |
1154 | ||
1155 | class EmptyStatementNode : public StatementNode { | |
1156 | public: | |
ba379fdc | 1157 | EmptyStatementNode(JSGlobalData*); |
9dae56ea | 1158 | |
ba379fdc A |
1159 | private: |
1160 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea | 1161 | |
ba379fdc | 1162 | virtual bool isEmptyStatement() const { return true; } |
9dae56ea A |
1163 | }; |
1164 | ||
1165 | class DebuggerStatementNode : public StatementNode { | |
1166 | public: | |
ba379fdc | 1167 | DebuggerStatementNode(JSGlobalData*); |
9dae56ea | 1168 | |
ba379fdc A |
1169 | private: |
1170 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea A |
1171 | }; |
1172 | ||
1173 | class ExprStatementNode : public StatementNode { | |
1174 | public: | |
ba379fdc | 1175 | ExprStatementNode(JSGlobalData*, ExpressionNode*); |
9dae56ea | 1176 | |
ba379fdc | 1177 | ExpressionNode* expr() const { return m_expr; } |
9dae56ea | 1178 | |
ba379fdc A |
1179 | private: |
1180 | virtual bool isExprStatement() const { return true; } | |
9dae56ea | 1181 | |
ba379fdc | 1182 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
9dae56ea | 1183 | |
ba379fdc | 1184 | ExpressionNode* m_expr; |
9dae56ea A |
1185 | }; |
1186 | ||
1187 | class VarStatementNode : public StatementNode { | |
1188 | public: | |
ba379fdc | 1189 | VarStatementNode(JSGlobalData*, ExpressionNode*); |
9dae56ea A |
1190 | |
1191 | private: | |
ba379fdc A |
1192 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1193 | ||
1194 | ExpressionNode* m_expr; | |
9dae56ea A |
1195 | }; |
1196 | ||
1197 | class IfNode : public StatementNode { | |
1198 | public: | |
ba379fdc | 1199 | IfNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock); |
9dae56ea A |
1200 | |
1201 | protected: | |
ba379fdc A |
1202 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1203 | ||
1204 | ExpressionNode* m_condition; | |
1205 | StatementNode* m_ifBlock; | |
9dae56ea A |
1206 | }; |
1207 | ||
1208 | class IfElseNode : public IfNode { | |
1209 | public: | |
ba379fdc | 1210 | IfElseNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock); |
9dae56ea A |
1211 | |
1212 | private: | |
ba379fdc A |
1213 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1214 | ||
1215 | StatementNode* m_elseBlock; | |
9dae56ea A |
1216 | }; |
1217 | ||
1218 | class DoWhileNode : public StatementNode { | |
1219 | public: | |
ba379fdc | 1220 | DoWhileNode(JSGlobalData*, StatementNode* statement, ExpressionNode*); |
9dae56ea A |
1221 | |
1222 | private: | |
ba379fdc A |
1223 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1224 | ||
1225 | StatementNode* m_statement; | |
1226 | ExpressionNode* m_expr; | |
9dae56ea A |
1227 | }; |
1228 | ||
1229 | class WhileNode : public StatementNode { | |
1230 | public: | |
ba379fdc | 1231 | WhileNode(JSGlobalData*, ExpressionNode*, StatementNode* statement); |
9dae56ea A |
1232 | |
1233 | private: | |
ba379fdc A |
1234 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1235 | ||
1236 | ExpressionNode* m_expr; | |
1237 | StatementNode* m_statement; | |
9dae56ea A |
1238 | }; |
1239 | ||
1240 | class ForNode : public StatementNode { | |
1241 | public: | |
ba379fdc | 1242 | ForNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl); |
9dae56ea A |
1243 | |
1244 | private: | |
ba379fdc A |
1245 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1246 | ||
1247 | ExpressionNode* m_expr1; | |
1248 | ExpressionNode* m_expr2; | |
1249 | ExpressionNode* m_expr3; | |
1250 | StatementNode* m_statement; | |
9dae56ea A |
1251 | bool m_expr1WasVarDecl; |
1252 | }; | |
1253 | ||
1254 | class ForInNode : public StatementNode, public ThrowableExpressionData { | |
1255 | public: | |
ba379fdc A |
1256 | ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*); |
1257 | ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset); | |
9dae56ea A |
1258 | |
1259 | private: | |
ba379fdc A |
1260 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1261 | ||
f9bf01c6 | 1262 | const Identifier& m_ident; |
ba379fdc A |
1263 | ExpressionNode* m_init; |
1264 | ExpressionNode* m_lexpr; | |
1265 | ExpressionNode* m_expr; | |
1266 | StatementNode* m_statement; | |
9dae56ea A |
1267 | bool m_identIsVarDecl; |
1268 | }; | |
1269 | ||
1270 | class ContinueNode : public StatementNode, public ThrowableExpressionData { | |
1271 | public: | |
ba379fdc A |
1272 | ContinueNode(JSGlobalData*); |
1273 | ContinueNode(JSGlobalData*, const Identifier&); | |
9dae56ea | 1274 | |
9dae56ea | 1275 | private: |
ba379fdc A |
1276 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1277 | ||
f9bf01c6 | 1278 | const Identifier& m_ident; |
9dae56ea A |
1279 | }; |
1280 | ||
1281 | class BreakNode : public StatementNode, public ThrowableExpressionData { | |
1282 | public: | |
ba379fdc A |
1283 | BreakNode(JSGlobalData*); |
1284 | BreakNode(JSGlobalData*, const Identifier&); | |
9dae56ea | 1285 | |
9dae56ea | 1286 | private: |
ba379fdc A |
1287 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1288 | ||
f9bf01c6 | 1289 | const Identifier& m_ident; |
9dae56ea A |
1290 | }; |
1291 | ||
1292 | class ReturnNode : public StatementNode, public ThrowableExpressionData { | |
1293 | public: | |
ba379fdc | 1294 | ReturnNode(JSGlobalData*, ExpressionNode* value); |
9dae56ea | 1295 | |
ba379fdc A |
1296 | private: |
1297 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); | |
9dae56ea | 1298 | |
ba379fdc | 1299 | virtual bool isReturnNode() const { return true; } |
9dae56ea | 1300 | |
ba379fdc | 1301 | ExpressionNode* m_value; |
9dae56ea A |
1302 | }; |
1303 | ||
1304 | class WithNode : public StatementNode { | |
1305 | public: | |
ba379fdc | 1306 | WithNode(JSGlobalData*, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength); |
9dae56ea A |
1307 | |
1308 | private: | |
ba379fdc A |
1309 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1310 | ||
1311 | ExpressionNode* m_expr; | |
1312 | StatementNode* m_statement; | |
9dae56ea A |
1313 | uint32_t m_divot; |
1314 | uint32_t m_expressionLength; | |
1315 | }; | |
1316 | ||
1317 | class LabelNode : public StatementNode, public ThrowableExpressionData { | |
1318 | public: | |
ba379fdc | 1319 | LabelNode(JSGlobalData*, const Identifier& name, StatementNode*); |
9dae56ea A |
1320 | |
1321 | private: | |
ba379fdc A |
1322 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1323 | ||
f9bf01c6 | 1324 | const Identifier& m_name; |
ba379fdc | 1325 | StatementNode* m_statement; |
9dae56ea A |
1326 | }; |
1327 | ||
1328 | class ThrowNode : public StatementNode, public ThrowableExpressionData { | |
1329 | public: | |
ba379fdc | 1330 | ThrowNode(JSGlobalData*, ExpressionNode*); |
9dae56ea A |
1331 | |
1332 | private: | |
ba379fdc A |
1333 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1334 | ||
1335 | ExpressionNode* m_expr; | |
9dae56ea A |
1336 | }; |
1337 | ||
1338 | class TryNode : public StatementNode { | |
1339 | public: | |
ba379fdc | 1340 | TryNode(JSGlobalData*, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock); |
9dae56ea A |
1341 | |
1342 | private: | |
f9bf01c6 | 1343 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
ba379fdc A |
1344 | |
1345 | StatementNode* m_tryBlock; | |
f9bf01c6 | 1346 | const Identifier& m_exceptionIdent; |
ba379fdc A |
1347 | StatementNode* m_catchBlock; |
1348 | StatementNode* m_finallyBlock; | |
9dae56ea A |
1349 | bool m_catchHasEval; |
1350 | }; | |
1351 | ||
f9bf01c6 | 1352 | class ParameterNode : public ParserArenaFreeable { |
9dae56ea | 1353 | public: |
ba379fdc A |
1354 | ParameterNode(JSGlobalData*, const Identifier&); |
1355 | ParameterNode(JSGlobalData*, ParameterNode*, const Identifier&); | |
9dae56ea | 1356 | |
ba379fdc A |
1357 | const Identifier& ident() const { return m_ident; } |
1358 | ParameterNode* nextParam() const { return m_next; } | |
9dae56ea A |
1359 | |
1360 | private: | |
f9bf01c6 | 1361 | const Identifier& m_ident; |
ba379fdc | 1362 | ParameterNode* m_next; |
9dae56ea A |
1363 | }; |
1364 | ||
f9bf01c6 | 1365 | struct ScopeNodeData : FastAllocBase { |
9dae56ea A |
1366 | typedef DeclarationStacks::VarStack VarStack; |
1367 | typedef DeclarationStacks::FunctionStack FunctionStack; | |
1368 | ||
ba379fdc | 1369 | ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, int numConstants); |
9dae56ea | 1370 | |
ba379fdc | 1371 | ParserArena m_arena; |
9dae56ea A |
1372 | VarStack m_varStack; |
1373 | FunctionStack m_functionStack; | |
1374 | int m_numConstants; | |
f9bf01c6 | 1375 | SourceElements* m_statements; |
9dae56ea A |
1376 | }; |
1377 | ||
ba379fdc | 1378 | class ScopeNode : public StatementNode, public ParserArenaRefCounted { |
9dae56ea A |
1379 | public: |
1380 | typedef DeclarationStacks::VarStack VarStack; | |
1381 | typedef DeclarationStacks::FunctionStack FunctionStack; | |
1382 | ||
ba379fdc A |
1383 | ScopeNode(JSGlobalData*); |
1384 | ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants); | |
9dae56ea | 1385 | |
f9bf01c6 A |
1386 | using ParserArenaRefCounted::operator new; |
1387 | ||
ba379fdc A |
1388 | void adoptData(std::auto_ptr<ScopeNodeData> data) |
1389 | { | |
1390 | ASSERT(!data->m_arena.contains(this)); | |
1391 | ASSERT(!m_data); | |
1392 | m_data.adopt(data); | |
1393 | } | |
9dae56ea A |
1394 | ScopeNodeData* data() const { return m_data.get(); } |
1395 | void destroyData() { m_data.clear(); } | |
1396 | ||
1397 | const SourceCode& source() const { return m_source; } | |
ba379fdc | 1398 | const UString& sourceURL() const { return m_source.provider()->url(); } |
9dae56ea A |
1399 | intptr_t sourceID() const { return m_source.provider()->asID(); } |
1400 | ||
1401 | void setFeatures(CodeFeatures features) { m_features = features; } | |
1402 | CodeFeatures features() { return m_features; } | |
1403 | ||
1404 | bool usesEval() const { return m_features & EvalFeature; } | |
1405 | bool usesArguments() const { return m_features & ArgumentsFeature; } | |
1406 | void setUsesArguments() { m_features |= ArgumentsFeature; } | |
1407 | bool usesThis() const { return m_features & ThisFeature; } | |
1408 | bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); } | |
1409 | ||
1410 | VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; } | |
1411 | FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; } | |
1412 | ||
9dae56ea A |
1413 | int neededConstants() |
1414 | { | |
1415 | ASSERT(m_data); | |
1416 | // We may need 2 more constants than the count given by the parser, | |
1417 | // because of the various uses of jsUndefined() and jsNull(). | |
1418 | return m_data->m_numConstants + 2; | |
1419 | } | |
1420 | ||
f9bf01c6 | 1421 | StatementNode* singleStatement() const; |
9dae56ea | 1422 | |
f9bf01c6 | 1423 | void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination); |
ba379fdc | 1424 | |
9dae56ea A |
1425 | protected: |
1426 | void setSource(const SourceCode& source) { m_source = source; } | |
1427 | ||
1428 | private: | |
1429 | OwnPtr<ScopeNodeData> m_data; | |
1430 | CodeFeatures m_features; | |
1431 | SourceCode m_source; | |
1432 | }; | |
1433 | ||
1434 | class ProgramNode : public ScopeNode { | |
1435 | public: | |
ba379fdc | 1436 | static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); |
9dae56ea | 1437 | |
f9bf01c6 | 1438 | static const bool scopeIsFunction = false; |
ba379fdc | 1439 | |
9dae56ea | 1440 | private: |
ba379fdc A |
1441 | ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); |
1442 | ||
ba379fdc | 1443 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
9dae56ea A |
1444 | }; |
1445 | ||
1446 | class EvalNode : public ScopeNode { | |
1447 | public: | |
ba379fdc | 1448 | static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); |
9dae56ea | 1449 | |
f9bf01c6 | 1450 | static const bool scopeIsFunction = false; |
ba379fdc | 1451 | |
9dae56ea | 1452 | private: |
ba379fdc | 1453 | EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); |
9dae56ea | 1454 | |
ba379fdc | 1455 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
f9bf01c6 | 1456 | }; |
ba379fdc | 1457 | |
f9bf01c6 A |
1458 | class FunctionParameters : public Vector<Identifier>, public RefCounted<FunctionParameters> { |
1459 | public: | |
1460 | static PassRefPtr<FunctionParameters> create(ParameterNode* firstParameter) { return adoptRef(new FunctionParameters(firstParameter)); } | |
1461 | ||
1462 | private: | |
1463 | FunctionParameters(ParameterNode*); | |
9dae56ea A |
1464 | }; |
1465 | ||
1466 | class FunctionBodyNode : public ScopeNode { | |
9dae56ea | 1467 | public: |
ba379fdc A |
1468 | static FunctionBodyNode* create(JSGlobalData*); |
1469 | static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); | |
9dae56ea | 1470 | |
f9bf01c6 A |
1471 | FunctionParameters* parameters() const { return m_parameters.get(); } |
1472 | size_t parameterCount() const { return m_parameters->size(); } | |
9dae56ea | 1473 | |
ba379fdc | 1474 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
9dae56ea | 1475 | |
f9bf01c6 A |
1476 | void finishParsing(const SourceCode&, ParameterNode*, const Identifier&); |
1477 | void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&); | |
9dae56ea | 1478 | |
f9bf01c6 | 1479 | const Identifier& ident() { return m_ident; } |
9dae56ea | 1480 | |
f9bf01c6 | 1481 | static const bool scopeIsFunction = true; |
ba379fdc | 1482 | |
9dae56ea | 1483 | private: |
ba379fdc A |
1484 | FunctionBodyNode(JSGlobalData*); |
1485 | FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants); | |
9dae56ea | 1486 | |
f9bf01c6 A |
1487 | Identifier m_ident; |
1488 | RefPtr<FunctionParameters> m_parameters; | |
9dae56ea A |
1489 | }; |
1490 | ||
f9bf01c6 | 1491 | class FuncExprNode : public ExpressionNode { |
9dae56ea | 1492 | public: |
ba379fdc | 1493 | FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0); |
9dae56ea | 1494 | |
f9bf01c6 | 1495 | FunctionBodyNode* body() { return m_body; } |
9dae56ea A |
1496 | |
1497 | private: | |
ba379fdc A |
1498 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1499 | ||
1500 | virtual bool isFuncExprNode() const { return true; } | |
1501 | ||
f9bf01c6 | 1502 | FunctionBodyNode* m_body; |
9dae56ea A |
1503 | }; |
1504 | ||
f9bf01c6 | 1505 | class FuncDeclNode : public StatementNode { |
9dae56ea | 1506 | public: |
ba379fdc | 1507 | FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0); |
9dae56ea | 1508 | |
f9bf01c6 | 1509 | FunctionBodyNode* body() { return m_body; } |
9dae56ea A |
1510 | |
1511 | private: | |
ba379fdc A |
1512 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1513 | ||
f9bf01c6 | 1514 | FunctionBodyNode* m_body; |
9dae56ea A |
1515 | }; |
1516 | ||
f9bf01c6 | 1517 | class CaseClauseNode : public ParserArenaFreeable { |
9dae56ea | 1518 | public: |
f9bf01c6 | 1519 | CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements* = 0); |
9dae56ea | 1520 | |
ba379fdc | 1521 | ExpressionNode* expr() const { return m_expr; } |
f9bf01c6 A |
1522 | |
1523 | void emitBytecode(BytecodeGenerator&, RegisterID* destination); | |
9dae56ea A |
1524 | |
1525 | private: | |
ba379fdc | 1526 | ExpressionNode* m_expr; |
f9bf01c6 | 1527 | SourceElements* m_statements; |
9dae56ea A |
1528 | }; |
1529 | ||
f9bf01c6 | 1530 | class ClauseListNode : public ParserArenaFreeable { |
9dae56ea | 1531 | public: |
ba379fdc A |
1532 | ClauseListNode(JSGlobalData*, CaseClauseNode*); |
1533 | ClauseListNode(JSGlobalData*, ClauseListNode*, CaseClauseNode*); | |
9dae56ea | 1534 | |
ba379fdc A |
1535 | CaseClauseNode* getClause() const { return m_clause; } |
1536 | ClauseListNode* getNext() const { return m_next; } | |
9dae56ea A |
1537 | |
1538 | private: | |
ba379fdc A |
1539 | CaseClauseNode* m_clause; |
1540 | ClauseListNode* m_next; | |
9dae56ea A |
1541 | }; |
1542 | ||
f9bf01c6 | 1543 | class CaseBlockNode : public ParserArenaFreeable { |
9dae56ea | 1544 | public: |
ba379fdc | 1545 | CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2); |
9dae56ea | 1546 | |
f9bf01c6 | 1547 | RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination); |
9dae56ea A |
1548 | |
1549 | private: | |
1550 | SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num); | |
ba379fdc A |
1551 | ClauseListNode* m_list1; |
1552 | CaseClauseNode* m_defaultClause; | |
1553 | ClauseListNode* m_list2; | |
9dae56ea A |
1554 | }; |
1555 | ||
1556 | class SwitchNode : public StatementNode { | |
1557 | public: | |
ba379fdc | 1558 | SwitchNode(JSGlobalData*, ExpressionNode*, CaseBlockNode*); |
9dae56ea A |
1559 | |
1560 | private: | |
ba379fdc A |
1561 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0); |
1562 | ||
1563 | ExpressionNode* m_expr; | |
1564 | CaseBlockNode* m_block; | |
9dae56ea A |
1565 | }; |
1566 | ||
1567 | struct ElementList { | |
1568 | ElementNode* head; | |
1569 | ElementNode* tail; | |
1570 | }; | |
1571 | ||
1572 | struct PropertyList { | |
1573 | PropertyListNode* head; | |
1574 | PropertyListNode* tail; | |
1575 | }; | |
1576 | ||
1577 | struct ArgumentList { | |
1578 | ArgumentListNode* head; | |
1579 | ArgumentListNode* tail; | |
1580 | }; | |
1581 | ||
1582 | struct ConstDeclList { | |
1583 | ConstDeclNode* head; | |
1584 | ConstDeclNode* tail; | |
1585 | }; | |
1586 | ||
1587 | struct ParameterList { | |
1588 | ParameterNode* head; | |
1589 | ParameterNode* tail; | |
1590 | }; | |
1591 | ||
1592 | struct ClauseList { | |
1593 | ClauseListNode* head; | |
1594 | ClauseListNode* tail; | |
1595 | }; | |
1596 | ||
1597 | } // namespace JSC | |
1598 | ||
ba379fdc | 1599 | #endif // Nodes_h |