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