source: webkit/trunk/Source/JavaScriptCore/parser/Nodes.h

Last change on this file was 292193, checked in by Chris Dumez, 3 years ago

Adopt Identifier::fromString(ASCIILiteral) more broadly
https://bugs.webkit.org/show_bug.cgi?id=238574

Reviewed by Darin Adler.

Adopt Identifier::fromString(ASCIILiteral) more broadly, now that it is very efficient.

Source/JavaScriptCore:

  • API/JSBase.cpp:

(JSGetMemoryUsageStatistics):

  • Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Combined.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-Builtin.Promise-Separate.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Combined.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-Builtin.prototype-Separate.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Combined.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-BuiltinConstructor-Separate.js-result:
  • Scripts/tests/builtins/expected/JavaScriptCore-InternalClashingNames-Combined.js-result:
  • Scripts/tests/builtins/expected/WebCore-AnotherGuardedInternalBuiltin-Separate.js-result:
  • Scripts/tests/builtins/expected/WebCore-ArbitraryConditionalGuard-Separate.js-result:
  • Scripts/tests/builtins/expected/WebCore-GuardedBuiltin-Separate.js-result:
  • Scripts/tests/builtins/expected/WebCore-GuardedInternalBuiltin-Separate.js-result:
  • Scripts/tests/builtins/expected/WebCore-UnguardedBuiltin-Separate.js-result:
  • Scripts/tests/builtins/expected/WebCore-xmlCasingTest-Separate.js-result:
  • Scripts/wkbuiltins/builtins_model.py:

(BuiltinFunction.fromString):

  • bytecompiler/BytecodeGenerator.cpp:

(JSC::BytecodeGenerator::emitThrowReferenceError):
(JSC::BytecodeGenerator::emitThrowTypeError):
(JSC::BytecodeGenerator::emitRequireObjectCoercible):

  • bytecompiler/BytecodeGenerator.h:
  • bytecompiler/NodesCodegen.cpp:

(JSC::ThrowableExpressionData::emitThrowReferenceError):

  • inspector/JSInjectedScriptHostPrototype.cpp:

(Inspector::JSInjectedScriptHostPrototype::finishCreation):

  • inspector/JSJavaScriptCallFramePrototype.cpp:

(Inspector::JSJavaScriptCallFramePrototype::finishCreation):

  • jsc.cpp:

(JSC_DEFINE_CUSTOM_SETTER):
(JSCMemoryFootprint::finishCreation):
(JSCMemoryFootprint::addProperty):
(JSC_DEFINE_HOST_FUNCTION):

  • parser/Nodes.h:
  • runtime/ArrayPrototype.cpp:

(JSC::ArrayPrototype::finishCreation):

  • runtime/ConsoleObject.cpp:

(JSC::ConsoleObject::finishCreation):

  • runtime/Identifier.cpp:

(JSC::Identifier::add): Deleted.

  • runtime/Identifier.h:
  • runtime/IdentifierInlines.h:

(JSC::Identifier::fromCString):

  • runtime/IntlDateTimeFormatPrototype.cpp:

(JSC::IntlDateTimeFormatPrototype::finishCreation):

  • runtime/IntlNumberFormatPrototype.cpp:

(JSC::IntlNumberFormatPrototype::finishCreation):

  • runtime/IntlObject.cpp:

(JSC::IntlObject::finishCreation):

  • runtime/JSObject.cpp:

(JSC::JSObject::reifyAllStaticProperties):

  • runtime/JSObject.h:

(JSC::makeIdentifier):

  • runtime/JSObjectInlines.h:

(JSC::JSObject::getNonReifiedStaticPropertyNames):

  • runtime/JSTypedArrayViewPrototype.cpp:

(JSC::JSTypedArrayViewPrototype::finishCreation):

  • runtime/ProxyConstructor.cpp:

(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::ProxyConstructor::finishCreation):

  • runtime/ProxyObject.cpp:

(JSC::ProxyObject::performInternalMethodGetOwnProperty):
(JSC::JSC_DEFINE_HOST_FUNCTION):
(JSC::ProxyObject::performDelete):
(JSC::ProxyObject::performPreventExtensions):
(JSC::ProxyObject::performIsExtensible):
(JSC::ProxyObject::performGetOwnPropertyNames):
(JSC::ProxyObject::performSetPrototype):
(JSC::ProxyObject::performGetPrototype):

  • runtime/StringPrototype.cpp:

(JSC::StringPrototype::finishCreation):

  • tools/JSDollarVM.cpp:

(JSC::JSDollarVM::finishCreation):
(JSC::JSDollarVM::addFunction):
(JSC::JSDollarVM::addConstructibleFunction):

  • tools/JSDollarVM.h:
  • wasm/js/JSWebAssembly.cpp:

(JSC::JSWebAssembly::finishCreation):

Source/WebCore:

  • Modules/encryptedmedia/legacy/LegacyCDMSessionClearKey.cpp:

(WebCore::CDMSessionClearKey::update):

  • bridge/testbindings.cpp:

(main):

  • bridge/testbindings.mm:

(main):

  • crypto/SubtleCrypto.cpp:

(WebCore::normalizeCryptoAlgorithmParameters):

  • html/HTMLMediaElement.cpp:

(WebCore::HTMLMediaElement::updatePageScaleFactorJSProperty):
(WebCore::HTMLMediaElement::updateUsesLTRUserInterfaceLayoutDirectionJSProperty):
(WebCore::HTMLMediaElement::setControllerJSProperty):
(WebCore::HTMLMediaElement::setMediaControlsMaximumRightContainerButtonCountOverride):
(WebCore::HTMLMediaElement::setMediaControlsHidePlaybackRates):

  • html/HTMLMediaElement.h:
  • inspector/InspectorFrontendHost.cpp:

(WebCore::InspectorFrontendHost::addSelfToGlobalObjectInWorld):
(WebCore::InspectorFrontendHost::showContextMenu):

  • inspector/WebInjectedScriptHost.cpp:

(WebCore::constructInternalProperty):
(WebCore::objectForPaymentOptions):
(WebCore::objectForPaymentCurrencyAmount):
(WebCore::objectForPaymentItem):
(WebCore::objectForPaymentShippingOption):
(WebCore::objectForPaymentDetailsModifier):
(WebCore::objectForPaymentDetails):
(WebCore::objectForEventTargetListeners):

  • inspector/agents/InspectorCanvasAgent.cpp:

(WebCore::InspectorCanvasAgent::consoleStartRecordingCanvas):

  • inspector/agents/InspectorDOMAgent.cpp:

(WebCore::InspectorDOMAgent::buildObjectForEventListener):

  • inspector/agents/page/PageAuditAgent.cpp:

(WebCore::PageAuditAgent::populateAuditObject):

  • testing/Internals.cpp:
  • testing/Internals.h:
  • worklets/PaintWorkletGlobalScope.cpp:

(WebCore::PaintWorkletGlobalScope::registerPaint):

Source/WebKit:

  • WebProcess/WebPage/IPCTestingAPI.cpp:

(WebKit::IPCTestingAPI::jsResultFromReplyDecoder):
(WebKit::IPCTestingAPI::createJSArrayForArgumentDescriptions):
(WebKit::IPCTestingAPI::JSIPC::messages):
(WebKit::IPCTestingAPI::JSMessageListener::jsDescriptionFromDecoder):
(WebKit::IPCTestingAPI::inject):

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