1 | /* |
2 | * Copyright (C) 1999-2000 Harri Porten ([email protected]) |
3 | * Copyright (C) 2001 Peter Kelly ([email protected]) |
4 | * Copyright (C) 2003-2019 Apple Inc. All rights reserved. |
5 | * Copyright (C) 2007 Cameron Zwarich ([email protected]) |
6 | * Copyright (C) 2007 Maks Orlovich |
7 | * Copyright (C) 2007 Eric Seidel <[email protected]> |
8 | * |
9 | * This library is free software; you can redistribute it and/or |
10 | * modify it under the terms of the GNU Library General Public |
11 | * License as published by the Free Software Foundation; either |
12 | * version 2 of the License, or (at your option) any later version. |
13 | * |
14 | * This library is distributed in the hope that it will be useful, |
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 | * Library General Public License for more details. |
18 | * |
19 | * You should have received a copy of the GNU Library General Public License |
20 | * along with this library; see the file COPYING.LIB. If not, write to |
21 | * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
22 | * Boston, MA 02110-1301, USA. |
23 | * |
24 | */ |
25 | |
26 | #pragma once |
27 | |
28 | #include "BytecodeIntrinsicRegistry.h" |
29 | #include "JITCode.h" |
30 | #include "Label.h" |
31 | #include "ParserArena.h" |
32 | #include "ParserModes.h" |
33 | #include "ParserTokens.h" |
34 | #include "ResultType.h" |
35 | #include "SourceCode.h" |
36 | #include "SymbolTable.h" |
37 | #include "VariableEnvironment.h" |
38 | #include <wtf/MathExtras.h> |
39 | #include <wtf/SmallPtrSet.h> |
40 | |
41 | namespace JSC { |
42 | |
43 | enum OpcodeID : unsigned; |
44 | |
45 | class ArgumentListNode; |
46 | class BytecodeGenerator; |
47 | class FunctionMetadataNode; |
48 | class FunctionParameters; |
49 | class ModuleAnalyzer; |
50 | class ModuleScopeData; |
51 | class PropertyListNode; |
52 | class ReadModifyResolveNode; |
53 | class RegisterID; |
54 | class ScopeNode; |
55 | |
56 | typedef SmallPtrSet<UniquedStringImpl*> UniquedStringImplPtrSet; |
57 | |
58 | enum Operator : uint8_t { |
59 | OpEqual, |
60 | OpPlusEq, |
61 | OpMinusEq, |
62 | OpMultEq, |
63 | OpDivEq, |
64 | OpPlusPlus, |
65 | OpMinusMinus, |
66 | OpAndEq, |
67 | OpXOrEq, |
68 | OpOrEq, |
69 | OpModEq, |
70 | OpPowEq, |
71 | OpLShift, |
72 | OpRShift, |
73 | OpURShift |
74 | }; |
75 | |
76 | enum LogicalOperator : uint8_t { |
77 | OpLogicalAnd, |
78 | OpLogicalOr |
79 | }; |
80 | |
81 | enum FallThroughMode : uint8_t { |
82 | FallThroughMeansTrue = 0, |
83 | FallThroughMeansFalse = 1 |
84 | }; |
85 | inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); } |
86 | |
87 | namespace DeclarationStacks { |
88 | typedef Vector<FunctionMetadataNode*> FunctionStack; |
89 | } |
90 | |
91 | struct SwitchInfo { |
92 | enum SwitchType : uint8_t { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString }; |
93 | uint32_t bytecodeOffset; |
94 | SwitchType switchType; |
95 | }; |
96 | |
97 | enum class AssignmentContext : uint8_t { |
98 | DeclarationStatement, |
99 | ConstDeclarationStatement, |
100 | AssignmentExpression |
101 | }; |
102 | |
103 | class ParserArenaFreeable { |
104 | public: |
105 | // ParserArenaFreeable objects are freed when the arena is deleted. |
106 | // Destructors are not called. Clients must not call delete on such objects. |
107 | void* operator new(size_t, ParserArena&); |
108 | }; |
109 | |
110 | class ParserArenaDeletable { |
111 | public: |
112 | virtual ~ParserArenaDeletable() { } |
113 | |
114 | // ParserArenaDeletable objects are deleted when the arena is deleted. |
115 | // Clients must not call delete directly on such objects. |
116 | template<typename T> void* operator new(size_t, ParserArena&); |
117 | }; |
118 | |
119 | #define JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED_IMPL(__classToNew) \ |
120 | void* operator new(size_t size, ParserArena& parserArena) \ |
121 | { \ |
122 | return ParserArenaDeletable::operator new<__classToNew>(size, parserArena); \ |
123 | } |
124 | |
125 | #define JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(__classToNew) \ |
126 | public: \ |
127 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED_IMPL(__classToNew) \ |
128 | private: \ |
129 | typedef int __thisIsHereToForceASemicolonAfterThisMacro |
130 | |
131 | class ParserArenaRoot { |
132 | WTF_MAKE_FAST_ALLOCATED; |
133 | protected: |
134 | ParserArenaRoot(ParserArena&); |
135 | |
136 | public: |
137 | ParserArena& parserArena() { return m_arena; } |
138 | virtual ~ParserArenaRoot() { } |
139 | |
140 | protected: |
141 | ParserArena m_arena; |
142 | }; |
143 | |
144 | class Node : public ParserArenaFreeable { |
145 | protected: |
146 | Node(const JSTokenLocation&); |
147 | |
148 | public: |
149 | virtual ~Node() { } |
150 | |
151 | int firstLine() const { return m_position.line; } |
152 | int startOffset() const { return m_position.offset; } |
153 | int endOffset() const { return m_endOffset; } |
154 | int lineStartOffset() const { return m_position.lineStartOffset; } |
155 | const JSTextPosition& position() const { return m_position; } |
156 | void setEndOffset(int offset) { m_endOffset = offset; } |
157 | void setStartOffset(int offset) { m_position.offset = offset; } |
158 | |
159 | bool needsDebugHook() const { return m_needsDebugHook; } |
160 | void setNeedsDebugHook() { m_needsDebugHook = true; } |
161 | |
162 | protected: |
163 | JSTextPosition m_position; |
164 | int m_endOffset { -1 }; |
165 | bool m_needsDebugHook { false }; |
166 | }; |
167 | |
168 | class ExpressionNode : public Node { |
169 | protected: |
170 | ExpressionNode(const JSTokenLocation&, ResultType = ResultType::unknownType()); |
171 | |
172 | public: |
173 | virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0; |
174 | |
175 | virtual bool isNumber() const { return false; } |
176 | virtual bool isString() const { return false; } |
177 | virtual bool isBigInt() const { return false; } |
178 | virtual bool isObjectLiteral() const { return false; } |
179 | virtual bool isArrayLiteral() const { return false; } |
180 | virtual bool isNull() const { return false; } |
181 | virtual bool isPure(BytecodeGenerator&) const { return false; } |
182 | virtual bool isConstant() const { return false; } |
183 | virtual bool isLocation() const { return false; } |
184 | virtual bool isAssignmentLocation() const { return isLocation(); } |
185 | virtual bool isResolveNode() const { return false; } |
186 | virtual bool isAssignResolveNode() const { return false; } |
187 | virtual bool isBracketAccessorNode() const { return false; } |
188 | virtual bool isDotAccessorNode() const { return false; } |
189 | virtual bool isDestructuringNode() const { return false; } |
190 | virtual bool isBaseFuncExprNode() const { return false; } |
191 | virtual bool isFuncExprNode() const { return false; } |
192 | virtual bool isArrowFuncExprNode() const { return false; } |
193 | virtual bool isClassExprNode() const { return false; } |
194 | virtual bool isCommaNode() const { return false; } |
195 | virtual bool isSimpleArray() const { return false; } |
196 | virtual bool isAdd() const { return false; } |
197 | virtual bool isSubtract() const { return false; } |
198 | virtual bool isBoolean() const { return false; } |
199 | virtual bool isSpreadExpression() const { return false; } |
200 | virtual bool isSuperNode() const { return false; } |
201 | virtual bool isImportNode() const { return false; } |
202 | virtual bool isMetaProperty() const { return false; } |
203 | virtual bool isNewTarget() const { return false; } |
204 | virtual bool isImportMeta() const { return false; } |
205 | virtual bool isBytecodeIntrinsicNode() const { return false; } |
206 | virtual bool isBinaryOpNode() const { return false; } |
207 | virtual bool isFunctionCall() const { return false; } |
208 | virtual bool isDeleteNode() const { return false; } |
209 | virtual bool isOptionalChain() const { return false; } |
210 | |
211 | virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label&, Label&, FallThroughMode); |
212 | |
213 | virtual ExpressionNode* stripUnaryPlus() { return this; } |
214 | |
215 | ResultType resultDescriptor() const { return m_resultType; } |
216 | |
217 | bool isOptionalChainBase() const { return m_isOptionalChainBase; } |
218 | void setIsOptionalChainBase() { m_isOptionalChainBase = true; } |
219 | |
220 | private: |
221 | ResultType m_resultType; |
222 | bool m_isOptionalChainBase { false }; |
223 | }; |
224 | |
225 | class StatementNode : public Node { |
226 | protected: |
227 | StatementNode(const JSTokenLocation&); |
228 | |
229 | public: |
230 | virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0; |
231 | |
232 | void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset); |
233 | unsigned lastLine() const { return m_lastLine; } |
234 | |
235 | StatementNode* next() const { return m_next; } |
236 | void setNext(StatementNode* next) { m_next = next; } |
237 | |
238 | virtual bool hasCompletionValue() const { return true; } |
239 | virtual bool hasEarlyBreakOrContinue() const { return false; } |
240 | |
241 | virtual bool isEmptyStatement() const { return false; } |
242 | virtual bool isDebuggerStatement() const { return false; } |
243 | virtual bool isFunctionNode() const { return false; } |
244 | virtual bool isReturnNode() const { return false; } |
245 | virtual bool isExprStatement() const { return false; } |
246 | virtual bool isBreak() const { return false; } |
247 | virtual bool isContinue() const { return false; } |
248 | virtual bool isLabel() const { return false; } |
249 | virtual bool isBlock() const { return false; } |
250 | virtual bool isFuncDeclNode() const { return false; } |
251 | virtual bool isModuleDeclarationNode() const { return false; } |
252 | virtual bool isForOfNode() const { return false; } |
253 | |
254 | protected: |
255 | int m_lastLine { -1 }; |
256 | StatementNode* m_next { nullptr }; |
257 | }; |
258 | |
259 | class VariableEnvironmentNode : public ParserArenaDeletable { |
260 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(VariableEnvironmentNode); |
261 | public: |
262 | typedef DeclarationStacks::FunctionStack FunctionStack; |
263 | |
264 | VariableEnvironmentNode() |
265 | { |
266 | } |
267 | |
268 | VariableEnvironmentNode(VariableEnvironment& lexicalDeclaredVariables); |
269 | VariableEnvironmentNode(VariableEnvironment& lexicalDeclaredVariables, FunctionStack&&); |
270 | |
271 | VariableEnvironment& lexicalVariables() { return m_lexicalVariables; } |
272 | FunctionStack& functionStack() { return m_functionStack; } |
273 | |
274 | protected: |
275 | VariableEnvironment m_lexicalVariables; |
276 | FunctionStack m_functionStack; |
277 | }; |
278 | |
279 | class ConstantNode : public ExpressionNode { |
280 | public: |
281 | ConstantNode(const JSTokenLocation&, ResultType); |
282 | bool isPure(BytecodeGenerator&) const override { return true; } |
283 | bool isConstant() const override { return true; } |
284 | virtual JSValue jsValue(BytecodeGenerator&) const = 0; |
285 | private: |
286 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
287 | void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override; |
288 | }; |
289 | |
290 | class NullNode final : public ConstantNode { |
291 | public: |
292 | NullNode(const JSTokenLocation&); |
293 | |
294 | private: |
295 | bool isNull() const override { return true; } |
296 | JSValue jsValue(BytecodeGenerator&) const override { return jsNull(); } |
297 | }; |
298 | |
299 | class BooleanNode final : public ConstantNode { |
300 | public: |
301 | BooleanNode(const JSTokenLocation&, bool value); |
302 | bool value() { return m_value; } |
303 | |
304 | private: |
305 | bool isBoolean() const override { return true; } |
306 | JSValue jsValue(BytecodeGenerator&) const override { return jsBoolean(m_value); } |
307 | |
308 | bool m_value; |
309 | }; |
310 | |
311 | class NumberNode : public ConstantNode { |
312 | public: |
313 | NumberNode(const JSTokenLocation&, double value); |
314 | double value() const { return m_value; } |
315 | virtual bool isIntegerNode() const = 0; |
316 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) final; |
317 | |
318 | private: |
319 | bool isNumber() const final { return true; } |
320 | JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); } |
321 | |
322 | double m_value; |
323 | }; |
324 | |
325 | class DoubleNode : public NumberNode { |
326 | public: |
327 | DoubleNode(const JSTokenLocation&, double value); |
328 | |
329 | private: |
330 | bool isIntegerNode() const override { return false; } |
331 | }; |
332 | |
333 | // An integer node represent a number represented as an integer (e.g. 42 instead of 42., 42.0, 42e0) |
334 | class IntegerNode final : public DoubleNode { |
335 | public: |
336 | IntegerNode(const JSTokenLocation&, double value); |
337 | bool isIntegerNode() const final { return true; } |
338 | }; |
339 | |
340 | class StringNode final : public ConstantNode { |
341 | public: |
342 | StringNode(const JSTokenLocation&, const Identifier&); |
343 | const Identifier& value() { return m_value; } |
344 | |
345 | private: |
346 | bool isString() const override { return true; } |
347 | JSValue jsValue(BytecodeGenerator&) const override; |
348 | |
349 | const Identifier& m_value; |
350 | }; |
351 | |
352 | class BigIntNode final : public ConstantNode { |
353 | public: |
354 | BigIntNode(const JSTokenLocation&, const Identifier&, uint8_t radix); |
355 | BigIntNode(const JSTokenLocation&, const Identifier&, uint8_t radix, bool sign); |
356 | const Identifier& value() { return m_value; } |
357 | |
358 | const Identifier& identifier() const { return m_value; } |
359 | uint8_t radix() const { return m_radix; } |
360 | bool sign() const { return m_sign; } |
361 | |
362 | private: |
363 | bool isBigInt() const final { return true; } |
364 | JSValue jsValue(BytecodeGenerator&) const final; |
365 | |
366 | const Identifier& m_value; |
367 | const uint8_t m_radix; |
368 | const bool m_sign; |
369 | }; |
370 | |
371 | class ThrowableExpressionData { |
372 | public: |
373 | ThrowableExpressionData() |
374 | : m_divot(-1, -1, -1) |
375 | , m_divotStart(-1, -1, -1) |
376 | , m_divotEnd(-1, -1, -1) |
377 | { |
378 | } |
379 | |
380 | ThrowableExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end) |
381 | : m_divot(divot) |
382 | , m_divotStart(start) |
383 | , m_divotEnd(end) |
384 | { |
385 | ASSERT(m_divot.offset >= m_divot.lineStartOffset); |
386 | ASSERT(m_divotStart.offset >= m_divotStart.lineStartOffset); |
387 | ASSERT(m_divotEnd.offset >= m_divotEnd.lineStartOffset); |
388 | } |
389 | |
390 | void setExceptionSourceCode(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) |
391 | { |
392 | ASSERT(divot.offset >= divot.lineStartOffset); |
393 | ASSERT(divotStart.offset >= divotStart.lineStartOffset); |
394 | ASSERT(divotEnd.offset >= divotEnd.lineStartOffset); |
395 | m_divot = divot; |
396 | m_divotStart = divotStart; |
397 | m_divotEnd = divotEnd; |
398 | } |
399 | |
400 | const JSTextPosition& divot() const { return m_divot; } |
401 | const JSTextPosition& divotStart() const { return m_divotStart; } |
402 | const JSTextPosition& divotEnd() const { return m_divotEnd; } |
403 | |
404 | protected: |
405 | RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message); |
406 | |
407 | private: |
408 | JSTextPosition m_divot; |
409 | JSTextPosition m_divotStart; |
410 | JSTextPosition m_divotEnd; |
411 | }; |
412 | |
413 | class ThrowableSubExpressionData : public ThrowableExpressionData { |
414 | public: |
415 | ThrowableSubExpressionData() |
416 | : m_subexpressionDivotOffset(0) |
417 | , m_subexpressionEndOffset(0) |
418 | , m_subexpressionLineOffset(0) |
419 | , m_subexpressionLineStartOffset(0) |
420 | { |
421 | } |
422 | |
423 | ThrowableSubExpressionData(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd) |
424 | : ThrowableExpressionData(divot, divotStart, divotEnd) |
425 | , m_subexpressionDivotOffset(0) |
426 | , m_subexpressionEndOffset(0) |
427 | , m_subexpressionLineOffset(0) |
428 | , m_subexpressionLineStartOffset(0) |
429 | { |
430 | } |
431 | |
432 | void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset) |
433 | { |
434 | ASSERT(subexpressionDivot.offset <= divot().offset); |
435 | // Overflow means we can't do this safely, so just point at the primary divot, |
436 | // divotLine, or divotLineStart. |
437 | if ((divot() - subexpressionDivot.offset) & ~0xFFFF) |
438 | return; |
439 | if ((divot().line - subexpressionDivot.line) & ~0xFFFF) |
440 | return; |
441 | if ((divot().lineStartOffset - subexpressionDivot.lineStartOffset) & ~0xFFFF) |
442 | return; |
443 | if ((divotEnd() - subexpressionOffset) & ~0xFFFF) |
444 | return; |
445 | m_subexpressionDivotOffset = divot() - subexpressionDivot.offset; |
446 | m_subexpressionEndOffset = divotEnd() - subexpressionOffset; |
447 | m_subexpressionLineOffset = divot().line - subexpressionDivot.line; |
448 | m_subexpressionLineStartOffset = divot().lineStartOffset - subexpressionDivot.lineStartOffset; |
449 | } |
450 | |
451 | JSTextPosition subexpressionDivot() |
452 | { |
453 | int newLine = divot().line - m_subexpressionLineOffset; |
454 | int newOffset = divot().offset - m_subexpressionDivotOffset; |
455 | int newLineStartOffset = divot().lineStartOffset - m_subexpressionLineStartOffset; |
456 | return JSTextPosition(newLine, newOffset, newLineStartOffset); |
457 | } |
458 | JSTextPosition subexpressionStart() { return divotStart(); } |
459 | JSTextPosition subexpressionEnd() { return divotEnd() - static_cast<int>(m_subexpressionEndOffset); } |
460 | |
461 | protected: |
462 | uint16_t m_subexpressionDivotOffset; |
463 | uint16_t m_subexpressionEndOffset; |
464 | uint16_t m_subexpressionLineOffset; |
465 | uint16_t m_subexpressionLineStartOffset; |
466 | }; |
467 | |
468 | class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData { |
469 | public: |
470 | ThrowablePrefixedSubExpressionData() |
471 | : m_subexpressionDivotOffset(0) |
472 | , m_subexpressionStartOffset(0) |
473 | , m_subexpressionLineOffset(0) |
474 | , m_subexpressionLineStartOffset(0) |
475 | { |
476 | } |
477 | |
478 | ThrowablePrefixedSubExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end) |
479 | : ThrowableExpressionData(divot, start, end) |
480 | , m_subexpressionDivotOffset(0) |
481 | , m_subexpressionStartOffset(0) |
482 | , m_subexpressionLineOffset(0) |
483 | , m_subexpressionLineStartOffset(0) |
484 | { |
485 | } |
486 | |
487 | void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset) |
488 | { |
489 | ASSERT(subexpressionDivot.offset >= divot().offset); |
490 | // Overflow means we can't do this safely, so just point at the primary divot, |
491 | // divotLine, or divotLineStart. |
492 | if ((subexpressionDivot.offset - divot()) & ~0xFFFF) |
493 | return; |
494 | if ((subexpressionDivot.line - divot().line) & ~0xFFFF) |
495 | return; |
496 | if ((subexpressionDivot.lineStartOffset - divot().lineStartOffset) & ~0xFFFF) |
497 | return; |
498 | if ((subexpressionOffset - divotStart()) & ~0xFFFF) |
499 | return; |
500 | m_subexpressionDivotOffset = subexpressionDivot.offset - divot(); |
501 | m_subexpressionStartOffset = subexpressionOffset - divotStart(); |
502 | m_subexpressionLineOffset = subexpressionDivot.line - divot().line; |
503 | m_subexpressionLineStartOffset = subexpressionDivot.lineStartOffset - divot().lineStartOffset; |
504 | } |
505 | |
506 | JSTextPosition subexpressionDivot() |
507 | { |
508 | int newLine = divot().line + m_subexpressionLineOffset; |
509 | int newOffset = divot().offset + m_subexpressionDivotOffset; |
510 | int newLineStartOffset = divot().lineStartOffset + m_subexpressionLineStartOffset; |
511 | return JSTextPosition(newLine, newOffset, newLineStartOffset); |
512 | } |
513 | JSTextPosition subexpressionStart() { return divotStart() + static_cast<int>(m_subexpressionStartOffset); } |
514 | JSTextPosition subexpressionEnd() { return divotEnd(); } |
515 | |
516 | protected: |
517 | uint16_t m_subexpressionDivotOffset; |
518 | uint16_t m_subexpressionStartOffset; |
519 | uint16_t m_subexpressionLineOffset; |
520 | uint16_t m_subexpressionLineStartOffset; |
521 | }; |
522 | |
523 | class TemplateExpressionListNode final : public ParserArenaFreeable { |
524 | public: |
525 | TemplateExpressionListNode(ExpressionNode*); |
526 | TemplateExpressionListNode(TemplateExpressionListNode*, ExpressionNode*); |
527 | |
528 | ExpressionNode* value() { return m_node; } |
529 | TemplateExpressionListNode* next() { return m_next; } |
530 | |
531 | private: |
532 | TemplateExpressionListNode* m_next { nullptr }; |
533 | ExpressionNode* m_node { nullptr }; |
534 | }; |
535 | |
536 | class TemplateStringNode final : public ExpressionNode { |
537 | public: |
538 | TemplateStringNode(const JSTokenLocation&, const Identifier* cooked, const Identifier* raw); |
539 | |
540 | const Identifier* cooked() { return m_cooked; } |
541 | const Identifier* raw() { return m_raw; } |
542 | |
543 | private: |
544 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
545 | |
546 | const Identifier* m_cooked; |
547 | const Identifier* m_raw; |
548 | }; |
549 | |
550 | class TemplateStringListNode final : public ParserArenaFreeable { |
551 | public: |
552 | TemplateStringListNode(TemplateStringNode*); |
553 | TemplateStringListNode(TemplateStringListNode*, TemplateStringNode*); |
554 | |
555 | TemplateStringNode* value() { return m_node; } |
556 | TemplateStringListNode* next() { return m_next; } |
557 | |
558 | private: |
559 | TemplateStringListNode* m_next { nullptr }; |
560 | TemplateStringNode* m_node { nullptr }; |
561 | }; |
562 | |
563 | class TemplateLiteralNode final : public ExpressionNode { |
564 | public: |
565 | TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*); |
566 | TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*, TemplateExpressionListNode*); |
567 | |
568 | TemplateStringListNode* templateStrings() const { return m_templateStrings; } |
569 | TemplateExpressionListNode* templateExpressions() const { return m_templateExpressions; } |
570 | |
571 | private: |
572 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
573 | |
574 | TemplateStringListNode* m_templateStrings; |
575 | TemplateExpressionListNode* m_templateExpressions; |
576 | }; |
577 | |
578 | class TaggedTemplateNode final : public ExpressionNode, public ThrowableExpressionData { |
579 | public: |
580 | TaggedTemplateNode(const JSTokenLocation&, ExpressionNode*, TemplateLiteralNode*); |
581 | |
582 | TemplateLiteralNode* templateLiteral() const { return m_templateLiteral; } |
583 | |
584 | private: |
585 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
586 | |
587 | ExpressionNode* m_tag; |
588 | TemplateLiteralNode* m_templateLiteral; |
589 | }; |
590 | |
591 | class RegExpNode final : public ExpressionNode, public ThrowableExpressionData { |
592 | public: |
593 | RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags); |
594 | |
595 | private: |
596 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
597 | |
598 | const Identifier& m_pattern; |
599 | const Identifier& m_flags; |
600 | }; |
601 | |
602 | class ThisNode final : public ExpressionNode { |
603 | public: |
604 | ThisNode(const JSTokenLocation&); |
605 | |
606 | private: |
607 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
608 | }; |
609 | |
610 | class SuperNode final : public ExpressionNode { |
611 | public: |
612 | SuperNode(const JSTokenLocation&); |
613 | |
614 | private: |
615 | bool isSuperNode() const override { return true; } |
616 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
617 | }; |
618 | |
619 | class ImportNode final : public ExpressionNode, public ThrowableExpressionData { |
620 | public: |
621 | ImportNode(const JSTokenLocation&, ExpressionNode*); |
622 | |
623 | private: |
624 | bool isImportNode() const override { return true; } |
625 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
626 | |
627 | ExpressionNode* m_expr; |
628 | }; |
629 | |
630 | class MetaPropertyNode : public ExpressionNode { |
631 | public: |
632 | MetaPropertyNode(const JSTokenLocation&); |
633 | |
634 | private: |
635 | bool isMetaProperty() const final { return true; } |
636 | }; |
637 | |
638 | class NewTargetNode final : public MetaPropertyNode { |
639 | public: |
640 | NewTargetNode(const JSTokenLocation&); |
641 | |
642 | private: |
643 | bool isNewTarget() const final { return true; } |
644 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
645 | }; |
646 | |
647 | class ImportMetaNode final : public MetaPropertyNode { |
648 | public: |
649 | ImportMetaNode(const JSTokenLocation&, ExpressionNode*); |
650 | |
651 | private: |
652 | bool isImportMeta() const final { return true; } |
653 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
654 | |
655 | ExpressionNode* m_expr; |
656 | }; |
657 | |
658 | class ResolveNode final : public ExpressionNode { |
659 | public: |
660 | ResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& start); |
661 | |
662 | const Identifier& identifier() const { return m_ident; } |
663 | |
664 | private: |
665 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
666 | |
667 | bool isPure(BytecodeGenerator&) const override; |
668 | bool isLocation() const override { return true; } |
669 | bool isResolveNode() const override { return true; } |
670 | |
671 | const Identifier& m_ident; |
672 | JSTextPosition m_start; |
673 | }; |
674 | |
675 | class ElementNode final : public ParserArenaFreeable { |
676 | public: |
677 | ElementNode(int elision, ExpressionNode*); |
678 | ElementNode(ElementNode*, int elision, ExpressionNode*); |
679 | |
680 | int elision() const { return m_elision; } |
681 | ExpressionNode* value() { return m_node; } |
682 | ElementNode* next() { return m_next; } |
683 | |
684 | private: |
685 | ElementNode* m_next { nullptr }; |
686 | ExpressionNode* m_node; |
687 | int m_elision; |
688 | }; |
689 | |
690 | class ArrayNode final : public ExpressionNode { |
691 | public: |
692 | ArrayNode(const JSTokenLocation&, int elision); |
693 | ArrayNode(const JSTokenLocation&, ElementNode*); |
694 | ArrayNode(const JSTokenLocation&, int elision, ElementNode*); |
695 | |
696 | bool isArrayLiteral() const override { return true; } |
697 | |
698 | ArgumentListNode* toArgumentList(ParserArena&, int, int) const; |
699 | |
700 | ElementNode* elements() const { return m_element; } |
701 | private: |
702 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
703 | |
704 | bool isSimpleArray() const override; |
705 | |
706 | ElementNode* m_element; |
707 | int m_elision; |
708 | bool m_optional; |
709 | }; |
710 | |
711 | enum class ClassElementTag : uint8_t { No, Instance, Static, LastTag }; |
712 | class PropertyNode final : public ParserArenaFreeable { |
713 | public: |
714 | enum Type : uint8_t { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16, Spread = 32 }; |
715 | enum PutType : uint8_t { Unknown, KnownDirect }; |
716 | |
717 | PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag); |
718 | PropertyNode(ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag); |
719 | PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag); |
720 | |
721 | ExpressionNode* expressionName() const { return m_expression; } |
722 | const Identifier* name() const { return m_name; } |
723 | |
724 | Type type() const { return static_cast<Type>(m_type); } |
725 | bool needsSuperBinding() const { return m_needsSuperBinding; } |
726 | bool isClassProperty() const { return static_cast<ClassElementTag>(m_classElementTag) != ClassElementTag::No; } |
727 | bool isStaticClassProperty() const { return static_cast<ClassElementTag>(m_classElementTag) == ClassElementTag::Static; } |
728 | bool isInstanceClassProperty() const { return static_cast<ClassElementTag>(m_classElementTag) == ClassElementTag::Instance; } |
729 | bool isOverriddenByDuplicate() const { return m_isOverriddenByDuplicate; } |
730 | void setIsOverriddenByDuplicate() { m_isOverriddenByDuplicate = true; } |
731 | PutType putType() const { return static_cast<PutType>(m_putType); } |
732 | |
733 | private: |
734 | friend class PropertyListNode; |
735 | const Identifier* m_name; |
736 | ExpressionNode* m_expression; |
737 | ExpressionNode* m_assign; |
738 | unsigned m_type : 6; |
739 | unsigned m_needsSuperBinding : 1; |
740 | unsigned m_putType : 1; |
741 | static_assert(1 << 2 > static_cast<unsigned>(ClassElementTag::LastTag), "ClassElementTag shouldn't use more than two bits" ); |
742 | unsigned m_classElementTag : 2; |
743 | unsigned m_isOverriddenByDuplicate: 1; |
744 | }; |
745 | |
746 | class PropertyListNode final : public ExpressionNode { |
747 | public: |
748 | PropertyListNode(const JSTokenLocation&, PropertyNode*); |
749 | PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*); |
750 | |
751 | bool hasStaticallyNamedProperty(const Identifier& propName); |
752 | |
753 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID*, RegisterID*); |
754 | |
755 | private: |
756 | RegisterID* emitBytecode(BytecodeGenerator& generator, RegisterID* dst = nullptr) override |
757 | { |
758 | return emitBytecode(generator, dst, nullptr); |
759 | } |
760 | void emitPutConstantProperty(BytecodeGenerator&, RegisterID*, PropertyNode&); |
761 | |
762 | PropertyNode* m_node; |
763 | PropertyListNode* m_next { nullptr }; |
764 | }; |
765 | |
766 | class ObjectLiteralNode final : public ExpressionNode { |
767 | public: |
768 | ObjectLiteralNode(const JSTokenLocation&); |
769 | ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*); |
770 | bool isObjectLiteral() const override { return true; } |
771 | |
772 | private: |
773 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
774 | |
775 | PropertyListNode* m_list; |
776 | }; |
777 | |
778 | class BracketAccessorNode final : public ExpressionNode, public ThrowableExpressionData { |
779 | public: |
780 | BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments); |
781 | |
782 | ExpressionNode* base() const { return m_base; } |
783 | ExpressionNode* subscript() const { return m_subscript; } |
784 | |
785 | bool subscriptHasAssignments() const { return m_subscriptHasAssignments; } |
786 | |
787 | private: |
788 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
789 | |
790 | bool isLocation() const override { return true; } |
791 | bool isBracketAccessorNode() const override { return true; } |
792 | |
793 | ExpressionNode* m_base; |
794 | ExpressionNode* m_subscript; |
795 | bool m_subscriptHasAssignments; |
796 | }; |
797 | |
798 | class DotAccessorNode final : public ExpressionNode, public ThrowableExpressionData { |
799 | public: |
800 | DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&); |
801 | |
802 | ExpressionNode* base() const { return m_base; } |
803 | const Identifier& identifier() const { return m_ident; } |
804 | |
805 | private: |
806 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
807 | |
808 | bool isLocation() const override { return true; } |
809 | bool isDotAccessorNode() const override { return true; } |
810 | |
811 | ExpressionNode* m_base; |
812 | const Identifier& m_ident; |
813 | }; |
814 | |
815 | class SpreadExpressionNode final : public ExpressionNode, public ThrowableExpressionData { |
816 | public: |
817 | SpreadExpressionNode(const JSTokenLocation&, ExpressionNode*); |
818 | |
819 | ExpressionNode* expression() const { return m_expression; } |
820 | |
821 | private: |
822 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
823 | |
824 | bool isSpreadExpression() const override { return true; } |
825 | ExpressionNode* m_expression; |
826 | }; |
827 | |
828 | class ObjectSpreadExpressionNode final : public ExpressionNode, public ThrowableExpressionData { |
829 | public: |
830 | ObjectSpreadExpressionNode(const JSTokenLocation&, ExpressionNode*); |
831 | |
832 | ExpressionNode* expression() const { return m_expression; } |
833 | |
834 | private: |
835 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
836 | |
837 | ExpressionNode* m_expression; |
838 | }; |
839 | |
840 | class ArgumentListNode final : public ExpressionNode { |
841 | public: |
842 | ArgumentListNode(const JSTokenLocation&, ExpressionNode*); |
843 | ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*); |
844 | |
845 | ArgumentListNode* m_next { nullptr }; |
846 | ExpressionNode* m_expr; |
847 | |
848 | private: |
849 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
850 | }; |
851 | |
852 | class ArgumentsNode final : public ParserArenaFreeable { |
853 | public: |
854 | ArgumentsNode(); |
855 | ArgumentsNode(ArgumentListNode*); |
856 | |
857 | ArgumentListNode* m_listNode; |
858 | }; |
859 | |
860 | class NewExprNode final : public ExpressionNode, public ThrowableExpressionData { |
861 | public: |
862 | NewExprNode(const JSTokenLocation&, ExpressionNode*); |
863 | NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*); |
864 | |
865 | private: |
866 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
867 | |
868 | ExpressionNode* m_expr; |
869 | ArgumentsNode* m_args; |
870 | }; |
871 | |
872 | class EvalFunctionCallNode final : public ExpressionNode, public ThrowableExpressionData { |
873 | public: |
874 | EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
875 | |
876 | private: |
877 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
878 | |
879 | bool isFunctionCall() const override { return true; } |
880 | |
881 | ArgumentsNode* m_args; |
882 | }; |
883 | |
884 | class FunctionCallValueNode final : public ExpressionNode, public ThrowableExpressionData { |
885 | public: |
886 | FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
887 | |
888 | private: |
889 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
890 | |
891 | bool isFunctionCall() const override { return true; } |
892 | |
893 | ExpressionNode* m_expr; |
894 | ArgumentsNode* m_args; |
895 | }; |
896 | |
897 | class FunctionCallResolveNode final : public ExpressionNode, public ThrowableExpressionData { |
898 | public: |
899 | FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
900 | |
901 | private: |
902 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
903 | |
904 | bool isFunctionCall() const override { return true; } |
905 | |
906 | const Identifier& m_ident; |
907 | ArgumentsNode* m_args; |
908 | }; |
909 | |
910 | class FunctionCallBracketNode final : public ExpressionNode, public ThrowableSubExpressionData { |
911 | public: |
912 | FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
913 | |
914 | private: |
915 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
916 | |
917 | bool isFunctionCall() const override { return true; } |
918 | |
919 | ExpressionNode* m_base; |
920 | ExpressionNode* m_subscript; |
921 | ArgumentsNode* m_args; |
922 | bool m_subscriptHasAssignments; |
923 | }; |
924 | |
925 | class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData { |
926 | public: |
927 | FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
928 | |
929 | private: |
930 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
931 | |
932 | protected: |
933 | bool isFunctionCall() const override { return true; } |
934 | |
935 | ExpressionNode* m_base; |
936 | const Identifier& m_ident; |
937 | ArgumentsNode* m_args; |
938 | }; |
939 | |
940 | class BytecodeIntrinsicNode final : public ExpressionNode, public ThrowableExpressionData { |
941 | public: |
942 | enum class Type : uint8_t { |
943 | Constant, |
944 | Function |
945 | }; |
946 | |
947 | BytecodeIntrinsicNode(Type, const JSTokenLocation&, BytecodeIntrinsicRegistry::Entry, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
948 | |
949 | bool isBytecodeIntrinsicNode() const override { return true; } |
950 | |
951 | Type type() const { return m_type; } |
952 | BytecodeIntrinsicRegistry::Entry entry() const { return m_entry; } |
953 | const Identifier& identifier() const { return m_ident; } |
954 | |
955 | #define JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS(name) RegisterID* emit_intrinsic_##name(BytecodeGenerator&, RegisterID*); |
956 | JSC_COMMON_BYTECODE_INTRINSIC_FUNCTIONS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS) |
957 | JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS) |
958 | #undef JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS |
959 | |
960 | private: |
961 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
962 | |
963 | bool isFunctionCall() const override { return m_type == Type::Function; } |
964 | |
965 | BytecodeIntrinsicRegistry::Entry m_entry; |
966 | const Identifier& m_ident; |
967 | ArgumentsNode* m_args; |
968 | Type m_type; |
969 | }; |
970 | |
971 | class CallFunctionCallDotNode final : public FunctionCallDotNode { |
972 | public: |
973 | CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, size_t distanceToInnermostCallOrApply); |
974 | |
975 | private: |
976 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
977 | size_t m_distanceToInnermostCallOrApply; |
978 | }; |
979 | |
980 | class ApplyFunctionCallDotNode final : public FunctionCallDotNode { |
981 | public: |
982 | ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, size_t distanceToInnermostCallOrApply); |
983 | |
984 | private: |
985 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
986 | size_t m_distanceToInnermostCallOrApply; |
987 | }; |
988 | |
989 | class DeleteResolveNode final : public ExpressionNode, public ThrowableExpressionData { |
990 | public: |
991 | DeleteResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
992 | |
993 | private: |
994 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
995 | |
996 | bool isDeleteNode() const final { return true; } |
997 | |
998 | const Identifier& m_ident; |
999 | }; |
1000 | |
1001 | class DeleteBracketNode final : public ExpressionNode, public ThrowableExpressionData { |
1002 | public: |
1003 | DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
1004 | |
1005 | private: |
1006 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1007 | |
1008 | bool isDeleteNode() const final { return true; } |
1009 | |
1010 | ExpressionNode* m_base; |
1011 | ExpressionNode* m_subscript; |
1012 | }; |
1013 | |
1014 | class DeleteDotNode final : public ExpressionNode, public ThrowableExpressionData { |
1015 | public: |
1016 | DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
1017 | |
1018 | private: |
1019 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1020 | |
1021 | bool isDeleteNode() const final { return true; } |
1022 | |
1023 | ExpressionNode* m_base; |
1024 | const Identifier& m_ident; |
1025 | }; |
1026 | |
1027 | class DeleteValueNode final : public ExpressionNode { |
1028 | public: |
1029 | DeleteValueNode(const JSTokenLocation&, ExpressionNode*); |
1030 | |
1031 | private: |
1032 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1033 | |
1034 | bool isDeleteNode() const final { return true; } |
1035 | |
1036 | ExpressionNode* m_expr; |
1037 | }; |
1038 | |
1039 | class VoidNode final : public ExpressionNode { |
1040 | public: |
1041 | VoidNode(const JSTokenLocation&, ExpressionNode*); |
1042 | |
1043 | private: |
1044 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1045 | |
1046 | ExpressionNode* m_expr; |
1047 | }; |
1048 | |
1049 | class TypeOfResolveNode final : public ExpressionNode { |
1050 | public: |
1051 | TypeOfResolveNode(const JSTokenLocation&, const Identifier&); |
1052 | |
1053 | const Identifier& identifier() const { return m_ident; } |
1054 | |
1055 | private: |
1056 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1057 | |
1058 | const Identifier& m_ident; |
1059 | }; |
1060 | |
1061 | class TypeOfValueNode final : public ExpressionNode { |
1062 | public: |
1063 | TypeOfValueNode(const JSTokenLocation&, ExpressionNode*); |
1064 | |
1065 | private: |
1066 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1067 | |
1068 | ExpressionNode* m_expr; |
1069 | }; |
1070 | |
1071 | class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData { |
1072 | public: |
1073 | PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
1074 | |
1075 | protected: |
1076 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1077 | virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0); |
1078 | virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0); |
1079 | virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0); |
1080 | |
1081 | ExpressionNode* m_expr; |
1082 | Operator m_operator; |
1083 | }; |
1084 | |
1085 | class PostfixNode final : public PrefixNode { |
1086 | public: |
1087 | PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
1088 | |
1089 | private: |
1090 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1091 | RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0) override; |
1092 | RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0) override; |
1093 | RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0) override; |
1094 | }; |
1095 | |
1096 | class UnaryOpNode : public ExpressionNode { |
1097 | public: |
1098 | UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID); |
1099 | |
1100 | protected: |
1101 | ExpressionNode* expr() { return m_expr; } |
1102 | const ExpressionNode* expr() const { return m_expr; } |
1103 | OpcodeID opcodeID() const { return m_opcodeID; } |
1104 | |
1105 | private: |
1106 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1107 | |
1108 | ExpressionNode* m_expr; |
1109 | OpcodeID m_opcodeID; |
1110 | }; |
1111 | |
1112 | class UnaryPlusNode final : public UnaryOpNode { |
1113 | public: |
1114 | UnaryPlusNode(const JSTokenLocation&, ExpressionNode*); |
1115 | |
1116 | private: |
1117 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1118 | |
1119 | ExpressionNode* stripUnaryPlus() override { return expr(); } |
1120 | }; |
1121 | |
1122 | class NegateNode final : public UnaryOpNode { |
1123 | public: |
1124 | NegateNode(const JSTokenLocation&, ExpressionNode*); |
1125 | }; |
1126 | |
1127 | class BitwiseNotNode final : public UnaryOpNode { |
1128 | public: |
1129 | BitwiseNotNode(const JSTokenLocation&, ExpressionNode*); |
1130 | }; |
1131 | |
1132 | class LogicalNotNode final : public UnaryOpNode { |
1133 | public: |
1134 | LogicalNotNode(const JSTokenLocation&, ExpressionNode*); |
1135 | private: |
1136 | void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override; |
1137 | }; |
1138 | |
1139 | class BinaryOpNode : public ExpressionNode { |
1140 | public: |
1141 | BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); |
1142 | BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); |
1143 | |
1144 | RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0); |
1145 | void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override; |
1146 | |
1147 | ExpressionNode* lhs() { return m_expr1; }; |
1148 | ExpressionNode* rhs() { return m_expr2; }; |
1149 | |
1150 | bool isBinaryOpNode() const override { return true; } |
1151 | |
1152 | private: |
1153 | enum class UInt32Result : uint8_t { UInt32, Constant, }; |
1154 | |
1155 | void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression); |
1156 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1157 | |
1158 | protected: |
1159 | OpcodeID opcodeID() const { return m_opcodeID; } |
1160 | |
1161 | protected: |
1162 | bool m_rightHasAssignments; |
1163 | bool m_shouldToUnsignedResult { true }; |
1164 | private: |
1165 | OpcodeID m_opcodeID; |
1166 | protected: |
1167 | ExpressionNode* m_expr1; |
1168 | ExpressionNode* m_expr2; |
1169 | }; |
1170 | |
1171 | class PowNode final : public BinaryOpNode { |
1172 | public: |
1173 | PowNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1174 | }; |
1175 | |
1176 | class MultNode final : public BinaryOpNode { |
1177 | public: |
1178 | MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1179 | }; |
1180 | |
1181 | class DivNode final : public BinaryOpNode { |
1182 | public: |
1183 | DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1184 | }; |
1185 | |
1186 | class ModNode final : public BinaryOpNode { |
1187 | public: |
1188 | ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1189 | }; |
1190 | |
1191 | class AddNode final : public BinaryOpNode { |
1192 | public: |
1193 | AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1194 | |
1195 | bool isAdd() const override { return true; } |
1196 | }; |
1197 | |
1198 | class SubNode final : public BinaryOpNode { |
1199 | public: |
1200 | SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1201 | |
1202 | bool isSubtract() const override { return true; } |
1203 | }; |
1204 | |
1205 | class LeftShiftNode final : public BinaryOpNode { |
1206 | public: |
1207 | LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1208 | }; |
1209 | |
1210 | class RightShiftNode final : public BinaryOpNode { |
1211 | public: |
1212 | RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1213 | }; |
1214 | |
1215 | class UnsignedRightShiftNode final : public BinaryOpNode { |
1216 | public: |
1217 | UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1218 | }; |
1219 | |
1220 | class LessNode final : public BinaryOpNode { |
1221 | public: |
1222 | LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1223 | }; |
1224 | |
1225 | class GreaterNode final : public BinaryOpNode { |
1226 | public: |
1227 | GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1228 | }; |
1229 | |
1230 | class LessEqNode final : public BinaryOpNode { |
1231 | public: |
1232 | LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1233 | }; |
1234 | |
1235 | class GreaterEqNode final : public BinaryOpNode { |
1236 | public: |
1237 | GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1238 | }; |
1239 | |
1240 | class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData { |
1241 | public: |
1242 | ThrowableBinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); |
1243 | ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments); |
1244 | |
1245 | private: |
1246 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1247 | }; |
1248 | |
1249 | class InstanceOfNode final : public ThrowableBinaryOpNode { |
1250 | public: |
1251 | InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1252 | |
1253 | private: |
1254 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1255 | }; |
1256 | |
1257 | class InNode final : public ThrowableBinaryOpNode { |
1258 | public: |
1259 | InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1260 | |
1261 | private: |
1262 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1263 | }; |
1264 | |
1265 | class EqualNode final : public BinaryOpNode { |
1266 | public: |
1267 | EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1268 | |
1269 | private: |
1270 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1271 | }; |
1272 | |
1273 | class NotEqualNode final : public BinaryOpNode { |
1274 | public: |
1275 | NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1276 | }; |
1277 | |
1278 | class StrictEqualNode final : public BinaryOpNode { |
1279 | public: |
1280 | StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1281 | |
1282 | private: |
1283 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1284 | }; |
1285 | |
1286 | class NotStrictEqualNode final : public BinaryOpNode { |
1287 | public: |
1288 | NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1289 | }; |
1290 | |
1291 | class BitAndNode final : public BinaryOpNode { |
1292 | public: |
1293 | BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1294 | }; |
1295 | |
1296 | class BitOrNode final : public BinaryOpNode { |
1297 | public: |
1298 | BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1299 | }; |
1300 | |
1301 | class BitXOrNode final : public BinaryOpNode { |
1302 | public: |
1303 | BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments); |
1304 | }; |
1305 | |
1306 | // m_expr1 && m_expr2, m_expr1 || m_expr2 |
1307 | class LogicalOpNode final : public ExpressionNode { |
1308 | public: |
1309 | LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator); |
1310 | |
1311 | private: |
1312 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1313 | void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override; |
1314 | |
1315 | LogicalOperator m_operator; |
1316 | ExpressionNode* m_expr1; |
1317 | ExpressionNode* m_expr2; |
1318 | }; |
1319 | |
1320 | class CoalesceNode final : public ExpressionNode { |
1321 | public: |
1322 | CoalesceNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool); |
1323 | |
1324 | private: |
1325 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = nullptr) final; |
1326 | |
1327 | ExpressionNode* m_expr1; |
1328 | ExpressionNode* m_expr2; |
1329 | bool m_hasAbsorbedOptionalChain; |
1330 | }; |
1331 | |
1332 | class OptionalChainNode final : public ExpressionNode { |
1333 | public: |
1334 | OptionalChainNode(const JSTokenLocation&, ExpressionNode*, bool); |
1335 | |
1336 | void setExpr(ExpressionNode* expr) { m_expr = expr; } |
1337 | ExpressionNode* expr() const { return m_expr; } |
1338 | |
1339 | private: |
1340 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = nullptr) final; |
1341 | |
1342 | bool isOptionalChain() const final { return true; } |
1343 | |
1344 | ExpressionNode* m_expr; |
1345 | bool m_isOutermost; |
1346 | }; |
1347 | |
1348 | // The ternary operator, "m_logical ? m_expr1 : m_expr2" |
1349 | class ConditionalNode final : public ExpressionNode { |
1350 | public: |
1351 | ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2); |
1352 | |
1353 | private: |
1354 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1355 | |
1356 | ExpressionNode* m_logical; |
1357 | ExpressionNode* m_expr1; |
1358 | ExpressionNode* m_expr2; |
1359 | }; |
1360 | |
1361 | class ReadModifyResolveNode final : public ExpressionNode, public ThrowableExpressionData { |
1362 | public: |
1363 | ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
1364 | |
1365 | private: |
1366 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1367 | |
1368 | const Identifier& m_ident; |
1369 | ExpressionNode* m_right; |
1370 | Operator m_operator; |
1371 | bool m_rightHasAssignments; |
1372 | }; |
1373 | |
1374 | class AssignResolveNode final : public ExpressionNode, public ThrowableExpressionData { |
1375 | public: |
1376 | AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right, AssignmentContext); |
1377 | bool isAssignResolveNode() const override { return true; } |
1378 | const Identifier& identifier() const { return m_ident; } |
1379 | |
1380 | private: |
1381 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1382 | |
1383 | const Identifier& m_ident; |
1384 | ExpressionNode* m_right; |
1385 | AssignmentContext m_assignmentContext; |
1386 | }; |
1387 | |
1388 | class ReadModifyBracketNode final : public ExpressionNode, public ThrowableSubExpressionData { |
1389 | public: |
1390 | ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
1391 | |
1392 | private: |
1393 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1394 | |
1395 | ExpressionNode* m_base; |
1396 | ExpressionNode* m_subscript; |
1397 | ExpressionNode* m_right; |
1398 | unsigned m_operator : 30; |
1399 | bool m_subscriptHasAssignments : 1; |
1400 | bool m_rightHasAssignments : 1; |
1401 | }; |
1402 | |
1403 | class AssignBracketNode final : public ExpressionNode, public ThrowableExpressionData { |
1404 | public: |
1405 | AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
1406 | |
1407 | private: |
1408 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1409 | |
1410 | ExpressionNode* m_base; |
1411 | ExpressionNode* m_subscript; |
1412 | ExpressionNode* m_right; |
1413 | bool m_subscriptHasAssignments : 1; |
1414 | bool m_rightHasAssignments : 1; |
1415 | }; |
1416 | |
1417 | class AssignDotNode final : public ExpressionNode, public ThrowableExpressionData { |
1418 | public: |
1419 | AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
1420 | |
1421 | private: |
1422 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1423 | |
1424 | ExpressionNode* m_base; |
1425 | const Identifier& m_ident; |
1426 | ExpressionNode* m_right; |
1427 | bool m_rightHasAssignments; |
1428 | }; |
1429 | |
1430 | class ReadModifyDotNode final : public ExpressionNode, public ThrowableSubExpressionData { |
1431 | public: |
1432 | ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
1433 | |
1434 | private: |
1435 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1436 | |
1437 | ExpressionNode* m_base; |
1438 | const Identifier& m_ident; |
1439 | ExpressionNode* m_right; |
1440 | unsigned m_operator : 31; |
1441 | bool m_rightHasAssignments : 1; |
1442 | }; |
1443 | |
1444 | class AssignErrorNode final : public ExpressionNode, public ThrowableExpressionData { |
1445 | public: |
1446 | AssignErrorNode(const JSTokenLocation&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd); |
1447 | |
1448 | private: |
1449 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1450 | }; |
1451 | |
1452 | class CommaNode final : public ExpressionNode { |
1453 | public: |
1454 | CommaNode(const JSTokenLocation&, ExpressionNode*); |
1455 | |
1456 | void setNext(CommaNode* next) { m_next = next; } |
1457 | CommaNode* next() { return m_next; } |
1458 | |
1459 | private: |
1460 | bool isCommaNode() const override { return true; } |
1461 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1462 | |
1463 | ExpressionNode* m_expr; |
1464 | CommaNode* m_next { nullptr }; |
1465 | }; |
1466 | |
1467 | class SourceElements final : public ParserArenaFreeable { |
1468 | public: |
1469 | SourceElements(); |
1470 | |
1471 | void append(StatementNode*); |
1472 | |
1473 | StatementNode* singleStatement() const; |
1474 | StatementNode* lastStatement() const; |
1475 | |
1476 | bool hasCompletionValue() const; |
1477 | bool hasEarlyBreakOrContinue() const; |
1478 | |
1479 | void emitBytecode(BytecodeGenerator&, RegisterID* destination); |
1480 | void analyzeModule(ModuleAnalyzer&); |
1481 | |
1482 | private: |
1483 | StatementNode* m_head { nullptr }; |
1484 | StatementNode* m_tail { nullptr }; |
1485 | }; |
1486 | |
1487 | class BlockNode final : public StatementNode, public VariableEnvironmentNode { |
1488 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(BlockNode); |
1489 | public: |
1490 | BlockNode(const JSTokenLocation&, SourceElements*, VariableEnvironment&, FunctionStack&&); |
1491 | |
1492 | StatementNode* singleStatement() const; |
1493 | StatementNode* lastStatement() const; |
1494 | |
1495 | private: |
1496 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1497 | |
1498 | bool hasCompletionValue() const override; |
1499 | bool hasEarlyBreakOrContinue() const override; |
1500 | |
1501 | bool isBlock() const override { return true; } |
1502 | |
1503 | SourceElements* m_statements; |
1504 | }; |
1505 | |
1506 | class EmptyStatementNode final : public StatementNode { |
1507 | public: |
1508 | EmptyStatementNode(const JSTokenLocation&); |
1509 | |
1510 | private: |
1511 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1512 | |
1513 | bool hasCompletionValue() const override { return false; } |
1514 | bool isEmptyStatement() const override { return true; } |
1515 | }; |
1516 | |
1517 | class DebuggerStatementNode final : public StatementNode { |
1518 | public: |
1519 | DebuggerStatementNode(const JSTokenLocation&); |
1520 | |
1521 | bool hasCompletionValue() const override { return false; } |
1522 | bool isDebuggerStatement() const override { return true; } |
1523 | |
1524 | private: |
1525 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1526 | }; |
1527 | |
1528 | class ExprStatementNode final : public StatementNode { |
1529 | public: |
1530 | ExprStatementNode(const JSTokenLocation&, ExpressionNode*); |
1531 | |
1532 | ExpressionNode* expr() const { return m_expr; } |
1533 | |
1534 | private: |
1535 | bool isExprStatement() const override { return true; } |
1536 | |
1537 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1538 | |
1539 | ExpressionNode* m_expr; |
1540 | }; |
1541 | |
1542 | class DeclarationStatement final : public StatementNode { |
1543 | public: |
1544 | DeclarationStatement(const JSTokenLocation&, ExpressionNode*); |
1545 | private: |
1546 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1547 | |
1548 | bool hasCompletionValue() const override { return false; } |
1549 | |
1550 | ExpressionNode* m_expr; |
1551 | }; |
1552 | |
1553 | class EmptyVarExpression final : public ExpressionNode { |
1554 | public: |
1555 | EmptyVarExpression(const JSTokenLocation&, const Identifier&); |
1556 | |
1557 | private: |
1558 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1559 | |
1560 | const Identifier& m_ident; |
1561 | }; |
1562 | |
1563 | class EmptyLetExpression final : public ExpressionNode { |
1564 | public: |
1565 | EmptyLetExpression(const JSTokenLocation&, const Identifier&); |
1566 | |
1567 | private: |
1568 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1569 | |
1570 | const Identifier& m_ident; |
1571 | }; |
1572 | |
1573 | class IfElseNode final : public StatementNode { |
1574 | public: |
1575 | IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock); |
1576 | |
1577 | private: |
1578 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1579 | bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock, |
1580 | Label*& trueTarget, FallThroughMode&); |
1581 | |
1582 | ExpressionNode* m_condition; |
1583 | StatementNode* m_ifBlock; |
1584 | StatementNode* m_elseBlock; |
1585 | }; |
1586 | |
1587 | class DoWhileNode final : public StatementNode { |
1588 | public: |
1589 | DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*); |
1590 | |
1591 | private: |
1592 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1593 | |
1594 | StatementNode* m_statement; |
1595 | ExpressionNode* m_expr; |
1596 | }; |
1597 | |
1598 | class WhileNode final : public StatementNode { |
1599 | public: |
1600 | WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*); |
1601 | |
1602 | private: |
1603 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1604 | |
1605 | ExpressionNode* m_expr; |
1606 | StatementNode* m_statement; |
1607 | }; |
1608 | |
1609 | class ForNode final : public StatementNode, public VariableEnvironmentNode { |
1610 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ForNode); |
1611 | public: |
1612 | ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*, VariableEnvironment&); |
1613 | |
1614 | private: |
1615 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1616 | |
1617 | ExpressionNode* m_expr1; |
1618 | ExpressionNode* m_expr2; |
1619 | ExpressionNode* m_expr3; |
1620 | StatementNode* m_statement; |
1621 | }; |
1622 | |
1623 | class DestructuringPatternNode; |
1624 | |
1625 | class EnumerationNode : public StatementNode, public ThrowableExpressionData, public VariableEnvironmentNode { |
1626 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(EnumerationNode); |
1627 | public: |
1628 | EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&); |
1629 | |
1630 | ExpressionNode* lexpr() const { return m_lexpr; } |
1631 | ExpressionNode* expr() const { return m_expr; } |
1632 | |
1633 | protected: |
1634 | ExpressionNode* m_lexpr; |
1635 | ExpressionNode* m_expr; |
1636 | StatementNode* m_statement; |
1637 | }; |
1638 | |
1639 | class ForInNode final : public EnumerationNode { |
1640 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ForInNode); |
1641 | public: |
1642 | ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&); |
1643 | |
1644 | private: |
1645 | RegisterID* tryGetBoundLocal(BytecodeGenerator&); |
1646 | void (BytecodeGenerator&, RegisterID* propertyName); |
1647 | |
1648 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1649 | }; |
1650 | |
1651 | class ForOfNode final : public EnumerationNode { |
1652 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ForOfNode); |
1653 | public: |
1654 | ForOfNode(bool, const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&); |
1655 | bool isForOfNode() const override { return true; } |
1656 | bool isForAwait() const { return m_isForAwait; } |
1657 | |
1658 | private: |
1659 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1660 | |
1661 | const bool m_isForAwait; |
1662 | }; |
1663 | |
1664 | class ContinueNode final : public StatementNode, public ThrowableExpressionData { |
1665 | public: |
1666 | ContinueNode(const JSTokenLocation&, const Identifier&); |
1667 | Label* trivialTarget(BytecodeGenerator&); |
1668 | |
1669 | private: |
1670 | bool hasCompletionValue() const override { return false; } |
1671 | bool isContinue() const override { return true; } |
1672 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1673 | |
1674 | const Identifier& m_ident; |
1675 | }; |
1676 | |
1677 | class BreakNode final : public StatementNode, public ThrowableExpressionData { |
1678 | public: |
1679 | BreakNode(const JSTokenLocation&, const Identifier&); |
1680 | Label* trivialTarget(BytecodeGenerator&); |
1681 | |
1682 | private: |
1683 | bool hasCompletionValue() const override { return false; } |
1684 | bool isBreak() const override { return true; } |
1685 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1686 | |
1687 | const Identifier& m_ident; |
1688 | }; |
1689 | |
1690 | class ReturnNode final : public StatementNode, public ThrowableExpressionData { |
1691 | public: |
1692 | ReturnNode(const JSTokenLocation&, ExpressionNode* value); |
1693 | |
1694 | ExpressionNode* value() { return m_value; } |
1695 | |
1696 | private: |
1697 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1698 | |
1699 | bool isReturnNode() const override { return true; } |
1700 | |
1701 | ExpressionNode* m_value; |
1702 | }; |
1703 | |
1704 | class WithNode final : public StatementNode { |
1705 | public: |
1706 | WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, const JSTextPosition& divot, uint32_t expressionLength); |
1707 | |
1708 | private: |
1709 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1710 | |
1711 | ExpressionNode* m_expr; |
1712 | StatementNode* m_statement; |
1713 | JSTextPosition m_divot; |
1714 | uint32_t m_expressionLength; |
1715 | }; |
1716 | |
1717 | class LabelNode final : public StatementNode, public ThrowableExpressionData { |
1718 | public: |
1719 | LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*); |
1720 | |
1721 | bool isLabel() const override { return true; } |
1722 | |
1723 | private: |
1724 | bool hasCompletionValue() const override { return m_statement->hasCompletionValue(); } |
1725 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1726 | |
1727 | const Identifier& m_name; |
1728 | StatementNode* m_statement; |
1729 | }; |
1730 | |
1731 | class ThrowNode final : public StatementNode, public ThrowableExpressionData { |
1732 | public: |
1733 | ThrowNode(const JSTokenLocation&, ExpressionNode*); |
1734 | |
1735 | private: |
1736 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1737 | |
1738 | ExpressionNode* m_expr; |
1739 | }; |
1740 | |
1741 | class TryNode final : public StatementNode, public VariableEnvironmentNode { |
1742 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(TryNode); |
1743 | public: |
1744 | TryNode(const JSTokenLocation&, StatementNode* tryBlock, DestructuringPatternNode* catchPattern, StatementNode* catchBlock, VariableEnvironment& catchEnvironment, StatementNode* finallyBlock); |
1745 | |
1746 | private: |
1747 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1748 | |
1749 | StatementNode* m_tryBlock; |
1750 | DestructuringPatternNode* m_catchPattern; |
1751 | StatementNode* m_catchBlock; |
1752 | StatementNode* m_finallyBlock; |
1753 | }; |
1754 | |
1755 | class ScopeNode : public StatementNode, public ParserArenaRoot, public VariableEnvironmentNode { |
1756 | public: |
1757 | // ScopeNode is never directly instantiate. The life-cycle of its derived classes are |
1758 | // managed using std::unique_ptr. Hence, though ScopeNode extends VariableEnvironmentNode, |
1759 | // which in turn extends ParserArenaDeletable, we don't want to use ParserArenaDeletable's |
1760 | // new for allocation. |
1761 | using ParserArenaRoot::operator new; |
1762 | |
1763 | ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext); |
1764 | ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants); |
1765 | |
1766 | const SourceCode& source() const { return m_source; } |
1767 | const String& sourceURL() const { return m_source.provider()->url(); } |
1768 | intptr_t sourceID() const { return m_source.providerID(); } |
1769 | |
1770 | int startLine() const { return m_startLineNumber; } |
1771 | int startStartOffset() const { return m_startStartOffset; } |
1772 | int startLineStartOffset() const { return m_startLineStartOffset; } |
1773 | |
1774 | void setFeatures(CodeFeatures features) { m_features = features; } |
1775 | CodeFeatures features() { return m_features; } |
1776 | InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures() { return m_innerArrowFunctionCodeFeatures; } |
1777 | bool doAnyInnerArrowFunctionsUseAnyFeature() { return m_innerArrowFunctionCodeFeatures != NoInnerArrowFunctionFeatures; } |
1778 | bool doAnyInnerArrowFunctionsUseArguments() { return m_innerArrowFunctionCodeFeatures & ArgumentsInnerArrowFunctionFeature; } |
1779 | bool doAnyInnerArrowFunctionsUseSuperCall() { return m_innerArrowFunctionCodeFeatures & SuperCallInnerArrowFunctionFeature; } |
1780 | bool doAnyInnerArrowFunctionsUseSuperProperty() { return m_innerArrowFunctionCodeFeatures & SuperPropertyInnerArrowFunctionFeature; } |
1781 | bool doAnyInnerArrowFunctionsUseEval() { return m_innerArrowFunctionCodeFeatures & EvalInnerArrowFunctionFeature; } |
1782 | bool doAnyInnerArrowFunctionsUseThis() { return m_innerArrowFunctionCodeFeatures & ThisInnerArrowFunctionFeature; } |
1783 | bool doAnyInnerArrowFunctionsUseNewTarget() { return m_innerArrowFunctionCodeFeatures & NewTargetInnerArrowFunctionFeature; } |
1784 | |
1785 | bool usesEval() const { return m_features & EvalFeature; } |
1786 | bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); } |
1787 | bool usesArrowFunction() const { return m_features & ArrowFunctionFeature; } |
1788 | bool isStrictMode() const { return m_features & StrictModeFeature; } |
1789 | void setUsesArguments() { m_features |= ArgumentsFeature; } |
1790 | bool usesThis() const { return m_features & ThisFeature; } |
1791 | bool usesSuperCall() const { return m_features & SuperCallFeature; } |
1792 | bool usesSuperProperty() const { return m_features & SuperPropertyFeature; } |
1793 | bool usesNewTarget() const { return m_features & NewTargetFeature; } |
1794 | bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature)); } |
1795 | bool hasCapturedVariables() const { return m_varDeclarations.hasCapturedVariables(); } |
1796 | bool captures(UniquedStringImpl* uid) { return m_varDeclarations.captures(uid); } |
1797 | bool captures(const Identifier& ident) { return captures(ident.impl()); } |
1798 | bool hasSloppyModeHoistedFunction(UniquedStringImpl* uid) const { return m_sloppyModeHoistedFunctions.contains(uid); } |
1799 | |
1800 | bool needsNewTargetRegisterForThisScope() const |
1801 | { |
1802 | return usesSuperCall() || usesNewTarget(); |
1803 | } |
1804 | |
1805 | VariableEnvironment& varDeclarations() { return m_varDeclarations; } |
1806 | |
1807 | int neededConstants() |
1808 | { |
1809 | // We may need 2 more constants than the count given by the parser, |
1810 | // because of the various uses of jsUndefined() and jsNull(). |
1811 | return m_numConstants + 2; |
1812 | } |
1813 | |
1814 | StatementNode* singleStatement() const; |
1815 | |
1816 | bool hasCompletionValue() const override; |
1817 | bool hasEarlyBreakOrContinue() const override; |
1818 | |
1819 | void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination); |
1820 | |
1821 | void analyzeModule(ModuleAnalyzer&); |
1822 | |
1823 | protected: |
1824 | int m_startLineNumber; |
1825 | unsigned m_startStartOffset; |
1826 | unsigned m_startLineStartOffset; |
1827 | |
1828 | private: |
1829 | CodeFeatures m_features; |
1830 | InnerArrowFunctionCodeFeatures m_innerArrowFunctionCodeFeatures; |
1831 | SourceCode m_source; |
1832 | VariableEnvironment m_varDeclarations; |
1833 | UniquedStringImplPtrSet m_sloppyModeHoistedFunctions; |
1834 | int m_numConstants; |
1835 | SourceElements* m_statements; |
1836 | }; |
1837 | |
1838 | class ProgramNode final : public ScopeNode { |
1839 | public: |
1840 | ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&); |
1841 | |
1842 | unsigned startColumn() const { return m_startColumn; } |
1843 | unsigned endColumn() const { return m_endColumn; } |
1844 | |
1845 | static constexpr bool scopeIsFunction = false; |
1846 | |
1847 | private: |
1848 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1849 | unsigned m_startColumn; |
1850 | unsigned m_endColumn; |
1851 | }; |
1852 | |
1853 | class EvalNode final : public ScopeNode { |
1854 | public: |
1855 | EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&); |
1856 | |
1857 | ALWAYS_INLINE unsigned startColumn() const { return 0; } |
1858 | unsigned endColumn() const { return m_endColumn; } |
1859 | |
1860 | static constexpr bool scopeIsFunction = false; |
1861 | |
1862 | private: |
1863 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1864 | |
1865 | unsigned m_endColumn; |
1866 | }; |
1867 | |
1868 | class ModuleProgramNode final : public ScopeNode { |
1869 | public: |
1870 | ModuleProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&); |
1871 | |
1872 | unsigned startColumn() const { return m_startColumn; } |
1873 | unsigned endColumn() const { return m_endColumn; } |
1874 | |
1875 | static constexpr bool scopeIsFunction = false; |
1876 | |
1877 | ModuleScopeData& moduleScopeData() |
1878 | { |
1879 | return m_moduleScopeData; |
1880 | } |
1881 | |
1882 | private: |
1883 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1884 | unsigned m_startColumn; |
1885 | unsigned m_endColumn; |
1886 | Ref<ModuleScopeData> m_moduleScopeData; |
1887 | }; |
1888 | |
1889 | class ModuleNameNode final : public Node { |
1890 | public: |
1891 | ModuleNameNode(const JSTokenLocation&, const Identifier& moduleName); |
1892 | |
1893 | const Identifier& moduleName() { return m_moduleName; } |
1894 | |
1895 | private: |
1896 | const Identifier& m_moduleName; |
1897 | }; |
1898 | |
1899 | class ImportSpecifierNode final : public Node { |
1900 | public: |
1901 | ImportSpecifierNode(const JSTokenLocation&, const Identifier& importedName, const Identifier& localName); |
1902 | |
1903 | const Identifier& importedName() { return m_importedName; } |
1904 | const Identifier& localName() { return m_localName; } |
1905 | |
1906 | private: |
1907 | const Identifier& m_importedName; |
1908 | const Identifier& m_localName; |
1909 | }; |
1910 | |
1911 | class ImportSpecifierListNode final : public ParserArenaDeletable { |
1912 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ImportSpecifierListNode); |
1913 | public: |
1914 | typedef Vector<ImportSpecifierNode*, 3> Specifiers; |
1915 | |
1916 | const Specifiers& specifiers() const { return m_specifiers; } |
1917 | void append(ImportSpecifierNode* specifier) |
1918 | { |
1919 | m_specifiers.append(specifier); |
1920 | } |
1921 | |
1922 | private: |
1923 | Specifiers m_specifiers; |
1924 | }; |
1925 | |
1926 | class ModuleDeclarationNode : public StatementNode { |
1927 | public: |
1928 | virtual void analyzeModule(ModuleAnalyzer&) = 0; |
1929 | bool hasCompletionValue() const override { return false; } |
1930 | bool isModuleDeclarationNode() const override { return true; } |
1931 | |
1932 | protected: |
1933 | ModuleDeclarationNode(const JSTokenLocation&); |
1934 | }; |
1935 | |
1936 | class ImportDeclarationNode final : public ModuleDeclarationNode { |
1937 | public: |
1938 | ImportDeclarationNode(const JSTokenLocation&, ImportSpecifierListNode*, ModuleNameNode*); |
1939 | |
1940 | ImportSpecifierListNode* specifierList() const { return m_specifierList; } |
1941 | ModuleNameNode* moduleName() const { return m_moduleName; } |
1942 | |
1943 | private: |
1944 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1945 | void analyzeModule(ModuleAnalyzer&) override; |
1946 | |
1947 | ImportSpecifierListNode* m_specifierList; |
1948 | ModuleNameNode* m_moduleName; |
1949 | }; |
1950 | |
1951 | class ExportAllDeclarationNode final : public ModuleDeclarationNode { |
1952 | public: |
1953 | ExportAllDeclarationNode(const JSTokenLocation&, ModuleNameNode*); |
1954 | |
1955 | ModuleNameNode* moduleName() const { return m_moduleName; } |
1956 | |
1957 | private: |
1958 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1959 | void analyzeModule(ModuleAnalyzer&) override; |
1960 | |
1961 | ModuleNameNode* m_moduleName; |
1962 | }; |
1963 | |
1964 | class ExportDefaultDeclarationNode final : public ModuleDeclarationNode { |
1965 | public: |
1966 | ExportDefaultDeclarationNode(const JSTokenLocation&, StatementNode*, const Identifier& localName); |
1967 | |
1968 | const StatementNode& declaration() const { return *m_declaration; } |
1969 | const Identifier& localName() const { return m_localName; } |
1970 | |
1971 | private: |
1972 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1973 | void analyzeModule(ModuleAnalyzer&) override; |
1974 | StatementNode* m_declaration; |
1975 | const Identifier& m_localName; |
1976 | }; |
1977 | |
1978 | class ExportLocalDeclarationNode final : public ModuleDeclarationNode { |
1979 | public: |
1980 | ExportLocalDeclarationNode(const JSTokenLocation&, StatementNode*); |
1981 | |
1982 | const StatementNode& declaration() const { return *m_declaration; } |
1983 | |
1984 | private: |
1985 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
1986 | void analyzeModule(ModuleAnalyzer&) override; |
1987 | StatementNode* m_declaration; |
1988 | }; |
1989 | |
1990 | class ExportSpecifierNode final : public Node { |
1991 | public: |
1992 | ExportSpecifierNode(const JSTokenLocation&, const Identifier& localName, const Identifier& exportedName); |
1993 | |
1994 | const Identifier& exportedName() { return m_exportedName; } |
1995 | const Identifier& localName() { return m_localName; } |
1996 | |
1997 | private: |
1998 | const Identifier& m_localName; |
1999 | const Identifier& m_exportedName; |
2000 | }; |
2001 | |
2002 | class ExportSpecifierListNode final : public ParserArenaDeletable { |
2003 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ExportSpecifierListNode); |
2004 | public: |
2005 | typedef Vector<ExportSpecifierNode*, 3> Specifiers; |
2006 | |
2007 | const Specifiers& specifiers() const { return m_specifiers; } |
2008 | void append(ExportSpecifierNode* specifier) |
2009 | { |
2010 | m_specifiers.append(specifier); |
2011 | } |
2012 | |
2013 | private: |
2014 | Specifiers m_specifiers; |
2015 | }; |
2016 | |
2017 | class ExportNamedDeclarationNode final : public ModuleDeclarationNode { |
2018 | public: |
2019 | ExportNamedDeclarationNode(const JSTokenLocation&, ExportSpecifierListNode*, ModuleNameNode*); |
2020 | |
2021 | ExportSpecifierListNode* specifierList() const { return m_specifierList; } |
2022 | ModuleNameNode* moduleName() const { return m_moduleName; } |
2023 | |
2024 | private: |
2025 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2026 | void analyzeModule(ModuleAnalyzer&) override; |
2027 | ExportSpecifierListNode* m_specifierList; |
2028 | ModuleNameNode* m_moduleName { nullptr }; |
2029 | }; |
2030 | |
2031 | class FunctionMetadataNode final : public ParserArenaDeletable, public Node { |
2032 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(FunctionMetadataNode); |
2033 | public: |
2034 | FunctionMetadataNode( |
2035 | ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, |
2036 | unsigned startColumn, unsigned endColumn, int functionKeywordStart, |
2037 | int functionNameStart, int , bool isInStrictContext, |
2038 | ConstructorKind, SuperBinding, unsigned parameterCount, |
2039 | SourceParseMode, bool isArrowFunctionBodyExpression); |
2040 | FunctionMetadataNode( |
2041 | const JSTokenLocation& start, const JSTokenLocation& end, |
2042 | unsigned startColumn, unsigned endColumn, int functionKeywordStart, |
2043 | int functionNameStart, int , bool isInStrictContext, |
2044 | ConstructorKind, SuperBinding, unsigned parameterCount, |
2045 | SourceParseMode, bool isArrowFunctionBodyExpression); |
2046 | |
2047 | void dump(PrintStream&) const; |
2048 | |
2049 | void finishParsing(const SourceCode&, const Identifier&, FunctionMode); |
2050 | |
2051 | void overrideName(const Identifier& ident) { m_ident = ident; } |
2052 | const Identifier& ident() { return m_ident; } |
2053 | void setEcmaName(const Identifier& ecmaName) { m_ecmaName = ecmaName; } |
2054 | const Identifier& ecmaName() { return m_ident.isEmpty() ? m_ecmaName : m_ident; } |
2055 | |
2056 | FunctionMode functionMode() { return m_functionMode; } |
2057 | |
2058 | int functionNameStart() const { return m_functionNameStart; } |
2059 | int functionKeywordStart() const { return m_functionKeywordStart; } |
2060 | int () const { return m_parametersStart; } |
2061 | unsigned startColumn() const { return m_startColumn; } |
2062 | unsigned endColumn() const { return m_endColumn; } |
2063 | unsigned parameterCount() const { return m_parameterCount; } |
2064 | SourceParseMode parseMode() const { return m_parseMode; } |
2065 | |
2066 | void setEndPosition(JSTextPosition); |
2067 | |
2068 | const SourceCode& source() const { return m_source; } |
2069 | const SourceCode& classSource() const { return m_classSource; } |
2070 | void setClassSource(const SourceCode& source) { m_classSource = source; } |
2071 | |
2072 | int startStartOffset() const { return m_startStartOffset; } |
2073 | bool isInStrictContext() const { return m_isInStrictContext; } |
2074 | SuperBinding superBinding() { return static_cast<SuperBinding>(m_superBinding); } |
2075 | ConstructorKind constructorKind() { return static_cast<ConstructorKind>(m_constructorKind); } |
2076 | bool isArrowFunctionBodyExpression() const { return m_isArrowFunctionBodyExpression; } |
2077 | |
2078 | void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset) |
2079 | { |
2080 | m_lastLine = lastLine; |
2081 | m_position = JSTextPosition(firstLine, startOffset, lineStartOffset); |
2082 | ASSERT(m_position.offset >= m_position.lineStartOffset); |
2083 | } |
2084 | unsigned lastLine() const { return m_lastLine; } |
2085 | |
2086 | bool operator==(const FunctionMetadataNode&) const; |
2087 | bool operator!=(const FunctionMetadataNode& other) const |
2088 | { |
2089 | return !(*this == other); |
2090 | } |
2091 | |
2092 | public: |
2093 | unsigned m_isInStrictContext : 1; |
2094 | unsigned m_superBinding : 1; |
2095 | unsigned m_constructorKind : 2; |
2096 | unsigned m_isArrowFunctionBodyExpression : 1; |
2097 | SourceParseMode m_parseMode; |
2098 | FunctionMode m_functionMode; |
2099 | Identifier m_ident; |
2100 | Identifier m_ecmaName; |
2101 | unsigned m_startColumn; |
2102 | unsigned m_endColumn; |
2103 | int m_functionKeywordStart; |
2104 | int m_functionNameStart; |
2105 | int ; |
2106 | SourceCode m_source; |
2107 | SourceCode m_classSource; |
2108 | int m_startStartOffset; |
2109 | unsigned m_parameterCount; |
2110 | int m_lastLine; |
2111 | }; |
2112 | |
2113 | class FunctionNode final : public ScopeNode { |
2114 | public: |
2115 | FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&); |
2116 | |
2117 | FunctionParameters* parameters() const { return m_parameters; } |
2118 | |
2119 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2120 | |
2121 | bool isFunctionNode() const override { return true; } |
2122 | |
2123 | void finishParsing(const Identifier&, FunctionMode); |
2124 | |
2125 | const Identifier& ident() { return m_ident; } |
2126 | |
2127 | FunctionMode functionMode() const { return m_functionMode; } |
2128 | |
2129 | unsigned startColumn() const { return m_startColumn; } |
2130 | unsigned endColumn() const { return m_endColumn; } |
2131 | |
2132 | static constexpr bool scopeIsFunction = true; |
2133 | |
2134 | private: |
2135 | Identifier m_ident; |
2136 | FunctionMode m_functionMode; |
2137 | FunctionParameters* m_parameters; |
2138 | unsigned m_startColumn; |
2139 | unsigned m_endColumn; |
2140 | }; |
2141 | |
2142 | class BaseFuncExprNode : public ExpressionNode { |
2143 | public: |
2144 | FunctionMetadataNode* metadata() { return m_metadata; } |
2145 | |
2146 | bool isBaseFuncExprNode() const override { return true; } |
2147 | |
2148 | protected: |
2149 | BaseFuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&, FunctionMode); |
2150 | |
2151 | FunctionMetadataNode* m_metadata; |
2152 | }; |
2153 | |
2154 | |
2155 | class FuncExprNode : public BaseFuncExprNode { |
2156 | public: |
2157 | FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&); |
2158 | |
2159 | protected: |
2160 | FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&, FunctionMode); |
2161 | |
2162 | private: |
2163 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2164 | |
2165 | bool isFuncExprNode() const override { return true; } |
2166 | }; |
2167 | |
2168 | class ArrowFuncExprNode final : public BaseFuncExprNode { |
2169 | public: |
2170 | ArrowFuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&); |
2171 | |
2172 | private: |
2173 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2174 | |
2175 | bool isArrowFuncExprNode() const override { return true; } |
2176 | }; |
2177 | |
2178 | class MethodDefinitionNode final : public FuncExprNode { |
2179 | public: |
2180 | MethodDefinitionNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&); |
2181 | |
2182 | private: |
2183 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2184 | }; |
2185 | |
2186 | class YieldExprNode final : public ExpressionNode, public ThrowableExpressionData { |
2187 | public: |
2188 | YieldExprNode(const JSTokenLocation&, ExpressionNode* argument, bool delegate); |
2189 | |
2190 | ExpressionNode* argument() const { return m_argument; } |
2191 | bool delegate() const { return m_delegate; } |
2192 | |
2193 | private: |
2194 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2195 | |
2196 | ExpressionNode* m_argument; |
2197 | bool m_delegate; |
2198 | }; |
2199 | |
2200 | class AwaitExprNode final : public ExpressionNode, public ThrowableExpressionData { |
2201 | public: |
2202 | AwaitExprNode(const JSTokenLocation&, ExpressionNode* argument); |
2203 | |
2204 | ExpressionNode* argument() const { return m_argument; } |
2205 | |
2206 | private: |
2207 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2208 | |
2209 | ExpressionNode* m_argument; |
2210 | }; |
2211 | |
2212 | class ClassExprNode final : public ExpressionNode, public VariableEnvironmentNode { |
2213 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ClassExprNode); |
2214 | public: |
2215 | ClassExprNode(const JSTokenLocation&, const Identifier&, const SourceCode& classSource, |
2216 | VariableEnvironment& classEnvironment, ExpressionNode* constructorExpresssion, |
2217 | ExpressionNode* parentClass, PropertyListNode* classElements); |
2218 | |
2219 | const Identifier& name() { return m_name; } |
2220 | const Identifier& ecmaName() { return m_ecmaName ? *m_ecmaName : m_name; } |
2221 | void setEcmaName(const Identifier& name) { m_ecmaName = m_name.isNull() ? &name : &m_name; } |
2222 | |
2223 | bool hasStaticProperty(const Identifier& propName) { return m_classElements ? m_classElements->hasStaticallyNamedProperty(propName) : false; } |
2224 | |
2225 | private: |
2226 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2227 | |
2228 | bool isClassExprNode() const override { return true; } |
2229 | |
2230 | SourceCode m_classSource; |
2231 | const Identifier& m_name; |
2232 | const Identifier* m_ecmaName; |
2233 | ExpressionNode* m_constructorExpression; |
2234 | ExpressionNode* m_classHeritage; |
2235 | PropertyListNode* m_classElements; |
2236 | }; |
2237 | |
2238 | class DestructuringPatternNode : public ParserArenaFreeable { |
2239 | public: |
2240 | virtual ~DestructuringPatternNode() { } |
2241 | virtual void collectBoundIdentifiers(Vector<Identifier>&) const = 0; |
2242 | virtual void bindValue(BytecodeGenerator&, RegisterID* source) const = 0; |
2243 | virtual void toString(StringBuilder&) const = 0; |
2244 | |
2245 | virtual bool isBindingNode() const { return false; } |
2246 | virtual bool isAssignmentElementNode() const { return false; } |
2247 | virtual bool isRestParameter() const { return false; } |
2248 | virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; } |
2249 | |
2250 | protected: |
2251 | DestructuringPatternNode(); |
2252 | }; |
2253 | |
2254 | class ArrayPatternNode final : public DestructuringPatternNode, public ParserArenaDeletable, public ThrowableExpressionData { |
2255 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ArrayPatternNode); |
2256 | public: |
2257 | ArrayPatternNode(); |
2258 | enum class BindingType : uint8_t { |
2259 | Elision, |
2260 | Element, |
2261 | RestElement |
2262 | }; |
2263 | |
2264 | void appendIndex(BindingType bindingType, const JSTokenLocation&, DestructuringPatternNode* node, ExpressionNode* defaultValue) |
2265 | { |
2266 | m_targetPatterns.append({ bindingType, node, defaultValue }); |
2267 | } |
2268 | |
2269 | private: |
2270 | struct Entry { |
2271 | BindingType bindingType; |
2272 | DestructuringPatternNode* pattern; |
2273 | ExpressionNode* defaultValue; |
2274 | }; |
2275 | void collectBoundIdentifiers(Vector<Identifier>&) const override; |
2276 | void bindValue(BytecodeGenerator&, RegisterID*) const override; |
2277 | RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID* dst, ExpressionNode*) override; |
2278 | void toString(StringBuilder&) const override; |
2279 | |
2280 | Vector<Entry> m_targetPatterns; |
2281 | }; |
2282 | |
2283 | class ObjectPatternNode final : public DestructuringPatternNode, public ParserArenaDeletable, public ThrowableExpressionData { |
2284 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ObjectPatternNode); |
2285 | public: |
2286 | ObjectPatternNode(); |
2287 | enum class BindingType : uint8_t { |
2288 | Element, |
2289 | RestElement |
2290 | }; |
2291 | void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DestructuringPatternNode* pattern, ExpressionNode* defaultValue, BindingType bindingType) |
2292 | { |
2293 | m_targetPatterns.append(Entry{ identifier, nullptr, wasString, pattern, defaultValue, bindingType }); |
2294 | } |
2295 | |
2296 | void appendEntry(VM& vm, const JSTokenLocation&, ExpressionNode* propertyExpression, DestructuringPatternNode* pattern, ExpressionNode* defaultValue, BindingType bindingType) |
2297 | { |
2298 | m_targetPatterns.append(Entry{ vm.propertyNames->nullIdentifier, propertyExpression, false, pattern, defaultValue, bindingType }); |
2299 | } |
2300 | |
2301 | void setContainsRestElement(bool containsRestElement) |
2302 | { |
2303 | m_containsRestElement = containsRestElement; |
2304 | } |
2305 | |
2306 | void setContainsComputedProperty(bool containsComputedProperty) |
2307 | { |
2308 | m_containsComputedProperty = containsComputedProperty; |
2309 | } |
2310 | |
2311 | private: |
2312 | void collectBoundIdentifiers(Vector<Identifier>&) const override; |
2313 | void bindValue(BytecodeGenerator&, RegisterID*) const override; |
2314 | void toString(StringBuilder&) const override; |
2315 | struct Entry { |
2316 | const Identifier& propertyName; |
2317 | ExpressionNode* propertyExpression; |
2318 | bool wasString; |
2319 | DestructuringPatternNode* pattern; |
2320 | ExpressionNode* defaultValue; |
2321 | BindingType bindingType; |
2322 | }; |
2323 | bool m_containsRestElement { false }; |
2324 | bool m_containsComputedProperty { false }; |
2325 | Vector<Entry> m_targetPatterns; |
2326 | }; |
2327 | |
2328 | class BindingNode final: public DestructuringPatternNode { |
2329 | public: |
2330 | BindingNode(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end, AssignmentContext); |
2331 | const Identifier& boundProperty() const { return m_boundProperty; } |
2332 | |
2333 | const JSTextPosition& divotStart() const { return m_divotStart; } |
2334 | const JSTextPosition& divotEnd() const { return m_divotEnd; } |
2335 | |
2336 | private: |
2337 | void collectBoundIdentifiers(Vector<Identifier>&) const override; |
2338 | void bindValue(BytecodeGenerator&, RegisterID*) const override; |
2339 | void toString(StringBuilder&) const override; |
2340 | |
2341 | bool isBindingNode() const override { return true; } |
2342 | |
2343 | JSTextPosition m_divotStart; |
2344 | JSTextPosition m_divotEnd; |
2345 | const Identifier& m_boundProperty; |
2346 | AssignmentContext m_bindingContext; |
2347 | }; |
2348 | |
2349 | class RestParameterNode final : public DestructuringPatternNode { |
2350 | public: |
2351 | RestParameterNode(DestructuringPatternNode*, unsigned numParametersToSkip); |
2352 | |
2353 | bool isRestParameter() const override { return true; } |
2354 | |
2355 | void emit(BytecodeGenerator&); |
2356 | |
2357 | private: |
2358 | void collectBoundIdentifiers(Vector<Identifier>&) const override; |
2359 | void bindValue(BytecodeGenerator&, RegisterID*) const override; |
2360 | void toString(StringBuilder&) const override; |
2361 | |
2362 | DestructuringPatternNode* m_pattern; |
2363 | unsigned m_numParametersToSkip; |
2364 | }; |
2365 | |
2366 | class AssignmentElementNode final : public DestructuringPatternNode { |
2367 | public: |
2368 | AssignmentElementNode(ExpressionNode* assignmentTarget, const JSTextPosition& start, const JSTextPosition& end); |
2369 | const ExpressionNode* assignmentTarget() { return m_assignmentTarget; } |
2370 | |
2371 | const JSTextPosition& divotStart() const { return m_divotStart; } |
2372 | const JSTextPosition& divotEnd() const { return m_divotEnd; } |
2373 | |
2374 | private: |
2375 | void collectBoundIdentifiers(Vector<Identifier>&) const override; |
2376 | void bindValue(BytecodeGenerator&, RegisterID*) const override; |
2377 | void toString(StringBuilder&) const override; |
2378 | |
2379 | bool isAssignmentElementNode() const override { return true; } |
2380 | |
2381 | JSTextPosition m_divotStart; |
2382 | JSTextPosition m_divotEnd; |
2383 | ExpressionNode* m_assignmentTarget; |
2384 | }; |
2385 | |
2386 | class DestructuringAssignmentNode final : public ExpressionNode { |
2387 | public: |
2388 | DestructuringAssignmentNode(const JSTokenLocation&, DestructuringPatternNode*, ExpressionNode*); |
2389 | DestructuringPatternNode* bindings() { return m_bindings; } |
2390 | |
2391 | private: |
2392 | bool isAssignmentLocation() const override { return true; } |
2393 | bool isDestructuringNode() const override { return true; } |
2394 | RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2395 | |
2396 | DestructuringPatternNode* m_bindings; |
2397 | ExpressionNode* m_initializer; |
2398 | }; |
2399 | |
2400 | class FunctionParameters final : public ParserArenaDeletable { |
2401 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(FunctionParameters); |
2402 | public: |
2403 | FunctionParameters(); |
2404 | ALWAYS_INLINE unsigned size() const { return m_patterns.size(); } |
2405 | ALWAYS_INLINE std::pair<DestructuringPatternNode*, ExpressionNode*> at(unsigned index) { return m_patterns[index]; } |
2406 | ALWAYS_INLINE void append(DestructuringPatternNode* pattern, ExpressionNode* defaultValue) |
2407 | { |
2408 | ASSERT(pattern); |
2409 | |
2410 | // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation |
2411 | // This implements IsSimpleParameterList in the Ecma 2015 spec. |
2412 | // If IsSimpleParameterList is false, we will create a strict-mode like arguments object. |
2413 | // IsSimpleParameterList is false if the argument list contains any default parameter values, |
2414 | // a rest parameter, or any destructuring patterns. |
2415 | // If we do have default parameters, destructuring parameters, or a rest parameter, our parameters will be allocated in a different scope. |
2416 | |
2417 | bool hasDefaultParameterValue = defaultValue; |
2418 | bool isSimpleParameter = !hasDefaultParameterValue && pattern->isBindingNode(); |
2419 | m_isSimpleParameterList &= isSimpleParameter; |
2420 | |
2421 | m_patterns.append(std::make_pair(pattern, defaultValue)); |
2422 | } |
2423 | ALWAYS_INLINE bool isSimpleParameterList() const { return m_isSimpleParameterList; } |
2424 | |
2425 | private: |
2426 | |
2427 | Vector<std::pair<DestructuringPatternNode*, ExpressionNode*>, 3> m_patterns; |
2428 | bool m_isSimpleParameterList { true }; |
2429 | }; |
2430 | |
2431 | class FuncDeclNode final : public StatementNode { |
2432 | public: |
2433 | FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&); |
2434 | |
2435 | bool hasCompletionValue() const override { return false; } |
2436 | bool isFuncDeclNode() const override { return true; } |
2437 | FunctionMetadataNode* metadata() { return m_metadata; } |
2438 | |
2439 | private: |
2440 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2441 | |
2442 | FunctionMetadataNode* m_metadata; |
2443 | }; |
2444 | |
2445 | class ClassDeclNode final : public StatementNode { |
2446 | public: |
2447 | ClassDeclNode(const JSTokenLocation&, ExpressionNode* classExpression); |
2448 | |
2449 | private: |
2450 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2451 | |
2452 | bool hasCompletionValue() const override { return false; } |
2453 | |
2454 | ExpressionNode* m_classDeclaration; |
2455 | }; |
2456 | |
2457 | class CaseClauseNode final : public ParserArenaFreeable { |
2458 | public: |
2459 | CaseClauseNode(ExpressionNode*, SourceElements* = 0); |
2460 | |
2461 | ExpressionNode* expr() const { return m_expr; } |
2462 | |
2463 | void emitBytecode(BytecodeGenerator&, RegisterID* destination); |
2464 | void setStartOffset(int offset) { m_startOffset = offset; } |
2465 | |
2466 | private: |
2467 | ExpressionNode* m_expr; |
2468 | SourceElements* m_statements; |
2469 | int m_startOffset; |
2470 | }; |
2471 | |
2472 | class ClauseListNode final : public ParserArenaFreeable { |
2473 | public: |
2474 | ClauseListNode(CaseClauseNode*); |
2475 | ClauseListNode(ClauseListNode*, CaseClauseNode*); |
2476 | |
2477 | CaseClauseNode* getClause() const { return m_clause; } |
2478 | ClauseListNode* getNext() const { return m_next; } |
2479 | |
2480 | private: |
2481 | CaseClauseNode* m_clause; |
2482 | ClauseListNode* m_next { nullptr }; |
2483 | }; |
2484 | |
2485 | class CaseBlockNode final : public ParserArenaFreeable { |
2486 | public: |
2487 | CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2); |
2488 | |
2489 | void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination); |
2490 | |
2491 | private: |
2492 | SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num); |
2493 | static constexpr size_t s_tableSwitchMinimum = 3; |
2494 | ClauseListNode* m_list1; |
2495 | CaseClauseNode* m_defaultClause; |
2496 | ClauseListNode* m_list2; |
2497 | }; |
2498 | |
2499 | class SwitchNode final : public StatementNode, public VariableEnvironmentNode { |
2500 | JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(SwitchNode); |
2501 | public: |
2502 | SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*, VariableEnvironment&, FunctionStack&&); |
2503 | |
2504 | private: |
2505 | void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override; |
2506 | |
2507 | ExpressionNode* m_expr; |
2508 | CaseBlockNode* m_block; |
2509 | }; |
2510 | |
2511 | struct ElementList { |
2512 | ElementNode* head; |
2513 | ElementNode* tail; |
2514 | }; |
2515 | |
2516 | struct PropertyList { |
2517 | PropertyListNode* head; |
2518 | PropertyListNode* tail; |
2519 | }; |
2520 | |
2521 | struct ArgumentList { |
2522 | ArgumentListNode* head; |
2523 | ArgumentListNode* tail; |
2524 | }; |
2525 | |
2526 | struct ClauseList { |
2527 | ClauseListNode* head; |
2528 | ClauseListNode* tail; |
2529 | }; |
2530 | |
2531 | } // namespace JSC |
2532 | |