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