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