Bug Summary

File:Source/JavaScriptCore/parser/ASTBuilder.h
Warning:line 1214, column 5
Member variable 'm_parserArena' in 'JSC::ASTBuilder' is a reference to ref-countable type 'JSC::ParserArena'; member variables must be Ref, RefPtr, WeakRef, or WeakPtr

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple arm64-apple-macosx26.2.0 -O3 -Wundef-prefix=TARGET_OS_ -Werror=undef-prefix -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Parser.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=osx -analyzer-checker=security.insecureAPI.decodeValueOfObjCType -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -mframe-pointer=non-leaf -ffp-contract=on -fno-rounding-math -target-sdk-version=26.2 -fdepfile-entry=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.2.sdk/SDKSettings.json -fcompatibility-qualified-id-block-type-checking -fvisibility-inlines-hidden-static-local-var -fno-modulemap-allow-subdirectory-search -fdefine-target-os-macros -enable-tlsdesc -target-cpu apple-m1 -target-feature +v8.4a -target-feature +aes -target-feature +altnzcv -target-feature +ccdp -target-feature +ccpp -target-feature +complxnum -target-feature +crc -target-feature +dotprod -target-feature +flagm -target-feature +fp-armv8 -target-feature +fp16fml -target-feature +fptoint -target-feature +fullfp16 -target-feature +jsconv -target-feature +lse -target-feature +neon -target-feature +pauth -target-feature +perfmon -target-feature +predres -target-feature +ras -target-feature +rcpc -target-feature +rdm -target-feature +sb -target-feature +sha2 -target-feature +sha3 -target-feature +specrestrict -target-feature +ssbs -target-abi darwinpcs -debug-info-kind=standalone -dwarf-version=5 -debugger-tuning=lldb -fdebug-compilation-dir=/Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/Source/JavaScriptCore -target-linker-version 1230.1 -fcoverage-compilation-dir=/Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/Source/JavaScriptCore -resource-dir /Users/buildbot/Library/Developer/Toolchains/swift-webkit.xctoolchain/usr/lib/clang/21 -dependency-file /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/scan-build-output/StaticAnalyzer/JavaScriptCore/libJavaScriptCore/normal/arm64/Parser.d -skip-unused-modulemap-deps -MT dependencies -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.2.sdk -iquote /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/JavaScriptCore.build/Release/libJavaScriptCore.build/JavaScriptCore-generated-files.hmap -iquote /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/JavaScriptCore.build/Release/libJavaScriptCore.build/JavaScriptCore-project-headers.hmap -isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.2.sdk/usr/local/include --system-header-prefix=unicode/ -isystem /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitLibraries/SDKs/macosx26.0-additions.sdk/usr/local/include -include-pch /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/PrecompiledHeaders/SharedPrecompiledHeaders/14042218785898393167/JavaScriptCorePrefix.h.gch -D _LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE_EXTENSIVE -D NDEBUG -D ENABLE_JSC_RESTRICTED_OPTIONS_BY_DEFAULT=1 -D PAS_BMALLOC_HIDDEN -D __clang_analyzer__ -I /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/JavaScriptCore.build/Release/libJavaScriptCore.build/JavaScriptCore-own-target-headers.hmap -I /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/JavaScriptCore.build/Release/libJavaScriptCore.build/JavaScriptCore-all-target-headers.hmap -I /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/Release/include -I /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/Release/DerivedSources/JavaScriptCore -I /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/Source/JavaScriptCore -I /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/Release/usr/local/include -I /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/JavaScriptCore.build/Release/libJavaScriptCore.build/DerivedSources-normal/arm64 -I /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/JavaScriptCore.build/Release/libJavaScriptCore.build/DerivedSources/arm64 -I /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/JavaScriptCore.build/Release/libJavaScriptCore.build/DerivedSources -F/Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/WebKitBuild/Release -D __STDC_WANT_LIB_EXT1__=1 -I/usr/local/include -stdlib=libc++ -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.2.sdk/usr/include/c++/v1 -internal-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.2.sdk/usr/local/include -internal-isystem /Users/buildbot/Library/Developer/Toolchains/swift-webkit.xctoolchain/usr/lib/clang/21/include -internal-externc-isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.2.sdk/usr/include -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.2.sdk/System/Library/Frameworks -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.2.sdk/System/Library/SubFrameworks -internal-iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX26.2.sdk/Library/Frameworks -Wno-trigraphs -Werror -Wno-missing-field-initializers -Wmissing-prototypes -Wdocumentation -Wunreachable-code -Wnon-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wunused-function -Wno-unused-label -Wno-unused-parameter -Wunused-variable -Wunused-value -Wempty-body -Wuninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wconstant-conversion -Wint-conversion -Wbool-conversion -Wenum-conversion -Wno-float-conversion -Wnon-literal-null-conversion -Wobjc-literal-conversion -Wsign-compare -Wno-shorten-64-to-32 -Wnewline-eof -Wno-c++11-extensions -Wno-implicit-fallthrough -Wdeprecated-declarations -Winvalid-offsetof -Wno-sign-conversion -Winfinite-recursion -Wmove -Wcomma -Wblock-capture-autoreleasing -Wstrict-prototypes -Wrange-loop-analysis -Wno-semicolon-before-method-body -Wall -Wc99-designator -Wconditional-uninitialized -Wextra -Wdeprecated-enum-enum-conversion -Wdeprecated-enum-float-conversion -Wenum-float-conversion -Wfinal-dtor-non-final-class -Wformat=2 -Wmisleading-indentation -Wpointer-to-int-cast -Wreorder-init-list -Wundef -Wunused-but-set-variable -Wvla -Werror=unguarded-availability -Wno-elaborated-enum-base -Wcast-qual -Wchar-subscripts -Wextra-tokens -Winit-self -Wmissing-noreturn -Wpacked -Wpointer-arith -Wredundant-decls -Wwrite-strings -Wexit-time-destructors -Wglobal-constructors -Wtautological-compare -Wimplicit-fallthrough -Wvla -Wliteral-conversion -Wthread-safety -Wno-profile-instr-out-of-date -Wno-profile-instr-unprofiled -Wno-backend-plugin -Wunsafe-buffer-usage -Wno-unknown-warning-option -std=c++2b -fdeprecated-macro -ferror-limit 19 -fmacro-backtrace-limit=0 -fvisibility=hidden -fvisibility-inlines-hidden -stack-protector 1 -fblocks -fencode-extended-block-signature -fno-rtti -fregister-global-dtors-with-atexit -fgnuc-version=4.2.1 -fno-threadsafe-statics -fno-implicit-modules -fskip-odr-check-in-gmf -fpascal-strings -fmax-type-align=16 -fdiagnostics-show-note-include-stack -vectorize-loops -fsafe-buffer-usage-suggestions -analyzer-output=html -analyzer-config report-in-main-source-file=true -analyzer-config nullability:NoDiagnoseCallsToSystemHeaders=true -analyzer-checker optin.osx.cocoa.localizability.NonLocalizedStringChecker -analyzer-checker security.insecureAPI.UncheckedReturn -analyzer-checker security.insecureAPI.getpw -analyzer-checker security.insecureAPI.gets -analyzer-checker security.insecureAPI.mkstemp -analyzer-checker security.insecureAPI.mktemp -analyzer-disable-checker security.insecureAPI.rand -analyzer-disable-checker security.insecureAPI.strcpy -analyzer-checker security.insecureAPI.vfork -analyzer-disable-checker alpha,apiModeling,core,cplusplus,deadcode,debug,fuchsia,nullability,optin,osx,security,unix,webkit -analyzer-checker alpha.webkit.ForwardDeclChecker,alpha.webkit.MemoryUnsafeCastChecker,alpha.webkit.NoDeleteChecker,alpha.webkit.NoUncheckedPtrMemberChecker,alpha.webkit.NoUnretainedMemberChecker,alpha.webkit.RetainPtrCtorAdoptChecker,alpha.webkit.UncheckedCallArgsChecker,alpha.webkit.UncheckedLocalVarsChecker,alpha.webkit.UncountedCallArgsChecker,alpha.webkit.UncountedLocalVarsChecker,alpha.webkit.UnretainedCallArgsChecker,alpha.webkit.UnretainedLambdaCapturesChecker,alpha.webkit.UnretainedLocalVarsChecker,webkit.NoUncountedMemberChecker,webkit.RefCntblBaseVirtualDtor,webkit.UncountedLambdaCapturesChecker -analyzer-config max-nodes=10000000 -analyzer-config verbose-report-filename=true -fdwarf2-cfi-asm -o /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/scan-build-output/StaticAnalyzer/JavaScriptCore/libJavaScriptCore/normal/arm64/Parser.plist -x c++ /Volumes/Data/worker/macOS-Safer-CPP-Checks-EWS/build/Source/JavaScriptCore/parser/Parser.cpp
1/*
2 * Copyright (C) 2010-2019 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "BuiltinNames.h"
29#include "BytecodeIntrinsicRegistry.h"
30#include "MathCommon.h"
31#include "NodeConstructors.h"
32#include "Parser.h"
33#include "SyntaxChecker.h"
34#include "VariableEnvironment.h"
35#include <utility>
36
37namespace JSC {
38
39class ASTBuilder {
40 struct BinaryOpInfo {
41 BinaryOpInfo() {}
42 BinaryOpInfo(const JSTextPosition& otherStart, const JSTextPosition& otherDivot, const JSTextPosition& otherEnd, bool rhsHasAssignment)
43 : start(otherStart)
44 , divot(otherDivot)
45 , end(otherEnd)
46 , hasAssignment(rhsHasAssignment)
47 {
48 }
49 BinaryOpInfo(const BinaryOpInfo& lhs, const BinaryOpInfo& rhs)
50 : start(lhs.start)
51 , divot(rhs.start)
52 , end(rhs.end)
53 , hasAssignment(lhs.hasAssignment || rhs.hasAssignment)
54 {
55 }
56 JSTextPosition start;
57 JSTextPosition divot;
58 JSTextPosition end;
59 bool hasAssignment;
60 };
61
62
63 struct AssignmentInfo {
64 AssignmentInfo() {}
65 AssignmentInfo(ExpressionNode* node, const JSTextPosition& start, const JSTextPosition& divot, int initAssignments, Operator op)
66 : m_node(node)
67 , m_start(start)
68 , m_divot(divot)
69 , m_initAssignments(initAssignments)
70 , m_op(op)
71 {
72 ASSERT(m_divot.offset >= m_divot.lineStartOffset)((void)0);
73 ASSERT(m_start.offset >= m_start.lineStartOffset)((void)0);
74 }
75 ExpressionNode* m_node;
76 JSTextPosition m_start;
77 JSTextPosition m_divot;
78 int m_initAssignments;
79 Operator m_op;
80 };
81public:
82 ASTBuilder(VM& vm, ParserArena& parserArena, SourceCode* sourceCode)
83 : m_vm(vm)
84 , m_parserArena(parserArena)
85 , m_sourceCode(sourceCode)
86 , m_evalCount(0)
87 {
88 }
89
90 struct BinaryExprContext {
91 BinaryExprContext(ASTBuilder&) {}
92 };
93 struct UnaryExprContext {
94 UnaryExprContext(ASTBuilder&) {}
95 };
96
97 typedef ExpressionNode* Expression;
98 typedef JSC::SourceElements* SourceElements;
99 typedef ArgumentsNode* Arguments;
100 typedef CommaNode* Comma;
101 typedef PropertyNode* Property;
102 typedef PropertyListNode* PropertyList;
103 typedef ElementNode* ElementList;
104 typedef ArgumentListNode* ArgumentsList;
105 typedef TemplateExpressionListNode* TemplateExpressionList;
106 typedef TemplateStringNode* TemplateString;
107 typedef TemplateStringListNode* TemplateStringList;
108 typedef TemplateLiteralNode* TemplateLiteral;
109 typedef FunctionParameters* FormalParameterList;
110 typedef FunctionMetadataNode* FunctionBody;
111 typedef ClassExprNode* ClassExpression;
112 typedef ModuleNameNode* ModuleName;
113 typedef ImportSpecifierNode* ImportSpecifier;
114 typedef ImportSpecifierListNode* ImportSpecifierList;
115 typedef ImportAttributesListNode* ImportAttributesList;
116 typedef ExportSpecifierNode* ExportSpecifier;
117 typedef ExportSpecifierListNode* ExportSpecifierList;
118 typedef StatementNode* Statement;
119 typedef ClauseListNode* ClauseList;
120 typedef CaseClauseNode* Clause;
121 typedef std::pair<ExpressionNode*, BinaryOpInfo> BinaryOperand;
122 typedef DestructuringPatternNode* DestructuringPattern;
123 typedef ArrayPatternNode* ArrayPattern;
124 typedef ObjectPatternNode* ObjectPattern;
125 typedef BindingNode* BindingPattern;
126 typedef AssignmentElementNode* AssignmentElement;
127 static constexpr bool CreatesAST = true;
128 static constexpr bool NeedsFreeVariableInfo = true;
129 static constexpr bool CanUseFunctionCache = true;
130 static constexpr OptionSet<LexerFlags> DontBuildKeywords = { };
131 static constexpr OptionSet<LexerFlags> DontBuildStrings = { };
132
133 ExpressionNode* makeBinaryNode(const JSTokenLocation&, int token, std::pair<ExpressionNode*, BinaryOpInfo>, std::pair<ExpressionNode*, BinaryOpInfo>);
134 ExpressionNode* makeStaticBlockFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
135 ExpressionNode* makeFunctionCallNode(const JSTokenLocation&, ExpressionNode* func, bool previousBaseWasSuper, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd, size_t callOrApplyChildDepth, bool isOptionalCall);
136
137 JSC::SourceElements* createSourceElements() { return new (m_parserArena) JSC::SourceElements(); }
138
139 int features() const { return m_scope.m_features; }
140 int numConstants() const { return m_scope.m_numConstants; }
141
142 ExpressionNode* makeAssignNode(const JSTokenLocation&, ExpressionNode* left, Operator, ExpressionNode* right, bool leftHasAssignments, bool rightHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
143 ExpressionNode* makePrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
144 ExpressionNode* makePostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
145 ExpressionNode* makeTypeOfNode(const JSTokenLocation&, ExpressionNode*, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
146 ExpressionNode* makeDeleteNode(const JSTokenLocation&, ExpressionNode*, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end);
147 ExpressionNode* makeNegateNode(const JSTokenLocation&, ExpressionNode*);
148 ExpressionNode* makeBitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
149 ExpressionNode* makePowNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
150 ExpressionNode* makeMultNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
151 ExpressionNode* makeDivNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
152 ExpressionNode* makeModNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
153 ExpressionNode* makeAddNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
154 ExpressionNode* makeSubNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
155 ExpressionNode* makeBitXOrNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
156 ExpressionNode* makeBitAndNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
157 ExpressionNode* makeBitOrNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
158 ExpressionNode* makeCoalesceNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right);
159 ExpressionNode* makeLeftShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
160 ExpressionNode* makeRightShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
161 ExpressionNode* makeURightShiftNode(const JSTokenLocation&, ExpressionNode* left, ExpressionNode* right, bool rightHasAssignments);
162
163 ExpressionNode* createLogicalNot(const JSTokenLocation& location, ExpressionNode* expr)
164 {
165 if (expr->isNumber())
166 return createBoolean(location, isZeroOrUnordered(static_cast<NumberNode*>(expr)->value()));
167
168 return new (m_parserArena) LogicalNotNode(location, expr);
169 }
170 ExpressionNode* createUnaryPlus(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_parserArena) UnaryPlusNode(location, expr); }
171 ExpressionNode* createVoid(const JSTokenLocation& location, ExpressionNode* expr)
172 {
173 incConstants();
174 return new (m_parserArena) VoidNode(location, expr);
175 }
176 ExpressionNode* createThisExpr(const JSTokenLocation& location)
177 {
178 usesThis();
179 return new (m_parserArena) ThisNode(location);
180 }
181 ExpressionNode* createSuperExpr(const JSTokenLocation& location)
182 {
183 return new (m_parserArena) SuperNode(location);
184 }
185 ExpressionNode* createImportExpr(const JSTokenLocation& location, ExpressionNode* expr, ExpressionNode* option, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
186 {
187 auto* node = new (m_parserArena) ImportNode(location, expr, option);
188 setExceptionLocation(node, start, divot, end);
189 return node;
190 }
191 ExpressionNode* createNewTargetExpr(const JSTokenLocation location)
192 {
193 usesNewTarget();
194 return new (m_parserArena) NewTargetNode(location);
195 }
196 ExpressionNode* createImportMetaExpr(const JSTokenLocation& location, ExpressionNode* expr) { return new (m_parserArena) ImportMetaNode(location, expr); }
197 bool isMetaProperty(ExpressionNode* node) { return node->isMetaProperty(); }
198 bool isNewTarget(ExpressionNode* node) { return node->isNewTarget(); }
199 bool isImportMeta(ExpressionNode* node) { return node->isImportMeta(); }
200 ExpressionNode* createResolve(const JSTokenLocation& location, const Identifier& ident, const JSTextPosition& start, const JSTextPosition& end, const bool needToCheckUsesArguments = true)
201 {
202 if (needToCheckUsesArguments && m_vm.propertyNames->arguments == ident)
203 usesArguments();
204
205 if (ident.isSymbol()) {
206 auto entry = m_vm.bytecodeIntrinsicRegistry().lookup(ident);
207 if (entry)
208 return new (m_parserArena) BytecodeIntrinsicNode(BytecodeIntrinsicNode::Type::Constant, location, entry.value(), ident, nullptr, start, start, end);
209 }
210
211 return new (m_parserArena) ResolveNode(location, ident, start);
212 }
213 ExpressionNode* createPrivateIdentifierNode(const JSTokenLocation& location, const Identifier& ident)
214 {
215 return new (m_parserArena) PrivateIdentifierNode(location, ident);
216 }
217 ExpressionNode* createObjectLiteral(const JSTokenLocation& location) { return new (m_parserArena) ObjectLiteralNode(location); }
218 ExpressionNode* createObjectLiteral(const JSTokenLocation& location, PropertyListNode* properties) { return new (m_parserArena) ObjectLiteralNode(location, properties); }
219
220 ExpressionNode* createArray(const JSTokenLocation& location, int elisions)
221 {
222 if (elisions)
223 incConstants();
224 return new (m_parserArena) ArrayNode(location, elisions);
225 }
226
227 ExpressionNode* createArray(const JSTokenLocation& location, ElementNode* elems) { return new (m_parserArena) ArrayNode(location, elems); }
228 ExpressionNode* createArray(const JSTokenLocation& location, int elisions, ElementNode* elems)
229 {
230 if (elisions)
231 incConstants();
232 return new (m_parserArena) ArrayNode(location, elisions, elems);
233 }
234 ExpressionNode* createDoubleExpr(const JSTokenLocation& location, double d)
235 {
236 incConstants();
237 return new (m_parserArena) DoubleNode(location, d);
238 }
239 ExpressionNode* createIntegerExpr(const JSTokenLocation& location, double d)
240 {
241 incConstants();
242 return new (m_parserArena) IntegerNode(location, d);
243 }
244
245 ExpressionNode* createBigInt(const JSTokenLocation& location, const Identifier* bigInt, uint8_t radix)
246 {
247 incConstants();
248 return new (m_parserArena) BigIntNode(location, *bigInt, radix);
249 }
250
251 ExpressionNode* createString(const JSTokenLocation& location, const Identifier* string)
252 {
253 ASSERT(string)((void)0);
254 incConstants();
255 return new (m_parserArena) StringNode(location, *string);
256 }
257
258 ExpressionNode* createBoolean(const JSTokenLocation& location, bool b)
259 {
260 incConstants();
261 return new (m_parserArena) BooleanNode(location, b);
262 }
263
264 ExpressionNode* createNull(const JSTokenLocation& location)
265 {
266 incConstants();
267 return new (m_parserArena) NullNode(location);
268 }
269
270 ExpressionNode* createBracketAccess(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* property, bool propertyHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
271 {
272 if (base->isSuperNode())
273 usesSuperProperty();
274
275 BracketAccessorNode* node = new (m_parserArena) BracketAccessorNode(location, base, property, propertyHasAssignments);
276 setExceptionLocation(node, start, divot, end);
277 return node;
278 }
279
280 ExpressionNode* createDotAccess(const JSTokenLocation& location, ExpressionNode* base, const Identifier* property, DotType type, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
281 {
282 if (base->isSuperNode())
283 usesSuperProperty();
284
285 DotAccessorNode* node = new (m_parserArena) DotAccessorNode(location, base, *property, type);
286 setExceptionLocation(node, start, divot, end);
287 return node;
288 }
289
290 ExpressionNode* createSpreadExpression(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
291 {
292 auto node = new (m_parserArena) SpreadExpressionNode(location, expression);
293 setExceptionLocation(node, start, divot, end);
294 return node;
295 }
296
297 ExpressionNode* createObjectSpreadExpression(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
298 {
299 auto node = new (m_parserArena) ObjectSpreadExpressionNode(location, expression);
300 setExceptionLocation(node, start, divot, end);
301 return node;
302 }
303
304 TemplateStringNode* createTemplateString(const JSTokenLocation& location, const Identifier* cooked, const Identifier* raw)
305 {
306 return new (m_parserArena) TemplateStringNode(location, cooked, raw);
307 }
308
309 TemplateStringListNode* createTemplateStringList(TemplateStringNode* templateString)
310 {
311 return new (m_parserArena) TemplateStringListNode(templateString);
312 }
313
314 TemplateStringListNode* createTemplateStringList(TemplateStringListNode* templateStringList, TemplateStringNode* templateString)
315 {
316 return new (m_parserArena) TemplateStringListNode(templateStringList, templateString);
317 }
318
319 TemplateExpressionListNode* createTemplateExpressionList(ExpressionNode* expression)
320 {
321 return new (m_parserArena) TemplateExpressionListNode(expression);
322 }
323
324 TemplateExpressionListNode* createTemplateExpressionList(TemplateExpressionListNode* templateExpressionListNode, ExpressionNode* expression)
325 {
326 return new (m_parserArena) TemplateExpressionListNode(templateExpressionListNode, expression);
327 }
328
329 TemplateLiteralNode* createTemplateLiteral(const JSTokenLocation& location, TemplateStringListNode* templateStringList)
330 {
331 return new (m_parserArena) TemplateLiteralNode(location, templateStringList);
332 }
333
334 TemplateLiteralNode* createTemplateLiteral(const JSTokenLocation& location, TemplateStringListNode* templateStringList, TemplateExpressionListNode* templateExpressionList)
335 {
336 return new (m_parserArena) TemplateLiteralNode(location, templateStringList, templateExpressionList);
337 }
338
339 ExpressionNode* createTaggedTemplate(const JSTokenLocation& location, ExpressionNode* base, TemplateLiteralNode* templateLiteral, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
340 {
341 auto node = new (m_parserArena) TaggedTemplateNode(location, base, templateLiteral);
342 setExceptionLocation(node, start, divot, end);
343 setEndOffset(node, end.offset);
344 return node;
345 }
346
347 ExpressionNode* createRegExp(const JSTokenLocation& location, const Identifier& pattern, const Identifier& flags, const JSTextPosition& start, bool skipSyntaxCheck)
348 {
349 if (!skipSyntaxCheck && Yarr::hasError(Yarr::checkSyntax(pattern.string(), flags.string())))
350 return nullptr;
351 RegExpNode* node = new (m_parserArena) RegExpNode(location, pattern, flags);
352 int size = pattern.length() + 2; // + 2 for the two /'s
353 JSTextPosition end = start + size;
354 setExceptionLocation(node, start, end, end);
355 return node;
356 }
357
358 ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, ArgumentsNode* arguments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
359 {
360 NewExprNode* node = new (m_parserArena) NewExprNode(location, expr, arguments);
361 setExceptionLocation(node, start, divot, end);
362 return node;
363 }
364
365 ExpressionNode* createNewExpr(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
366 {
367 NewExprNode* node = new (m_parserArena) NewExprNode(location, expr);
368 setExceptionLocation(node, start, divot, end);
369 return node;
370 }
371
372 ExpressionNode* createOptionalChain(const JSTokenLocation& location, ExpressionNode* base, ExpressionNode* expr, bool isOutermost)
373 {
374 if (base)
375 base->setIsOptionalChainBase();
376 return new (m_parserArena) OptionalChainNode(location, expr, isOutermost);
377 }
378
379 ExpressionNode* createConditionalExpr(const JSTokenLocation& location, ExpressionNode* condition, ExpressionNode* lhs, ExpressionNode* rhs)
380 {
381 return new (m_parserArena) ConditionalNode(location, condition, lhs, rhs);
382 }
383
384 ExpressionNode* createAssignResolve(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* rhs, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end, AssignmentContext assignmentContext)
385 {
386 if (rhs->isBaseFuncExprNode()) {
387 auto metadata = static_cast<BaseFuncExprNode*>(rhs)->metadata();
388 metadata->setEcmaName(ident);
389 } else if (rhs->isClassExprNode())
390 static_cast<ClassExprNode*>(rhs)->setEcmaName(ident);
391 if (assignmentContext == AssignmentContext::AwaitUsingDeclarationStatement)
392 usesAwait();
393 AssignResolveNode* node = new (m_parserArena) AssignResolveNode(location, ident, rhs, assignmentContext);
394 setExceptionLocation(node, start, divot, end);
395 return node;
396 }
397
398 YieldExprNode* createYield(const JSTokenLocation& location)
399 {
400 return new (m_parserArena) YieldExprNode(location, nullptr, /* delegate */ false);
401 }
402
403 YieldExprNode* createYield(const JSTokenLocation& location, ExpressionNode* argument, bool delegate, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
404 {
405 YieldExprNode* node = new (m_parserArena) YieldExprNode(location, argument, delegate);
406 setExceptionLocation(node, start, divot, end);
407 return node;
408 }
409
410 AwaitExprNode* createAwait(const JSTokenLocation& location, ExpressionNode* argument, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
411 {
412 ASSERT(argument)((void)0);
413 usesAwait();
414 AwaitExprNode* node = new (m_parserArena) AwaitExprNode(location, argument);
415 setExceptionLocation(node, start, divot, end);
416 return node;
417 }
418
419 DefineFieldNode* createDefineField(const JSTokenLocation& location, const Identifier& ident, ExpressionNode* initializer, DefineFieldNode::Type type)
420 {
421 return new (m_parserArena) DefineFieldNode(location, ident, initializer, type);
422 }
423
424 ClassExprNode* createClassExpr(const JSTokenLocation& location, const ParserClassInfo<ASTBuilder>& classInfo, VariableEnvironment&& classHeadEnvironment, VariableEnvironment&& classEnvironment, ExpressionNode* constructor,
425 ExpressionNode* parentClass, PropertyListNode* classElements, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
426 {
427 SourceCode source = m_sourceCode->subExpression(classInfo.startOffset, classInfo.endOffset, classInfo.startLine, classInfo.startColumn);
428 ClassExprNode* node = new (m_parserArena) ClassExprNode(location, *classInfo.className, source, WTF::move(classHeadEnvironment), WTF::move(classEnvironment), constructor, parentClass, classElements);
429 setExceptionLocation(node, start, divot, end);
430 return node;
431 }
432
433 ExpressionNode* createFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo)
434 {
435 FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *functionInfo.name, functionInfo.body,
436 m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn));
437 functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
438 return result;
439 }
440
441 ExpressionNode* createGeneratorFunctionBody(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo, const Identifier& name)
442 {
443 FuncExprNode* result = static_cast<FuncExprNode*>(createFunctionExpr(location, functionInfo));
444 if (!name.isNull())
445 result->metadata()->setEcmaName(name);
446 return result;
447 }
448
449 ExpressionNode* createAsyncFunctionBody(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo, SourceParseMode parseMode, const Identifier& name)
450 {
451 if (parseMode == SourceParseMode::AsyncArrowFunctionBodyMode) {
452 SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.body->isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
453 FuncExprNode* result = new (m_parserArena) FuncExprNode(location, *functionInfo.name, functionInfo.body, source);
454 if (!name.isNull())
455 result->metadata()->setEcmaName(name);
456 functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
457 return result;
458 }
459 FuncExprNode* result = static_cast<FuncExprNode*>(createFunctionExpr(location, functionInfo));
460 if (!name.isNull())
461 result->metadata()->setEcmaName(name);
462 return result;
463 }
464
465 ExpressionNode* createMethodDefinition(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo)
466 {
467 MethodDefinitionNode* result = new (m_parserArena) MethodDefinitionNode(location, *functionInfo.name, functionInfo.body,
468 m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn));
469 functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
470 return result;
471 }
472
473 FunctionMetadataNode* createFunctionMetadata(
474 const JSTokenLocation& startLocation, const JSTokenLocation& endLocation,
475 unsigned startColumn, unsigned endColumn, unsigned functionStart, int functionNameStart,
476 int parametersStart, ImplementationVisibility implementationVisibility, LexicallyScopedFeatures lexicallyScopedFeatures,
477 ConstructorKind constructorKind, SuperBinding superBinding,
478 unsigned parameterCount,
479 SourceParseMode mode, bool isArrowFunctionBodyExpression)
480 {
481 return new (m_parserArena) FunctionMetadataNode(
482 m_parserArena, startLocation, endLocation, startColumn, endColumn, functionStart,
483 functionNameStart, parametersStart, implementationVisibility,
484 lexicallyScopedFeatures, constructorKind, superBinding,
485 parameterCount, mode, isArrowFunctionBodyExpression);
486 }
487
488 ExpressionNode* createArrowFunctionExpr(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo)
489 {
490 usesArrowFunction();
491 SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.body->isArrowFunctionBodyExpression() ? functionInfo.endOffset - 1 : functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
492 ArrowFuncExprNode* result = new (m_parserArena) ArrowFuncExprNode(location, *functionInfo.name, functionInfo.body, source);
493 functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
494 return result;
495 }
496
497 ArgumentsNode* createArguments() { return new (m_parserArena) ArgumentsNode(); }
498 ArgumentsNode* createArguments(ArgumentListNode* args, bool hasAssignments) { return new (m_parserArena) ArgumentsNode(args, hasAssignments); }
499 ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ExpressionNode* arg) { return new (m_parserArena) ArgumentListNode(location, arg); }
500 ArgumentListNode* createArgumentsList(const JSTokenLocation& location, ArgumentListNode* args, ExpressionNode* arg) { return new (m_parserArena) ArgumentListNode(location, args, arg); }
501
502 NEVER_INLINE__attribute__((__noinline__)) PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type,
503 const Identifier* name, const ParserFunctionInfo<ASTBuilder>& functionInfo, ClassElementTag tag)
504 {
505 ASSERT(name)((void)0);
506 functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
507 functionInfo.body->setEcmaName(*name);
508 SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
509 MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, m_vm.propertyNames->nullIdentifier, functionInfo.body, source);
510 return new (m_parserArena) PropertyNode(*name, methodDef, type, SuperBinding::Needed, tag);
511 }
512
513 NEVER_INLINE__attribute__((__noinline__)) PropertyNode* createGetterOrSetterProperty(const JSTokenLocation& location, PropertyNode::Type type,
514 ExpressionNode* name, const ParserFunctionInfo<ASTBuilder>& functionInfo, ClassElementTag tag)
515 {
516 ASSERT(name)((void)0);
517 functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
518 SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
519 MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, m_vm.propertyNames->nullIdentifier, functionInfo.body, source);
520 return new (m_parserArena) PropertyNode(name, methodDef, type, SuperBinding::Needed, tag);
521 }
522
523 NEVER_INLINE__attribute__((__noinline__)) PropertyNode* createGetterOrSetterProperty(VM& vm, ParserArena& parserArena, const JSTokenLocation& location, PropertyNode::Type type,
524 double name, const ParserFunctionInfo<ASTBuilder>& functionInfo, ClassElementTag tag)
525 {
526 functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
527 const Identifier& ident = parserArena.identifierArena().makeNumericIdentifier(vm, name);
528 functionInfo.body->setEcmaName(ident);
529 SourceCode source = m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn);
530 MethodDefinitionNode* methodDef = new (m_parserArena) MethodDefinitionNode(location, vm.propertyNames->nullIdentifier, functionInfo.body, source);
531 return new (m_parserArena) PropertyNode(ident, methodDef, type, SuperBinding::Needed, tag);
532 }
533
534 PropertyNode* createProperty(const Identifier* propertyName, PropertyNode::Type type, SuperBinding superBinding, ClassElementTag tag)
535 {
536 return new (m_parserArena) PropertyNode(*propertyName, type, superBinding, tag);
537 }
538 PropertyNode* createProperty(const Identifier* propertyName, ExpressionNode* node, PropertyNode::Type type, SuperBinding superBinding, InferName inferName, ClassElementTag tag)
539 {
540 if (inferName == InferName::Allowed) {
541 if (node->isBaseFuncExprNode()) {
542 auto metadata = static_cast<BaseFuncExprNode*>(node)->metadata();
543 metadata->setEcmaName(*propertyName);
544 } else if (node->isClassExprNode())
545 static_cast<ClassExprNode*>(node)->setEcmaName(*propertyName);
546 }
547 return new (m_parserArena) PropertyNode(*propertyName, node, type, superBinding, tag);
548 }
549 PropertyNode* createProperty(ExpressionNode* node, PropertyNode::Type type, SuperBinding superBinding, ClassElementTag tag)
550 {
551 return new (m_parserArena) PropertyNode(node, type, superBinding, tag);
552 }
553 PropertyNode* createProperty(VM& vm, ParserArena& parserArena, double propertyName, ExpressionNode* node, PropertyNode::Type type, SuperBinding superBinding, ClassElementTag tag)
554 {
555 return new (m_parserArena) PropertyNode(parserArena.identifierArena().makeNumericIdentifier(vm, propertyName), node, type, superBinding, tag);
556 }
557 PropertyNode* createProperty(ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, SuperBinding superBinding, ClassElementTag tag) { return new (m_parserArena) PropertyNode(propertyName, node, type, superBinding, tag); }
558 PropertyNode* createProperty(const Identifier* identifier, ExpressionNode* propertyName, ExpressionNode* node, PropertyNode::Type type, SuperBinding superBinding, ClassElementTag tag) { return new (m_parserArena) PropertyNode(*identifier, propertyName, node, type, superBinding, tag); }
559 PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property) { return new (m_parserArena) PropertyListNode(location, property); }
560 PropertyListNode* createPropertyList(const JSTokenLocation& location, PropertyNode* property, PropertyListNode* tail) { return new (m_parserArena) PropertyListNode(location, property, tail); }
561
562 ElementNode* createElementList(int elisions, ExpressionNode* expr) { return new (m_parserArena) ElementNode(elisions, expr); }
563 ElementNode* createElementList(ElementNode* elems, int elisions, ExpressionNode* expr) { return new (m_parserArena) ElementNode(elems, elisions, expr); }
564 ElementNode* createElementList(ArgumentListNode* elems)
565 {
566 ElementNode* head = new (m_parserArena) ElementNode(0, elems->m_expr);
567 ElementNode* tail = head;
568 elems = elems->m_next;
569 while (elems) {
570 tail = new (m_parserArena) ElementNode(tail, 0, elems->m_expr);
571 elems = elems->m_next;
572 }
573 return head;
574 }
575
576 FormalParameterList createFormalParameterList() { return new (m_parserArena) FunctionParameters(); }
577 void appendParameter(FormalParameterList list, DestructuringPattern pattern, ExpressionNode* defaultValue)
578 {
579 list->append(pattern, defaultValue);
580 tryInferNameInPattern(pattern, defaultValue);
581 }
582
583 CaseClauseNode* createClause(ExpressionNode* expr, JSC::SourceElements* statements) { return new (m_parserArena) CaseClauseNode(expr, statements); }
584 ClauseListNode* createClauseList(CaseClauseNode* clause) { return new (m_parserArena) ClauseListNode(clause); }
585 ClauseListNode* createClauseList(ClauseListNode* tail, CaseClauseNode* clause) { return new (m_parserArena) ClauseListNode(tail, clause); }
586
587 StatementNode* createFuncDeclStatement(const JSTokenLocation& location, const ParserFunctionInfo<ASTBuilder>& functionInfo)
588 {
589 FuncDeclNode* decl = new (m_parserArena) FuncDeclNode(location, *functionInfo.name, functionInfo.body,
590 m_sourceCode->subExpression(functionInfo.startOffset, functionInfo.endOffset, functionInfo.startLine, functionInfo.parametersStartColumn));
591 if (*functionInfo.name == m_vm.propertyNames->arguments)
592 usesArguments();
593 functionInfo.body->setLoc(functionInfo.startLine, functionInfo.endLine, location.startOffset, location.lineStartOffset);
594 return decl;
595 }
596
597 StatementNode* createClassDeclStatement(const JSTokenLocation& location, ClassExprNode* classExpression,
598 const JSTextPosition& classStart, const JSTextPosition& classEnd, unsigned startLine, unsigned endLine)
599 {
600 ExpressionNode* assign = createAssignResolve(location, classExpression->name(), classExpression, classStart, classStart + 1, classEnd, AssignmentContext::DeclarationStatement);
601 ClassDeclNode* decl = new (m_parserArena) ClassDeclNode(location, assign);
602 decl->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
603 return decl;
604 }
605
606 StatementNode* createBlockStatement(const JSTokenLocation& location, JSC::SourceElements* elements, int startLine, int endLine, VariableEnvironment&& lexicalVariables, DeclarationStacks::FunctionStack&& functionStack)
607 {
608 BlockNode* block = new (m_parserArena) BlockNode(location, elements, WTF::move(lexicalVariables), WTF::move(functionStack));
609 block->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
610 return block;
611 }
612
613 StatementNode* createExprStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, int end)
614 {
615 ExprStatementNode* result = new (m_parserArena) ExprStatementNode(location, expr);
616 result->setLoc(start.line, end, start.offset, start.lineStartOffset);
617 return result;
618 }
619
620 StatementNode* createIfStatement(const JSTokenLocation& location, ExpressionNode* condition, StatementNode* trueBlock, StatementNode* falseBlock, int start, int end)
621 {
622 IfElseNode* result = new (m_parserArena) IfElseNode(location, condition, trueBlock, falseBlock);
623 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
624 return result;
625 }
626
627 StatementNode* createForLoop(const JSTokenLocation& location, ExpressionNode* initializer, ExpressionNode* condition, ExpressionNode* iter, StatementNode* statements, int start, int end, VariableEnvironment&& lexicalVariables, bool initializerContainsClosure)
628 {
629 ForNode* result = new (m_parserArena) ForNode(location, initializer, condition, iter, statements, WTF::move(lexicalVariables), initializerContainsClosure);
630 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
631 return result;
632 }
633
634 StatementNode* createForInLoop(const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation&, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment&& lexicalVariables)
635 {
636 ForInNode* result = new (m_parserArena) ForInNode(location, lhs, iter, statements, WTF::move(lexicalVariables));
637 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
638 setExceptionLocation(result, eStart, eDivot, eEnd);
639 return result;
640 }
641
642 StatementNode* createForInLoop(const JSTokenLocation& location, DestructuringPatternNode* pattern, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation& declLocation, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment&& lexicalVariables)
643 {
644 auto lexpr = new (m_parserArena) DestructuringAssignmentNode(declLocation, pattern, nullptr);
645 return createForInLoop(location, lexpr, iter, statements, declLocation, eStart, eDivot, eEnd, start, end, WTF::move(lexicalVariables));
646 }
647
648 StatementNode* createForOfLoop(bool isForAwait, const JSTokenLocation& location, ExpressionNode* lhs, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation&, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment&& lexicalVariables)
649 {
650 ForOfNode* result = new (m_parserArena) ForOfNode(isForAwait, location, lhs, iter, statements, WTF::move(lexicalVariables));
651 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
652 setExceptionLocation(result, eStart, eDivot, eEnd);
653 if (isForAwait)
654 usesAwait();
655 return result;
656 }
657
658 StatementNode* createForOfLoop(bool isForAwait, const JSTokenLocation& location, DestructuringPatternNode* pattern, ExpressionNode* iter, StatementNode* statements, const JSTokenLocation& declLocation, const JSTextPosition& eStart, const JSTextPosition& eDivot, const JSTextPosition& eEnd, int start, int end, VariableEnvironment&& lexicalVariables)
659 {
660 auto lexpr = new (m_parserArena) DestructuringAssignmentNode(declLocation, pattern, nullptr);
661 return createForOfLoop(isForAwait, location, lexpr, iter, statements, declLocation, eStart, eDivot, eEnd, start, end, WTF::move(lexicalVariables));
662 }
663
664 bool isBindingNode(const DestructuringPattern& pattern)
665 {
666 return pattern->isBindingNode();
667 }
668
669 bool isLocation(const Expression& node)
670 {
671 return node->isLocation();
672 }
673
674 bool isAssignmentLocation(const Expression& node)
675 {
676 return node->isAssignmentLocation();
677 }
678
679 bool isPrivateLocation(const Expression& node)
680 {
681 return node->isPrivateLocation();
682 }
683
684 bool isObjectLiteral(const Expression& node)
685 {
686 return node->isObjectLiteral();
687 }
688
689 bool isArrayLiteral(const Expression& node)
690 {
691 return node->isArrayLiteral();
692 }
693
694 bool isObjectOrArrayLiteral(const Expression& node)
695 {
696 return isObjectLiteral(node) || isArrayLiteral(node);
697 }
698
699 bool isFunctionCall(const Expression& node)
700 {
701 return node->isFunctionCall();
702 }
703
704 bool shouldSkipPauseLocation(StatementNode* statement) const
705 {
706 return !statement || statement->isLabel();
707 }
708
709 StatementNode* createEmptyStatement(const JSTokenLocation& location) { return new (m_parserArena) EmptyStatementNode(location); }
710
711 StatementNode* createDeclarationStatement(const JSTokenLocation& location, ExpressionNode* expr, int start, int end)
712 {
713 StatementNode* result;
714 result = new (m_parserArena) DeclarationStatement(location, expr);
715 result->setLoc(start, end, location.startOffset, location.lineStartOffset);
716 return result;
717 }
718
719 ExpressionNode* createEmptyVarExpression(const JSTokenLocation& location, const Identifier& identifier)
720 {
721 return new (m_parserArena) EmptyVarExpression(location, identifier);
722 }
723
724 ExpressionNode* createEmptyLetExpression(const JSTokenLocation& location, const Identifier& identifier)
725 {
726 return new (m_parserArena) EmptyLetExpression(location, identifier);
727 }
728
729 StatementNode* createReturnStatement(const JSTokenLocation& location, ExpressionNode* expression, const JSTextPosition& start, const JSTextPosition& end)
730 {
731 ReturnNode* result = new (m_parserArena) ReturnNode(location, expression);
732 setExceptionLocation(result, start, end, end);
733 result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
734 return result;
735 }
736
737 StatementNode* createBreakStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
738 {
739 BreakNode* result = new (m_parserArena) BreakNode(location, *ident);
740 setExceptionLocation(result, start, end, end);
741 result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
742 return result;
743 }
744
745 StatementNode* createContinueStatement(const JSTokenLocation& location, const Identifier* ident, const JSTextPosition& start, const JSTextPosition& end)
746 {
747 ContinueNode* result = new (m_parserArena) ContinueNode(location, *ident);
748 setExceptionLocation(result, start, end, end);
749 result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
750 return result;
751 }
752
753 StatementNode* createTryStatement(const JSTokenLocation& location, StatementNode* tryBlock, DestructuringPatternNode* catchPattern, StatementNode* catchBlock, StatementNode* finallyBlock, int startLine, int endLine, VariableEnvironment&& catchEnvironment)
754 {
755 TryNode* result = new (m_parserArena) TryNode(location, tryBlock, catchPattern, catchBlock, WTF::move(catchEnvironment), finallyBlock);
756 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
757 return result;
758 }
759
760 StatementNode* createSwitchStatement(const JSTokenLocation& location, ExpressionNode* expr, ClauseListNode* firstClauses, CaseClauseNode* defaultClause, ClauseListNode* secondClauses, int startLine, int endLine, VariableEnvironment&& lexicalVariables, DeclarationStacks::FunctionStack&& functionStack)
761 {
762 CaseBlockNode* cases = new (m_parserArena) CaseBlockNode(firstClauses, defaultClause, secondClauses);
763 SwitchNode* result = new (m_parserArena) SwitchNode(location, expr, cases, WTF::move(lexicalVariables), WTF::move(functionStack));
764 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
765 return result;
766 }
767
768 StatementNode* createWhileStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, int startLine, int endLine)
769 {
770 WhileNode* result = new (m_parserArena) WhileNode(location, expr, statement);
771 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
772 return result;
773 }
774
775 StatementNode* createDoWhileStatement(const JSTokenLocation& location, StatementNode* statement, ExpressionNode* expr, int startLine, int endLine)
776 {
777 DoWhileNode* result = new (m_parserArena) DoWhileNode(location, statement, expr);
778 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
779 return result;
780 }
781
782 StatementNode* createLabelStatement(const JSTokenLocation& location, const Identifier* ident, StatementNode* statement, const JSTextPosition& start, const JSTextPosition& end)
783 {
784 LabelNode* result = new (m_parserArena) LabelNode(location, *ident, statement);
785 setExceptionLocation(result, start, end, end);
786 return result;
787 }
788
789 StatementNode* createWithStatement(const JSTokenLocation& location, ExpressionNode* expr, StatementNode* statement, unsigned start, const JSTextPosition& end, unsigned startLine, unsigned endLine)
790 {
791 usesWith();
792 WithNode* result = new (m_parserArena) WithNode(location, expr, statement, end, end - start);
793 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
794 return result;
795 }
796
797 StatementNode* createThrowStatement(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& end)
798 {
799 ThrowNode* result = new (m_parserArena) ThrowNode(location, expr);
800 result->setLoc(start.line, end.line, start.offset, start.lineStartOffset);
801 setExceptionLocation(result, start, end, end);
802 return result;
803 }
804
805 StatementNode* createDebugger(const JSTokenLocation& location, int startLine, int endLine)
806 {
807 DebuggerStatementNode* result = new (m_parserArena) DebuggerStatementNode(location);
808 result->setLoc(startLine, endLine, location.startOffset, location.lineStartOffset);
809 return result;
810 }
811
812 ModuleNameNode* createModuleName(const JSTokenLocation& location, const Identifier& moduleName)
813 {
814 return new (m_parserArena) ModuleNameNode(location, moduleName);
815 }
816
817 ImportSpecifierNode* createImportSpecifier(const JSTokenLocation& location, const Identifier& importedName, const Identifier& localName)
818 {
819 return new (m_parserArena) ImportSpecifierNode(location, importedName, localName);
820 }
821
822 ImportSpecifierListNode* createImportSpecifierList()
823 {
824 return new (m_parserArena) ImportSpecifierListNode();
825 }
826
827 void appendImportSpecifier(ImportSpecifierListNode* specifierList, ImportSpecifierNode* specifier)
828 {
829 specifierList->append(specifier);
830 }
831
832 ImportAttributesListNode* createImportAttributesList()
833 {
834 return new (m_parserArena) ImportAttributesListNode();
835 }
836
837 void appendImportAttribute(ImportAttributesListNode* attributesList, const Identifier& key, const Identifier& value)
838 {
839 attributesList->append(key, value);
840 }
841
842 StatementNode* createImportDeclaration(const JSTokenLocation& location, ImportDeclarationNode::ImportType type, ImportSpecifierListNode* importSpecifierList, ModuleNameNode* moduleName, ImportAttributesListNode* importAttributesList)
843 {
844 return new (m_parserArena) ImportDeclarationNode(location, type, importSpecifierList, moduleName, importAttributesList);
845 }
846
847 StatementNode* createExportAllDeclaration(const JSTokenLocation& location, ModuleNameNode* moduleName, ImportAttributesListNode* importAttributesList)
848 {
849 return new (m_parserArena) ExportAllDeclarationNode(location, moduleName, importAttributesList);
850 }
851
852 StatementNode* createExportDefaultDeclaration(const JSTokenLocation& location, StatementNode* declaration, const Identifier& localName)
853 {
854 return new (m_parserArena) ExportDefaultDeclarationNode(location, declaration, localName);
855 }
856
857 StatementNode* createExportLocalDeclaration(const JSTokenLocation& location, StatementNode* declaration)
858 {
859 return new (m_parserArena) ExportLocalDeclarationNode(location, declaration);
860 }
861
862 StatementNode* createExportNamedDeclaration(const JSTokenLocation& location, ExportSpecifierListNode* exportSpecifierList, ModuleNameNode* moduleName, ImportAttributesListNode* importAttributesList)
863 {
864 return new (m_parserArena) ExportNamedDeclarationNode(location, exportSpecifierList, moduleName, importAttributesList);
865 }
866
867 ExportSpecifierNode* createExportSpecifier(const JSTokenLocation& location, const Identifier& localName, const Identifier& exportedName)
868 {
869 return new (m_parserArena) ExportSpecifierNode(location, localName, exportedName);
870 }
871
872 ExportSpecifierListNode* createExportSpecifierList()
873 {
874 return new (m_parserArena) ExportSpecifierListNode();
875 }
876
877 void appendExportSpecifier(ExportSpecifierListNode* specifierList, ExportSpecifierNode* specifier)
878 {
879 specifierList->append(specifier);
880 }
881
882 void appendStatement(JSC::SourceElements* elements, JSC::StatementNode* statement)
883 {
884 elements->append(statement);
885 }
886
887 CommaNode* createCommaExpr(const JSTokenLocation& location, ExpressionNode* node)
888 {
889 return new (m_parserArena) CommaNode(location, node);
890 }
891
892 CommaNode* appendToCommaExpr(const JSTokenLocation& location, ExpressionNode* tail, ExpressionNode* next)
893 {
894 ASSERT(tail->isCommaNode())((void)0);
895 ASSERT(next)((void)0);
896 CommaNode* newTail = new (m_parserArena) CommaNode(location, next);
897 static_cast<CommaNode*>(tail)->setNext(newTail);
898 return newTail;
899 }
900
901 int evalCount() const { return m_evalCount; }
902
903 void appendBinaryExpressionInfo(int& operandStackDepth, ExpressionNode* current, const JSTextPosition& exprStart, const JSTextPosition& lhs, const JSTextPosition& rhs, bool hasAssignments)
904 {
905 operandStackDepth++;
906 m_binaryOperandStack.append(std::make_pair(current, BinaryOpInfo(exprStart, lhs, rhs, hasAssignments)));
907 }
908
909 // Logic to handle datastructures used during parsing of binary expressions
910 void operatorStackPop(int& operatorStackDepth)
911 {
912 operatorStackDepth--;
913 m_binaryOperatorStack.removeLast();
914 }
915 bool operatorStackShouldReduce(int precedence)
916 {
917 // If the current precedence of the operator stack is the same to the one of the given operator,
918 // it depends on the associative whether we reduce the stack.
919 // If the operator is right associative, we should not reduce the stack right now.
920 if (precedence == m_binaryOperatorStack.last().second)
921 return !(m_binaryOperatorStack.last().first & RightAssociativeBinaryOpTokenFlag);
922 return precedence < m_binaryOperatorStack.last().second;
923 }
924 const BinaryOperand& getFromOperandStack(int i) { return m_binaryOperandStack[m_binaryOperandStack.size() + i]; }
925 void shrinkOperandStackBy(int& operandStackDepth, int amount)
926 {
927 operandStackDepth -= amount;
928 ASSERT(operandStackDepth >= 0)((void)0);
929 m_binaryOperandStack.shrink(m_binaryOperandStack.size() - amount);
930 }
931 void appendBinaryOperation(const JSTokenLocation& location, int& operandStackDepth, int&, const BinaryOperand& lhs, const BinaryOperand& rhs)
932 {
933 operandStackDepth++;
934 m_binaryOperandStack.append(std::make_pair(makeBinaryNode(location, m_binaryOperatorStack.last().first, lhs, rhs), BinaryOpInfo(lhs.second, rhs.second)));
935 }
936 void operatorStackAppend(int& operatorStackDepth, int op, int precedence)
937 {
938 operatorStackDepth++;
939 m_binaryOperatorStack.append(std::make_pair(op, precedence));
940 }
941 ExpressionNode* popOperandStack(int&)
942 {
943 ExpressionNode* result = m_binaryOperandStack.last().first;
944 m_binaryOperandStack.removeLast();
945 return result;
946 }
947
948 void appendUnaryToken(int& tokenStackDepth, int type, const JSTextPosition& start)
949 {
950 tokenStackDepth++;
951 m_unaryTokenStack.append(std::make_pair(type, start));
952 }
953
954 int unaryTokenStackLastType(int&)
955 {
956 return m_unaryTokenStack.last().first;
957 }
958
959 const JSTextPosition& unaryTokenStackLastStart(int&)
960 {
961 return m_unaryTokenStack.last().second;
962 }
963
964 void unaryTokenStackRemoveLast(int& tokenStackDepth)
965 {
966 tokenStackDepth--;
967 m_unaryTokenStack.removeLast();
968 }
969
970 int unaryTokenStackDepth() const
971 {
972 return m_unaryTokenStack.size();
973 }
974
975 void setUnaryTokenStackDepth(int oldDepth)
976 {
977 m_unaryTokenStack.shrink(oldDepth);
978 }
979
980 void assignmentStackAppend(int& assignmentStackDepth, ExpressionNode* node, const JSTextPosition& start, const JSTextPosition& divot, int assignmentCount, Operator op)
981 {
982 assignmentStackDepth++;
983 ASSERT(start.offset >= start.lineStartOffset)((void)0);
984 ASSERT(divot.offset >= divot.lineStartOffset)((void)0);
985 m_assignmentInfoStack.append(AssignmentInfo(node, start, divot, assignmentCount, op));
986 }
987
988 ExpressionNode* createAssignment(const JSTokenLocation& location, int& assignmentStackDepth, ExpressionNode* rhs, int initialAssignmentCount, int currentAssignmentCount, const JSTextPosition& lastTokenEnd)
989 {
990 AssignmentInfo& info = m_assignmentInfoStack.last();
991 checkArgumentsLengthModification(info.m_node);
992 ExpressionNode* result = makeAssignNode(location, info.m_node, info.m_op, rhs, info.m_initAssignments != initialAssignmentCount, info.m_initAssignments != currentAssignmentCount, info.m_start, info.m_divot + 1, lastTokenEnd);
993 m_assignmentInfoStack.removeLast();
994 assignmentStackDepth--;
995 return result;
996 }
997
998 PropertyNode::Type getType(const Property& property) const { return property->type(); }
999 bool isUnderscoreProtoSetter(const Property& property) const { return PropertyNode::isUnderscoreProtoSetter(m_vm, *property); }
1000 bool isResolve(ExpressionNode* expr) const { return expr->isResolveNode(); }
1001
1002 ExpressionNode* createDestructuringAssignment(const JSTokenLocation& location, DestructuringPattern pattern, ExpressionNode* initializer)
1003 {
1004 return new (m_parserArena) DestructuringAssignmentNode(location, pattern, initializer);
1005 }
1006
1007 ArrayPattern createArrayPattern(const JSTokenLocation&)
1008 {
1009 return new (m_parserArena) ArrayPatternNode();
1010 }
1011
1012 void appendArrayPatternSkipEntry(ArrayPattern node, const JSTokenLocation& location)
1013 {
1014 node->appendIndex(ArrayPatternNode::BindingType::Elision, location, nullptr, nullptr);
1015 }
1016
1017 void appendArrayPatternEntry(ArrayPattern node, const JSTokenLocation& location, DestructuringPattern pattern, ExpressionNode* defaultValue)
1018 {
1019 node->appendIndex(ArrayPatternNode::BindingType::Element, location, pattern, defaultValue);
1020 tryInferNameInPattern(pattern, defaultValue);
1021 }
1022
1023 void appendArrayPatternRestEntry(ArrayPattern node, const JSTokenLocation& location, DestructuringPattern pattern)
1024 {
1025 node->appendIndex(ArrayPatternNode::BindingType::RestElement, location, pattern, nullptr);
1026 }
1027
1028 void finishArrayPattern(ArrayPattern node, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
1029 {
1030 setExceptionLocation(node, divotStart, divot, divotEnd);
1031 }
1032
1033 ObjectPattern createObjectPattern(const JSTokenLocation&)
1034 {
1035 return new (m_parserArena) ObjectPatternNode();
1036 }
1037
1038 void appendObjectPatternEntry(ObjectPattern node, const JSTokenLocation& location, bool wasString, const Identifier& identifier, DestructuringPattern pattern, ExpressionNode* defaultValue)
1039 {
1040 node->appendEntry(location, identifier, wasString, pattern, defaultValue, ObjectPatternNode::BindingType::Element);
1041 tryInferNameInPattern(pattern, defaultValue);
1042 }
1043
1044 void appendObjectPatternEntry(VM& vm, ObjectPattern node, const JSTokenLocation& location, ExpressionNode* propertyExpression, DestructuringPattern pattern, ExpressionNode* defaultValue)
1045 {
1046 node->appendEntry(vm, location, propertyExpression, pattern, defaultValue, ObjectPatternNode::BindingType::Element);
1047 tryInferNameInPattern(pattern, defaultValue);
1048 }
1049
1050 void appendObjectPatternRestEntry(VM& vm, ObjectPattern node, const JSTokenLocation& location, DestructuringPattern pattern)
1051 {
1052 node->appendEntry(vm, location, nullptr, pattern, nullptr, ObjectPatternNode::BindingType::RestElement);
1053 }
1054
1055 void setContainsObjectRestElement(ObjectPattern node, bool containsRestElement)
1056 {
1057 node->setContainsRestElement(containsRestElement);
1058 }
1059
1060 void setContainsComputedProperty(ObjectPattern node, bool containsComputedProperty)
1061 {
1062 node->setContainsComputedProperty(containsComputedProperty);
1063 }
1064
1065 void finishObjectPattern(ObjectPattern node, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
1066 {
1067 setExceptionLocation(node, divotStart, divot, divotEnd);
1068 }
1069
1070 BindingPattern createBindingLocation(const JSTokenLocation&, const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end, AssignmentContext context)
1071 {
1072 if (context == AssignmentContext::AwaitUsingDeclarationStatement)
1073 usesAwait();
1074 return new (m_parserArena) BindingNode(boundProperty, start, end, context);
1075 }
1076
1077 RestParameterNode* createRestParameter(DestructuringPatternNode* pattern, size_t numParametersToSkip)
1078 {
1079 return new (m_parserArena) RestParameterNode(pattern, numParametersToSkip);
1080 }
1081
1082 AssignmentElement createAssignmentElement(const Expression& assignmentTarget, const JSTextPosition& start, const JSTextPosition& end)
1083 {
1084 checkArgumentsLengthModification(assignmentTarget);
1085 return new (m_parserArena) AssignmentElementNode(assignmentTarget, start, end);
1086 }
1087
1088 void setEndOffset(Node* node, int offset)
1089 {
1090 node->setEndOffset(offset);
1091 }
1092
1093 int endOffset(Node* node)
1094 {
1095 return node->endOffset();
1096 }
1097
1098 void setStartOffset(CaseClauseNode* node, int offset)
1099 {
1100 node->setStartOffset(offset);
1101 }
1102
1103 void setStartOffset(Node* node, int offset)
1104 {
1105 node->setStartOffset(offset);
1106 }
1107
1108 JSTextPosition breakpointLocation(Node* node)
1109 {
1110 node->setNeedsDebugHook();
1111 return node->position();
1112 }
1113
1114 void propagateArgumentsUse() { usesArguments(); }
1115
1116 bool hasArgumentsFeature() const { return m_scope.m_features & ArgumentsFeature; }
1117
1118private:
1119 struct Scope {
1120 Scope()
1121 : m_features(0)
1122 , m_numConstants(0)
1123 {
1124 }
1125 int m_features;
1126 int m_numConstants;
1127 };
1128
1129 void checkArgumentsLengthModification(const ExpressionNode* node)
1130 {
1131 // Since we exclude pattern `arguments.length` to enable ArgumentsFeature,
1132 // we need re-enable ArgumentsFeature for `arguments.length` modification.
1133 if (node && node->isArgumentsLengthAccess(m_vm))
1134 usesArguments();
1135 }
1136
1137 static void setExceptionLocation(ThrowableExpressionData* node, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd)
1138 {
1139 ASSERT(divot && divotStart && divotEnd)((void)0);
1140 ASSERT(divot.offset >= divot.lineStartOffset)((void)0);
1141 node->setExceptionSourceCode(divot, divotStart, divotEnd);
1142 }
1143
1144 void incConstants() { m_scope.m_numConstants++; }
1145 void usesThis() { m_scope.m_features |= ThisFeature; }
1146 void usesArrowFunction() { m_scope.m_features |= ArrowFunctionFeature; }
1147 void usesArguments() { m_scope.m_features |= ArgumentsFeature; }
1148 void usesWith() { m_scope.m_features |= WithFeature; }
1149 void usesSuperCall() { m_scope.m_features |= SuperCallFeature; }
1150 void usesSuperProperty() { m_scope.m_features |= SuperPropertyFeature; }
1151 void usesEval()
1152 {
1153 m_evalCount++;
1154 m_scope.m_features |= EvalFeature;
1155 }
1156 void usesNewTarget() { m_scope.m_features |= NewTargetFeature; }
1157 void usesAwait() { m_scope.m_features |= AwaitFeature; }
1158 ExpressionNode* createIntegerLikeNumber(const JSTokenLocation& location, double d)
1159 {
1160 return new (m_parserArena) IntegerNode(location, d);
1161 }
1162 ExpressionNode* createDoubleLikeNumber(const JSTokenLocation& location, double d)
1163 {
1164 return new (m_parserArena) DoubleNode(location, d);
1165 }
1166 ExpressionNode* createBigIntWithSign(const JSTokenLocation& location, const Identifier& bigInt, uint8_t radix, bool sign)
1167 {
1168 return new (m_parserArena) BigIntNode(location, bigInt, radix, sign);
1169 }
1170 ExpressionNode* createNumberFromBinaryOperation(const JSTokenLocation& location, double value, const NumberNode& originalNodeA, const NumberNode& originalNodeB)
1171 {
1172 if (originalNodeA.isIntegerNode() && originalNodeB.isIntegerNode())
1173 return createIntegerLikeNumber(location, value);
1174 return createDoubleLikeNumber(location, value);
1175 }
1176 ExpressionNode* createNumberFromUnaryOperation(const JSTokenLocation& location, double value, const NumberNode& originalNode)
1177 {
1178 if (originalNode.isIntegerNode())
1179 return createIntegerLikeNumber(location, value);
1180 return createDoubleLikeNumber(location, value);
1181 }
1182 ExpressionNode* createBigIntFromUnaryOperation(const JSTokenLocation& location, bool sign, const BigIntNode& originalNode)
1183 {
1184 return createBigIntWithSign(location, originalNode.identifier(), originalNode.radix(), sign);
1185 }
1186
1187 void tryInferNameInPattern(DestructuringPattern pattern, ExpressionNode* defaultValue)
1188 {
1189 if (!defaultValue)
1190 return;
1191
1192 if (pattern->isBindingNode()) {
1193 const Identifier& ident = static_cast<BindingNode*>(pattern)->boundProperty();
1194 tryInferNameInPatternWithIdentifier(ident, defaultValue);
1195 } else if (pattern->isAssignmentElementNode()) {
1196 const ExpressionNode* assignmentTarget = static_cast<AssignmentElementNode*>(pattern)->assignmentTarget();
1197 if (assignmentTarget->isResolveNode()) {
1198 const Identifier& ident = static_cast<const ResolveNode*>(assignmentTarget)->identifier();
1199 tryInferNameInPatternWithIdentifier(ident, defaultValue);
1200 }
1201 }
1202 }
1203
1204 void tryInferNameInPatternWithIdentifier(const Identifier& ident, ExpressionNode* defaultValue)
1205 {
1206 if (defaultValue->isBaseFuncExprNode()) {
1207 auto metadata = static_cast<BaseFuncExprNode*>(defaultValue)->metadata();
1208 metadata->setEcmaName(ident);
1209 } else if (defaultValue->isClassExprNode())
1210 static_cast<ClassExprNode*>(defaultValue)->setEcmaName(ident);
1211 }
1212
1213 VM& m_vm;
1214 ParserArena& m_parserArena;
Member variable 'm_parserArena' in 'JSC::ASTBuilder' is a reference to ref-countable type 'JSC::ParserArena'; member variables must be Ref, RefPtr, WeakRef, or WeakPtr
1215 SourceCode* m_sourceCode;
1216 Scope m_scope;
1217 Vector<BinaryOperand, 10, UnsafeVectorOverflow> m_binaryOperandStack;
1218 Vector<AssignmentInfo, 10, UnsafeVectorOverflow> m_assignmentInfoStack;
1219 Vector<std::pair<int, int>, 10, UnsafeVectorOverflow> m_binaryOperatorStack;
1220 Vector<std::pair<int, JSTextPosition>, 10, UnsafeVectorOverflow> m_unaryTokenStack;
1221 int m_evalCount;
1222};
1223
1224ExpressionNode* ASTBuilder::makeTypeOfNode(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1225{
1226 if (expr->isResolveNode()) {
1227 ResolveNode* resolve = static_cast<ResolveNode*>(expr);
1228 return new (m_parserArena) TypeOfResolveNode(location, resolve->identifier(), start, divot, end);
1229 }
1230 return new (m_parserArena) TypeOfValueNode(location, expr);
1231}
1232
1233ExpressionNode* ASTBuilder::makeDeleteNode(const JSTokenLocation& location, ExpressionNode* expr, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1234{
1235 if (expr->isOptionalChain()) {
1236 OptionalChainNode* optionalChain = static_cast<OptionalChainNode*>(expr);
1237 if (optionalChain->expr()->isLocation()) {
1238 ASSERT(!optionalChain->expr()->isResolveNode())((void)0);
1239 optionalChain->setExpr(makeDeleteNode(location, optionalChain->expr(), start, divot, end));
1240 return optionalChain;
1241 }
1242 }
1243
1244 if (!expr->isLocation())
1245 return new (m_parserArena) DeleteValueNode(location, expr);
1246 if (expr->isResolveNode()) {
1247 ResolveNode* resolve = static_cast<ResolveNode*>(expr);
1248 return new (m_parserArena) DeleteResolveNode(location, resolve->identifier(), divot, start, end);
1249 }
1250 if (expr->isBracketAccessorNode()) {
1251 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(expr);
1252 return new (m_parserArena) DeleteBracketNode(location, bracket->base(), bracket->subscript(), divot, start, end);
1253 }
1254 ASSERT(expr->isDotAccessorNode())((void)0);
1255 checkArgumentsLengthModification(expr);
1256 DotAccessorNode* dot = static_cast<DotAccessorNode*>(expr);
1257 return new (m_parserArena) DeleteDotNode(location, dot->base(), dot->identifier(), divot, start, end);
1258}
1259
1260ExpressionNode* ASTBuilder::makeNegateNode(const JSTokenLocation& location, ExpressionNode* n)
1261{
1262 if (n->isNumber()) {
1263 const NumberNode& numberNode = static_cast<const NumberNode&>(*n);
1264 return createNumberFromUnaryOperation(location, -numberNode.value(), numberNode);
1265 }
1266
1267 if (n->isBigInt()) {
1268 const BigIntNode& bigIntNode = static_cast<const BigIntNode&>(*n);
1269 return createBigIntFromUnaryOperation(location, !bigIntNode.sign(), bigIntNode);
1270 }
1271
1272 return new (m_parserArena) NegateNode(location, n);
1273}
1274
1275ExpressionNode* ASTBuilder::makeBitwiseNotNode(const JSTokenLocation& location, ExpressionNode* expr)
1276{
1277 if (expr->isNumber())
1278 return createIntegerLikeNumber(location, ~toInt32(static_cast<NumberNode*>(expr)->value()));
1279 return new (m_parserArena) BitwiseNotNode(location, expr);
1280}
1281
1282ExpressionNode* ASTBuilder::makePowNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1283{
1284 auto* strippedExpr1 = expr1->stripUnaryPlus();
1285 auto* strippedExpr2 = expr2->stripUnaryPlus();
1286
1287 if (strippedExpr1->isNumber() && strippedExpr2->isNumber()) {
1288 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*strippedExpr1);
1289 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*strippedExpr2);
1290 return createNumberFromBinaryOperation(location, operationMathPow(numberExpr1.value(), numberExpr2.value()), numberExpr1, numberExpr2);
1291 }
1292
1293 if (strippedExpr1->isNumber())
1294 expr1 = strippedExpr1;
1295 if (strippedExpr2->isNumber())
1296 expr2 = strippedExpr2;
1297
1298 return new (m_parserArena) PowNode(location, expr1, expr2, rightHasAssignments);
1299}
1300
1301ExpressionNode* ASTBuilder::makeMultNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1302{
1303 // FIXME: Unary + change the evaluation order.
1304 // https://bugs.webkit.org/show_bug.cgi?id=159968
1305 expr1 = expr1->stripUnaryPlus();
1306 expr2 = expr2->stripUnaryPlus();
1307
1308 if (expr1->isNumber() && expr2->isNumber()) {
1309 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1310 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1311 return createNumberFromBinaryOperation(location, numberExpr1.value() * numberExpr2.value(), numberExpr1, numberExpr2);
1312 }
1313
1314 if (expr1->isNumber() && static_cast<NumberNode*>(expr1)->value() == 1)
1315 return new (m_parserArena) UnaryPlusNode(location, expr2);
1316
1317 if (expr2->isNumber() && static_cast<NumberNode*>(expr2)->value() == 1)
1318 return new (m_parserArena) UnaryPlusNode(location, expr1);
1319
1320 return new (m_parserArena) MultNode(location, expr1, expr2, rightHasAssignments);
1321}
1322
1323ExpressionNode* ASTBuilder::makeDivNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1324{
1325 // FIXME: Unary + change the evaluation order.
1326 // https://bugs.webkit.org/show_bug.cgi?id=159968
1327 expr1 = expr1->stripUnaryPlus();
1328 expr2 = expr2->stripUnaryPlus();
1329
1330 if (expr1->isNumber() && expr2->isNumber()) {
1331 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1332 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1333 double result = numberExpr1.value() / numberExpr2.value();
1334 if (static_cast<int64_t>(result) == result)
1335 return createNumberFromBinaryOperation(location, result, numberExpr1, numberExpr2);
1336 return createDoubleLikeNumber(location, result);
1337 }
1338 return new (m_parserArena) DivNode(location, expr1, expr2, rightHasAssignments);
1339}
1340
1341ExpressionNode* ASTBuilder::makeModNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1342{
1343 // FIXME: Unary + change the evaluation order.
1344 // https://bugs.webkit.org/show_bug.cgi?id=159968
1345 expr1 = expr1->stripUnaryPlus();
1346 expr2 = expr2->stripUnaryPlus();
1347
1348 if (expr1->isNumber() && expr2->isNumber()) {
1349 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1350 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1351 return createIntegerLikeNumber(location, fmod(numberExpr1.value(), numberExpr2.value()));
1352 }
1353 return new (m_parserArena) ModNode(location, expr1, expr2, rightHasAssignments);
1354}
1355
1356ExpressionNode* ASTBuilder::makeAddNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1357{
1358
1359 if (expr1->isNumber() && expr2->isNumber()) {
1360 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1361 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1362 return createNumberFromBinaryOperation(location, numberExpr1.value() + numberExpr2.value(), numberExpr1, numberExpr2);
1363 }
1364 return new (m_parserArena) AddNode(location, expr1, expr2, rightHasAssignments);
1365}
1366
1367ExpressionNode* ASTBuilder::makeSubNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1368{
1369 // FIXME: Unary + change the evaluation order.
1370 // https://bugs.webkit.org/show_bug.cgi?id=159968
1371 expr1 = expr1->stripUnaryPlus();
1372 expr2 = expr2->stripUnaryPlus();
1373
1374 if (expr1->isNumber() && expr2->isNumber()) {
1375 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1376 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1377 return createNumberFromBinaryOperation(location, numberExpr1.value() - numberExpr2.value(), numberExpr1, numberExpr2);
1378 }
1379 return new (m_parserArena) SubNode(location, expr1, expr2, rightHasAssignments);
1380}
1381
1382ExpressionNode* ASTBuilder::makeLeftShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1383{
1384 if (expr1->isNumber() && expr2->isNumber()) {
1385 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1386 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1387 return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) << (toUInt32(numberExpr2.value()) & 0x1f));
1388 }
1389 return new (m_parserArena) LeftShiftNode(location, expr1, expr2, rightHasAssignments);
1390}
1391
1392ExpressionNode* ASTBuilder::makeRightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1393{
1394 if (expr1->isNumber() && expr2->isNumber()) {
1395 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1396 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1397 return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) >> (toUInt32(numberExpr2.value()) & 0x1f));
1398 }
1399 return new (m_parserArena) RightShiftNode(location, expr1, expr2, rightHasAssignments);
1400}
1401
1402ExpressionNode* ASTBuilder::makeURightShiftNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1403{
1404 if (expr1->isNumber() && expr2->isNumber()) {
1405 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1406 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1407 return createIntegerLikeNumber(location, toUInt32(numberExpr1.value()) >> (toUInt32(numberExpr2.value()) & 0x1f));
1408 }
1409 return new (m_parserArena) UnsignedRightShiftNode(location, expr1, expr2, rightHasAssignments);
1410}
1411
1412ExpressionNode* ASTBuilder::makeBitOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1413{
1414 if (expr1->isNumber() && expr2->isNumber()) {
1415 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1416 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1417 return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) | toInt32(numberExpr2.value()));
1418 }
1419 return new (m_parserArena) BitOrNode(location, expr1, expr2, rightHasAssignments);
1420}
1421
1422ExpressionNode* ASTBuilder::makeBitAndNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1423{
1424 if (expr1->isNumber() && expr2->isNumber()) {
1425 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1426 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1427 return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) & toInt32(numberExpr2.value()));
1428 }
1429 return new (m_parserArena) BitAndNode(location, expr1, expr2, rightHasAssignments);
1430}
1431
1432ExpressionNode* ASTBuilder::makeBitXOrNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments)
1433{
1434 if (expr1->isNumber() && expr2->isNumber()) {
1435 const NumberNode& numberExpr1 = static_cast<NumberNode&>(*expr1);
1436 const NumberNode& numberExpr2 = static_cast<NumberNode&>(*expr2);
1437 return createIntegerLikeNumber(location, toInt32(numberExpr1.value()) ^ toInt32(numberExpr2.value()));
1438 }
1439 return new (m_parserArena) BitXOrNode(location, expr1, expr2, rightHasAssignments);
1440}
1441
1442ExpressionNode* ASTBuilder::makeCoalesceNode(const JSTokenLocation& location, ExpressionNode* expr1, ExpressionNode* expr2)
1443{
1444 // Optimization for `x?.y ?? z`.
1445 if (expr1->isOptionalChain()) {
1446 OptionalChainNode* optionalChain = static_cast<OptionalChainNode*>(expr1);
1447 if (!optionalChain->expr()->isDeleteNode()) {
1448 constexpr bool hasAbsorbedOptionalChain = true;
1449 return new (m_parserArena) CoalesceNode(location, optionalChain->expr(), expr2, hasAbsorbedOptionalChain);
1450 }
1451 }
1452 constexpr bool hasAbsorbedOptionalChain = false;
1453 return new (m_parserArena) CoalesceNode(location, expr1, expr2, hasAbsorbedOptionalChain);
1454}
1455
1456ExpressionNode* ASTBuilder::makeStaticBlockFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
1457{
1458 return new (m_parserArena) StaticBlockFunctionCallNode(location, func, divot, divotStart, divotEnd);
1459}
1460
1461ExpressionNode* ASTBuilder::makeFunctionCallNode(const JSTokenLocation& location, ExpressionNode* func, bool previousBaseWasSuper, ArgumentsNode* args, const JSTextPosition& divotStart, const JSTextPosition& divot, const JSTextPosition& divotEnd, size_t callOrApplyChildDepth, bool isOptionalCall)
1462{
1463 ASSERT(divot.offset >= divot.lineStartOffset)((void)0);
1464 if (func->isSuperNode())
1465 usesSuperCall();
1466
1467 if (func->isBytecodeIntrinsicNode()) {
1468 ASSERT(!isOptionalCall)((void)0);
1469 BytecodeIntrinsicNode* intrinsic = static_cast<BytecodeIntrinsicNode*>(func);
1470 if (intrinsic->type() == BytecodeIntrinsicNode::Type::Constant && intrinsic->entry().type() == BytecodeIntrinsicRegistry::Type::Emitter)
1471 return new (m_parserArena) BytecodeIntrinsicNode(BytecodeIntrinsicNode::Type::Function, location, intrinsic->entry(), intrinsic->identifier(), args, divot, divotStart, divotEnd);
1472 }
1473
1474 if (func->isOptionalChain()) {
1475 OptionalChainNode* optionalChain = static_cast<OptionalChainNode*>(func);
1476 if (optionalChain->expr()->isLocation()) {
1477 ASSERT(!optionalChain->expr()->isResolveNode())((void)0);
1478 // We must take care to preserve our `this` value in cases like `a?.b?.()` and `(a?.b)()`, respectively.
1479 if (isOptionalCall)
1480 return makeFunctionCallNode(location, optionalChain->expr(), previousBaseWasSuper, args, divotStart, divot, divotEnd, callOrApplyChildDepth, isOptionalCall);
1481 optionalChain->setExpr(makeFunctionCallNode(location, optionalChain->expr(), previousBaseWasSuper, args, divotStart, divot, divotEnd, callOrApplyChildDepth, isOptionalCall));
1482 return optionalChain;
1483 }
1484 }
1485
1486 if (!func->isLocation())
1487 return new (m_parserArena) FunctionCallValueNode(location, func, args, divot, divotStart, divotEnd, isOptionalCall);
1488 if (func->isResolveNode()) {
1489 ResolveNode* resolve = static_cast<ResolveNode*>(func);
1490 const Identifier& identifier = resolve->identifier();
1491 if (identifier == m_vm.propertyNames->eval && !isOptionalCall) {
1492 usesEval();
1493 return new (m_parserArena) EvalFunctionCallNode(location, args, divot, divotStart, divotEnd);
1494 }
1495 return new (m_parserArena) FunctionCallResolveNode(location, identifier, args, divot, divotStart, divotEnd, isOptionalCall);
1496 }
1497 if (func->isBracketAccessorNode()) {
1498 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(func);
1499 FunctionCallBracketNode* node = new (m_parserArena) FunctionCallBracketNode(location, bracket->base(), bracket->subscript(), bracket->subscriptHasAssignments(), args, divot, divotStart, divotEnd, isOptionalCall);
1500 node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset);
1501 return node;
1502 }
1503 ASSERT(func->isDotAccessorNode())((void)0);
1504 DotAccessorNode* dot = static_cast<DotAccessorNode*>(func);
1505 FunctionCallDotNode* node = nullptr;
1506 if (!previousBaseWasSuper && (dot->identifier() == m_vm.propertyNames->builtinNames().callPublicName() || dot->identifier() == m_vm.propertyNames->builtinNames().callPrivateName()))
1507 node = new (m_parserArena) CallFunctionCallDotNode(location, dot->base(), dot->identifier(), dot->type(), args, divot, divotStart, divotEnd, isOptionalCall, callOrApplyChildDepth);
1508 else if (!previousBaseWasSuper && (dot->identifier() == m_vm.propertyNames->builtinNames().applyPublicName() || dot->identifier() == m_vm.propertyNames->builtinNames().applyPrivateName())) {
1509 // FIXME: This check is only needed because we haven't taught the bytecode generator to inline
1510 // Reflect.apply yet. See https://bugs.webkit.org/show_bug.cgi?id=190668.
1511 if (!dot->base()->isResolveNode() || static_cast<ResolveNode*>(dot->base())->identifier() != m_vm.propertyNames->Reflect)
1512 node = new (m_parserArena) ApplyFunctionCallDotNode(location, dot->base(), dot->identifier(), dot->type(), args, divot, divotStart, divotEnd, isOptionalCall, callOrApplyChildDepth);
1513 } else if (!previousBaseWasSuper
1514 && dot->identifier() == m_vm.propertyNames->hasOwnProperty
1515 && args->m_listNode
1516 && args->m_listNode->m_expr
1517 && args->m_listNode->m_expr->isResolveNode()
1518 && !args->m_listNode->m_next
1519 && (dot->base()->isResolveNode() || dot->base()->isThisNode())) {
1520 // We match the AST pattern:
1521 // <resolveNode|thisNode>.hasOwnProperty(<resolveNode>)
1522 // i.e:
1523 // o.hasOwnProperty(p)
1524 node = new (m_parserArena) HasOwnPropertyFunctionCallDotNode(location, dot->base(), dot->identifier(), dot->type(), args, divot, divotStart, divotEnd, isOptionalCall);
1525 }
1526 if (!node)
1527 node = new (m_parserArena) FunctionCallDotNode(location, dot->base(), dot->identifier(), dot->type(), args, divot, divotStart, divotEnd, isOptionalCall);
1528 node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
1529 return node;
1530}
1531
1532ExpressionNode* ASTBuilder::makeBinaryNode(const JSTokenLocation& location, int token, std::pair<ExpressionNode*, BinaryOpInfo> lhs, std::pair<ExpressionNode*, BinaryOpInfo> rhs)
1533{
1534 switch (token) {
1535 case COALESCE:
1536 return makeCoalesceNode(location, lhs.first, rhs.first);
1537
1538 case OR:
1539 return new (m_parserArena) LogicalOpNode(location, lhs.first, rhs.first, LogicalOperator::Or);
1540
1541 case AND:
1542 return new (m_parserArena) LogicalOpNode(location, lhs.first, rhs.first, LogicalOperator::And);
1543
1544 case BITOR:
1545 return makeBitOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1546
1547 case BITXOR:
1548 return makeBitXOrNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1549
1550 case BITAND:
1551 return makeBitAndNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1552
1553 case EQEQ:
1554 return new (m_parserArena) EqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1555
1556 case NE:
1557 return new (m_parserArena) NotEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1558
1559 case STREQ:
1560 return new (m_parserArena) StrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1561
1562 case STRNEQ:
1563 return new (m_parserArena) NotStrictEqualNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1564
1565 case LT:
1566 return new (m_parserArena) LessNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1567
1568 case GT:
1569 return new (m_parserArena) GreaterNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1570
1571 case LE:
1572 return new (m_parserArena) LessEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1573
1574 case GE:
1575 return new (m_parserArena) GreaterEqNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1576
1577 case INSTANCEOF: {
1578 InstanceOfNode* node = new (m_parserArena) InstanceOfNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1579 setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
1580 return node;
1581 }
1582
1583 case INTOKEN: {
1584 InNode* node = new (m_parserArena) InNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1585 setExceptionLocation(node, lhs.second.start, rhs.second.start, rhs.second.end);
1586 return node;
1587 }
1588
1589 case LSHIFT:
1590 return makeLeftShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1591
1592 case RSHIFT:
1593 return makeRightShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1594
1595 case URSHIFT:
1596 return makeURightShiftNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1597
1598 case PLUS:
1599 return makeAddNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1600
1601 case MINUS:
1602 return makeSubNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1603
1604 case TIMES:
1605 return makeMultNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1606
1607 case DIVIDE:
1608 return makeDivNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1609
1610 case MOD:
1611 return makeModNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1612
1613 case POW:
1614 return makePowNode(location, lhs.first, rhs.first, rhs.second.hasAssignment);
1615 }
1616 CRASH()do { __asm__ volatile ("brk #0xc471"); __builtin_unreachable(
); } while (0)
;
1617 return nullptr;
1618}
1619
1620ExpressionNode* ASTBuilder::makeAssignNode(const JSTokenLocation& location, ExpressionNode* loc, Operator op, ExpressionNode* expr, bool locHasAssignments, bool exprHasAssignments, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1621{
1622 if (!loc->isLocation()) {
1623 ASSERT(loc->isFunctionCall())((void)0);
1624 return new (m_parserArena) AssignErrorNode(location, loc, divot, start, end);
1625 }
1626
1627 if (loc->isResolveNode()) {
1628 ResolveNode* resolve = static_cast<ResolveNode*>(loc);
1629
1630 if (op == Operator::Equal) {
1631 if (expr->isBaseFuncExprNode()) {
1632 auto metadata = static_cast<BaseFuncExprNode*>(expr)->metadata();
1633 metadata->setEcmaName(resolve->identifier());
1634 } else if (expr->isClassExprNode())
1635 static_cast<ClassExprNode*>(expr)->setEcmaName(resolve->identifier());
1636 AssignResolveNode* node = new (m_parserArena) AssignResolveNode(location, resolve->identifier(), expr, AssignmentContext::AssignmentExpression);
1637 setExceptionLocation(node, start, divot, end);
1638 return node;
1639 }
1640
1641 if (op == Operator::CoalesceEq || op == Operator::OrEq || op == Operator::AndEq) {
1642 if (expr->isBaseFuncExprNode()) {
1643 auto metadata = static_cast<BaseFuncExprNode*>(expr)->metadata();
1644 metadata->setEcmaName(resolve->identifier());
1645 } else if (expr->isClassExprNode())
1646 static_cast<ClassExprNode*>(expr)->setEcmaName(resolve->identifier());
1647 return new (m_parserArena) ShortCircuitReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, start, end);
1648 }
1649
1650 return new (m_parserArena) ReadModifyResolveNode(location, resolve->identifier(), op, expr, exprHasAssignments, divot, start, end);
1651 }
1652
1653 if (loc->isBracketAccessorNode()) {
1654 BracketAccessorNode* bracket = static_cast<BracketAccessorNode*>(loc);
1655
1656 if (op == Operator::Equal)
1657 return new (m_parserArena) AssignBracketNode(location, bracket->base(), bracket->subscript(), expr, locHasAssignments, exprHasAssignments, bracket->divot(), start, end);
1658
1659 if (op == Operator::CoalesceEq || op == Operator::OrEq || op == Operator::AndEq) {
1660 auto* node = new (m_parserArena) ShortCircuitReadModifyBracketNode(location, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, start, end);
1661 node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset);
1662 return node;
1663 }
1664
1665 ReadModifyBracketNode* node = new (m_parserArena) ReadModifyBracketNode(location, bracket->base(), bracket->subscript(), op, expr, locHasAssignments, exprHasAssignments, divot, start, end);
1666 node->setSubexpressionInfo(bracket->divot(), bracket->divotEnd().offset);
1667 return node;
1668 }
1669
1670 ASSERT(loc->isDotAccessorNode())((void)0);
1671 DotAccessorNode* dot = static_cast<DotAccessorNode*>(loc);
1672
1673 if (op == Operator::Equal)
1674 return new (m_parserArena) AssignDotNode(location, dot->base(), dot->identifier(), dot->type(), expr, exprHasAssignments, dot->divot(), start, end);
1675
1676 if (op == Operator::CoalesceEq || op == Operator::OrEq || op == Operator::AndEq) {
1677 auto* node = new (m_parserArena) ShortCircuitReadModifyDotNode(location, dot->base(), dot->identifier(), dot->type(), op, expr, exprHasAssignments, divot, start, end);
1678 node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
1679 return node;
1680 }
1681
1682 ReadModifyDotNode* node = new (m_parserArena) ReadModifyDotNode(location, dot->base(), dot->identifier(), dot->type(), op, expr, exprHasAssignments, divot, start, end);
1683 node->setSubexpressionInfo(dot->divot(), dot->divotEnd().offset);
1684 return node;
1685}
1686
1687ExpressionNode* ASTBuilder::makePrefixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1688{
1689 checkArgumentsLengthModification(expr);
1690 return new (m_parserArena) PrefixNode(location, expr, op, divot, start, end);
1691}
1692
1693ExpressionNode* ASTBuilder::makePostfixNode(const JSTokenLocation& location, ExpressionNode* expr, Operator op, const JSTextPosition& start, const JSTextPosition& divot, const JSTextPosition& end)
1694{
1695 checkArgumentsLengthModification(expr);
1696 return new (m_parserArena) PostfixNode(location, expr, op, divot, start, end);
1697}
1698
1699}