Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h
Warning:line 266, column 64
Access to field 'length' results in a dereference of a null pointer (loaded from variable 'data')

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -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=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 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src/frontend -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src/frontend -resource-dir /usr/lib/llvm-18/lib/clang/18 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D WASM_SUPPORTS_HUGE_MEMORY -D JS_CACHEIR_SPEW -D JS_STRUCTURED_SPEW -D JS_HAS_CTYPES -D FFI_BUILDING -D EXPORT_JS_API -D MOZ_HAS_MOZGLUE -D MOZ_SUPPORT_LEAKCHECKING -I /var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src/frontend -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src -I /var/lib/jenkins/workspace/firefox-scan-build/js/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-07-27-022226-2793976-1 -x c++ /var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp

/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp

1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7/*
8 * JS parser.
9 *
10 * This is a recursive-descent parser for the JavaScript language specified by
11 * "The ECMAScript Language Specification" (Standard ECMA-262). It uses
12 * lexical and semantic feedback to disambiguate non-LL(1) structures. It
13 * generates trees of nodes induced by the recursive parsing (not precise
14 * syntax trees, see Parser.h). After tree construction, it rewrites trees to
15 * fold constants and evaluate compile-time expressions.
16 *
17 * This parser attempts no error recovery.
18 */
19
20#include "frontend/Parser.h"
21
22#include "mozilla/ArrayUtils.h"
23#include "mozilla/Assertions.h"
24#include "mozilla/Casting.h"
25#include "mozilla/Range.h"
26#include "mozilla/Sprintf.h"
27#include "mozilla/Try.h" // MOZ_TRY*
28#include "mozilla/Utf8.h"
29#include "mozilla/Variant.h"
30
31#include <memory>
32#include <new>
33#include <type_traits>
34
35#include "jsnum.h"
36#include "jstypes.h"
37
38#include "frontend/FoldConstants.h"
39#include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind
40#include "frontend/ModuleSharedContext.h"
41#include "frontend/ParseNode.h"
42#include "frontend/ParseNodeVerify.h"
43#include "frontend/Parser-macros.h" // MOZ_TRY_VAR_OR_RETURN
44#include "frontend/ParserAtom.h" // TaggedParserAtomIndex, ParserAtomsTable, ParserAtom
45#include "frontend/ScriptIndex.h" // ScriptIndex
46#include "frontend/TokenStream.h" // IsKeyword, ReservedWordTokenKind, ReservedWordToCharZ, DeprecatedContent, *TokenStream*, CharBuffer, TokenKindToDesc
47#include "irregexp/RegExpAPI.h"
48#include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin, JS::ColumnNumberOneOrigin
49#include "js/ErrorReport.h" // JSErrorBase
50#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
51#include "js/HashTable.h"
52#include "js/RegExpFlags.h" // JS::RegExpFlags
53#include "js/Stack.h" // JS::NativeStackLimit
54#include "util/StringBuffer.h" // StringBuffer
55#include "vm/BytecodeUtil.h"
56#include "vm/FunctionFlags.h" // js::FunctionFlags
57#include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind
58#include "vm/JSContext.h"
59#include "vm/JSScript.h"
60#include "vm/ModuleBuilder.h" // js::ModuleBuilder
61#include "vm/Scope.h" // GetScopeDataTrailingNames
62#include "wasm/AsmJS.h"
63
64#include "frontend/ParseContext-inl.h"
65#include "frontend/SharedContext-inl.h"
66
67using namespace js;
68
69using mozilla::AssertedCast;
70using mozilla::AsVariant;
71using mozilla::Maybe;
72using mozilla::Nothing;
73using mozilla::PointerRangeSize;
74using mozilla::Some;
75using mozilla::Utf8Unit;
76
77using JS::ReadOnlyCompileOptions;
78using JS::RegExpFlags;
79
80namespace js::frontend {
81
82using DeclaredNamePtr = ParseContext::Scope::DeclaredNamePtr;
83using AddDeclaredNamePtr = ParseContext::Scope::AddDeclaredNamePtr;
84using BindingIter = ParseContext::Scope::BindingIter;
85using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr;
86
87using ParserBindingNameVector = Vector<ParserBindingName, 6>;
88
89static inline void PropagateTransitiveParseFlags(const FunctionBox* inner,
90 SharedContext* outer) {
91 if (inner->bindingsAccessedDynamically()) {
92 outer->setBindingsAccessedDynamically();
93 }
94 if (inner->hasDirectEval()) {
95 outer->setHasDirectEval();
96 }
97}
98
99static bool StatementKindIsBraced(StatementKind kind) {
100 return kind == StatementKind::Block || kind == StatementKind::Switch ||
101 kind == StatementKind::Try || kind == StatementKind::Catch ||
102 kind == StatementKind::Finally;
103}
104
105template <class ParseHandler, typename Unit>
106inline typename GeneralParser<ParseHandler, Unit>::FinalParser*
107GeneralParser<ParseHandler, Unit>::asFinalParser() {
108 static_assert(
109 std::is_base_of_v<GeneralParser<ParseHandler, Unit>, FinalParser>,
110 "inheritance relationship required by the static_cast<> below");
111
112 return static_cast<FinalParser*>(this);
113}
114
115template <class ParseHandler, typename Unit>
116inline const typename GeneralParser<ParseHandler, Unit>::FinalParser*
117GeneralParser<ParseHandler, Unit>::asFinalParser() const {
118 static_assert(
119 std::is_base_of_v<GeneralParser<ParseHandler, Unit>, FinalParser>,
120 "inheritance relationship required by the static_cast<> below");
121
122 return static_cast<const FinalParser*>(this);
123}
124
125template <class ParseHandler, typename Unit>
126template <typename ConditionT, typename ErrorReportT>
127bool GeneralParser<ParseHandler, Unit>::mustMatchTokenInternal(
128 ConditionT condition, ErrorReportT errorReport) {
129 MOZ_ASSERT(condition(TokenKind::Div) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::Div) == false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(condition(TokenKind::Div) ==
false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("condition(TokenKind::Div) == false", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::Div) == false"
")"); do { *((volatile int*)__null) = 129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
130 MOZ_ASSERT(condition(TokenKind::DivAssign) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::DivAssign) == false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(condition(TokenKind::DivAssign) == false))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("condition(TokenKind::DivAssign) == false"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::DivAssign) == false"
")"); do { *((volatile int*)__null) = 130; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
131 MOZ_ASSERT(condition(TokenKind::RegExp) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::RegExp) == false)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(condition(TokenKind::RegExp) == false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("condition(TokenKind::RegExp) == false"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 131); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::RegExp) == false"
")"); do { *((volatile int*)__null) = 131; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
132
133 TokenKind actual;
134 if (!tokenStream.getToken(&actual, TokenStream::SlashIsInvalid)) {
135 return false;
136 }
137 if (!condition(actual)) {
138 errorReport(actual);
139 return false;
140 }
141 return true;
142}
143
144ParserSharedBase::ParserSharedBase(FrontendContext* fc,
145 CompilationState& compilationState,
146 Kind kind)
147 : fc_(fc),
148 alloc_(compilationState.parserAllocScope.alloc()),
149 compilationState_(compilationState),
150 pc_(nullptr),
151 usedNames_(compilationState.usedNames) {
152 fc_->nameCollectionPool().addActiveCompilation();
153}
154
155ParserSharedBase::~ParserSharedBase() {
156 fc_->nameCollectionPool().removeActiveCompilation();
157}
158
159#if defined(DEBUG1) || defined(JS_JITSPEW1)
160void ParserSharedBase::dumpAtom(TaggedParserAtomIndex index) const {
161 parserAtoms().dump(index);
162}
163#endif
164
165ParserBase::ParserBase(FrontendContext* fc,
166 const ReadOnlyCompileOptions& options,
167 bool foldConstants, CompilationState& compilationState)
168 : ParserSharedBase(fc, compilationState, ParserSharedBase::Kind::Parser),
169 anyChars(fc, options, this),
170 ss(nullptr),
171 foldConstants_(foldConstants),
172#ifdef DEBUG1
173 checkOptionsCalled_(false),
174#endif
175 isUnexpectedEOF_(false),
176 awaitHandling_(AwaitIsName),
177 inParametersOfAsyncFunction_(false) {
178}
179
180bool ParserBase::checkOptions() {
181#ifdef DEBUG1
182 checkOptionsCalled_ = true;
183#endif
184
185 return anyChars.checkOptions();
186}
187
188ParserBase::~ParserBase() { MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 188); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 188; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; }
189
190JSAtom* ParserBase::liftParserAtomToJSAtom(TaggedParserAtomIndex index) {
191 JSContext* cx = fc_->maybeCurrentJSContext();
192 MOZ_ASSERT(cx)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(cx)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(cx))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("cx", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 192); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cx" ")"); do
{ *((volatile int*)__null) = 192; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
193 return parserAtoms().toJSAtom(cx, fc_, index,
194 compilationState_.input.atomCache);
195}
196
197template <class ParseHandler>
198PerHandlerParser<ParseHandler>::PerHandlerParser(
199 FrontendContext* fc, const ReadOnlyCompileOptions& options,
200 bool foldConstants, CompilationState& compilationState,
201 void* internalSyntaxParser)
202 : ParserBase(fc, options, foldConstants, compilationState),
203 handler_(fc, compilationState),
204 internalSyntaxParser_(internalSyntaxParser) {
205 MOZ_ASSERT(compilationState.isInitialStencil() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(compilationState.isInitialStencil() == compilationState
.input.isInitialStencil())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(compilationState.isInitialStencil
() == compilationState.input.isInitialStencil()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 206); AnnotateMozCrashReason("MOZ_ASSERT" "(" "compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
")"); do { *((volatile int*)__null) = 206; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
206 compilationState.input.isInitialStencil())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(compilationState.isInitialStencil() == compilationState
.input.isInitialStencil())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(compilationState.isInitialStencil
() == compilationState.input.isInitialStencil()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 206); AnnotateMozCrashReason("MOZ_ASSERT" "(" "compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
")"); do { *((volatile int*)__null) = 206; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
207}
208
209template <class ParseHandler, typename Unit>
210GeneralParser<ParseHandler, Unit>::GeneralParser(
211 FrontendContext* fc, const ReadOnlyCompileOptions& options,
212 const Unit* units, size_t length, bool foldConstants,
213 CompilationState& compilationState, SyntaxParser* syntaxParser)
214 : Base(fc, options, foldConstants, compilationState, syntaxParser),
215 tokenStream(fc, &compilationState.parserAtoms, options, units, length) {}
216
217template <typename Unit>
218void Parser<SyntaxParseHandler, Unit>::setAwaitHandling(
219 AwaitHandling awaitHandling) {
220 this->awaitHandling_ = awaitHandling;
221}
222
223template <typename Unit>
224void Parser<FullParseHandler, Unit>::setAwaitHandling(
225 AwaitHandling awaitHandling) {
226 this->awaitHandling_ = awaitHandling;
227 if (SyntaxParser* syntaxParser = getSyntaxParser()) {
228 syntaxParser->setAwaitHandling(awaitHandling);
229 }
230}
231
232template <class ParseHandler, typename Unit>
233inline void GeneralParser<ParseHandler, Unit>::setAwaitHandling(
234 AwaitHandling awaitHandling) {
235 asFinalParser()->setAwaitHandling(awaitHandling);
236}
237
238template <typename Unit>
239void Parser<SyntaxParseHandler, Unit>::setInParametersOfAsyncFunction(
240 bool inParameters) {
241 this->inParametersOfAsyncFunction_ = inParameters;
242}
243
244template <typename Unit>
245void Parser<FullParseHandler, Unit>::setInParametersOfAsyncFunction(
246 bool inParameters) {
247 this->inParametersOfAsyncFunction_ = inParameters;
248 if (SyntaxParser* syntaxParser = getSyntaxParser()) {
249 syntaxParser->setInParametersOfAsyncFunction(inParameters);
250 }
251}
252
253template <class ParseHandler, typename Unit>
254inline void GeneralParser<ParseHandler, Unit>::setInParametersOfAsyncFunction(
255 bool inParameters) {
256 asFinalParser()->setInParametersOfAsyncFunction(inParameters);
257}
258
259template <class ParseHandler>
260FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
261 FunctionNodeType funNode, TaggedParserAtomIndex explicitName,
262 FunctionFlags flags, uint32_t toStringStart, Directives inheritedDirectives,
263 GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
264 MOZ_ASSERT(funNode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funNode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funNode))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("funNode", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 264); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funNode" ")"
); do { *((volatile int*)__null) = 264; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
265
266 ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
267 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
268 ReportAllocationOverflow(fc_);
269 return nullptr;
270 }
271 if (!compilationState_.appendScriptStencilAndData(fc_)) {
272 return nullptr;
273 }
274
275 bool isInitialStencil = compilationState_.isInitialStencil();
276
277 // This source extent will be further filled in during the remainder of parse.
278 SourceExtent extent;
279 extent.toStringStart = toStringStart;
280
281 FunctionBox* funbox = alloc_.new_<FunctionBox>(
282 fc_, extent, compilationState_, inheritedDirectives, generatorKind,
283 asyncKind, isInitialStencil, explicitName, flags, index);
284 if (!funbox) {
285 ReportOutOfMemory(fc_);
286 return nullptr;
287 }
288
289 handler_.setFunctionBox(funNode, funbox);
290
291 return funbox;
292}
293
294template <class ParseHandler>
295FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
296 FunctionNodeType funNode, const ScriptStencil& cachedScriptData,
297 const ScriptStencilExtra& cachedScriptExtra) {
298 MOZ_ASSERT(funNode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funNode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funNode))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("funNode", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 298); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funNode" ")"
); do { *((volatile int*)__null) = 298; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
299
300 ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
301 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
302 ReportAllocationOverflow(fc_);
303 return nullptr;
304 }
305 if (!compilationState_.appendScriptStencilAndData(fc_)) {
306 return nullptr;
307 }
308
309 FunctionBox* funbox = alloc_.new_<FunctionBox>(
310 fc_, cachedScriptExtra.extent, compilationState_,
311 Directives(/* strict = */ false), cachedScriptExtra.generatorKind(),
312 cachedScriptExtra.asyncKind(), compilationState_.isInitialStencil(),
313 cachedScriptData.functionAtom, cachedScriptData.functionFlags, index);
314 if (!funbox) {
315 ReportOutOfMemory(fc_);
316 return nullptr;
317 }
318
319 handler_.setFunctionBox(funNode, funbox);
320 funbox->initFromScriptStencilExtra(cachedScriptExtra);
321
322 return funbox;
323}
324
325bool ParserBase::setSourceMapInfo() {
326 // If support for source pragmas have been fully disabled, we can skip
327 // processing of all of these values.
328 if (!options().sourcePragmas()) {
329 return true;
330 }
331
332 // Not all clients initialize ss. Can't update info to an object that isn't
333 // there.
334 if (!ss) {
335 return true;
336 }
337
338 if (anyChars.hasDisplayURL()) {
339 if (!ss->setDisplayURL(fc_, anyChars.displayURL())) {
340 return false;
341 }
342 }
343
344 if (anyChars.hasSourceMapURL()) {
345 MOZ_ASSERT(!ss->hasSourceMapURL())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!ss->hasSourceMapURL())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!ss->hasSourceMapURL())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("!ss->hasSourceMapURL()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 345); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!ss->hasSourceMapURL()"
")"); do { *((volatile int*)__null) = 345; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
346 if (!ss->setSourceMapURL(fc_, anyChars.sourceMapURL())) {
347 return false;
348 }
349 }
350
351 /*
352 * Source map URLs passed as a compile option (usually via a HTTP source map
353 * header) override any source map urls passed as comment pragmas.
354 */
355 if (options().sourceMapURL()) {
356 // Warn about the replacement, but use the new one.
357 if (ss->hasSourceMapURL()) {
358 if (!warningNoOffset(JSMSG_ALREADY_HAS_PRAGMA, ss->filename(),
359 "//# sourceMappingURL")) {
360 return false;
361 }
362 }
363
364 if (!ss->setSourceMapURL(fc_, options().sourceMapURL())) {
365 return false;
366 }
367 }
368
369 return true;
370}
371
372/*
373 * Parse a top-level JS script.
374 */
375template <class ParseHandler, typename Unit>
376typename ParseHandler::ListNodeResult
377GeneralParser<ParseHandler, Unit>::parse() {
378 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 378); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 378; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
379
380 SourceExtent extent = SourceExtent::makeGlobalExtent(
381 /* len = */ 0, options().lineno,
382 JS::LimitedColumnNumberOneOrigin::fromUnlimited(
383 JS::ColumnNumberOneOrigin(options().column)));
384 Directives directives(options().forceStrictMode());
385 GlobalSharedContext globalsc(this->fc_, ScopeKind::Global, options(),
386 directives, extent);
387 SourceParseContext globalpc(this, &globalsc, /* newDirectives = */ nullptr);
388 if (!globalpc.init()) {
389 return errorResult();
390 }
391
392 ParseContext::VarScope varScope(this);
393 if (!varScope.init(pc_)) {
394 return errorResult();
395 }
396
397 ListNodeType stmtList;
398 MOZ_TRY_VAR(stmtList, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (stmtList) =
mozTryVarTempResult_.unwrap(); } while (0)
;
399
400 TokenKind tt;
401 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
402 return errorResult();
403 }
404 if (tt != TokenKind::Eof) {
405 error(JSMSG_GARBAGE_AFTER_INPUT, "script", TokenKindToDesc(tt));
406 return errorResult();
407 }
408
409 if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
410 return errorResult();
411 }
412
413 if (foldConstants_) {
414 Node node = stmtList;
415 // Don't constant-fold inside "use asm" code, as this could create a parse
416 // tree that doesn't type-check as asm.js.
417 if (!pc_->useAsmOrInsideUseAsm()) {
418 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
419 return errorResult();
420 }
421 }
422 stmtList = handler_.asListNode(node);
423 }
424
425 return stmtList;
426}
427
428/*
429 * Strict mode forbids introducing new definitions for 'eval', 'arguments',
430 * 'let', 'static', 'yield', or for any strict mode reserved word.
431 */
432bool ParserBase::isValidStrictBinding(TaggedParserAtomIndex name) {
433 TokenKind tt = ReservedWordTokenKind(name);
434 if (tt == TokenKind::Limit) {
435 return name != TaggedParserAtomIndex::WellKnown::eval() &&
436 name != TaggedParserAtomIndex::WellKnown::arguments();
437 }
438 return tt != TokenKind::Let && tt != TokenKind::Static &&
439 tt != TokenKind::Yield && !TokenKindIsStrictReservedWord(tt);
440}
441
442/*
443 * Returns true if all parameter names are valid strict mode binding names and
444 * no duplicate parameter names are present.
445 */
446bool ParserBase::hasValidSimpleStrictParameterNames() {
447 MOZ_ASSERT(pc_->isFunctionBox() &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox() && pc_->functionBox
()->hasSimpleParameterList())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox() &&
pc_->functionBox()->hasSimpleParameterList()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
")"); do { *((volatile int*)__null) = 448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
448 pc_->functionBox()->hasSimpleParameterList())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox() && pc_->functionBox
()->hasSimpleParameterList())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox() &&
pc_->functionBox()->hasSimpleParameterList()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
")"); do { *((volatile int*)__null) = 448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
449
450 if (pc_->functionBox()->hasDuplicateParameters) {
451 return false;
452 }
453
454 for (auto name : pc_->positionalFormalParameterNames()) {
455 MOZ_ASSERT(name)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(name))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("name", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 455); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name" ")"); do
{ *((volatile int*)__null) = 455; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
456 if (!isValidStrictBinding(name)) {
457 return false;
458 }
459 }
460 return true;
461}
462
463template <class ParseHandler, typename Unit>
464void GeneralParser<ParseHandler, Unit>::reportMissingClosing(
465 unsigned errorNumber, unsigned noteNumber, uint32_t openedPos) {
466 auto notes = MakeUnique<JSErrorNotes>();
467 if (!notes) {
468 ReportOutOfMemory(this->fc_);
469 return;
470 }
471
472 uint32_t line;
473 JS::LimitedColumnNumberOneOrigin column;
474 tokenStream.computeLineAndColumn(openedPos, &line, &column);
475
476 const size_t MaxWidth = sizeof("4294967295");
477 char columnNumber[MaxWidth];
478 SprintfLiteral(columnNumber, "%" PRIu32"u", column.oneOriginValue());
479 char lineNumber[MaxWidth];
480 SprintfLiteral(lineNumber, "%" PRIu32"u", line);
481
482 if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
483 JS::ColumnNumberOneOrigin(column), GetErrorMessage,
484 nullptr, noteNumber, lineNumber, columnNumber)) {
485 return;
486 }
487
488 errorWithNotes(std::move(notes), errorNumber);
489}
490
491template <class ParseHandler, typename Unit>
492void GeneralParser<ParseHandler, Unit>::reportRedeclarationHelper(
493 TaggedParserAtomIndex& name, DeclarationKind& prevKind, TokenPos& pos,
494 uint32_t& prevPos, const unsigned& errorNumber,
495 const unsigned& noteErrorNumber) {
496 UniqueChars bytes = this->parserAtoms().toPrintableString(name);
497 if (!bytes) {
498 ReportOutOfMemory(this->fc_);
499 return;
500 }
501
502 if (prevPos == DeclaredNameInfo::npos) {
503 errorAt(pos.begin, errorNumber, DeclarationKindString(prevKind),
504 bytes.get());
505 return;
506 }
507
508 auto notes = MakeUnique<JSErrorNotes>();
509 if (!notes) {
510 ReportOutOfMemory(this->fc_);
511 return;
512 }
513
514 uint32_t line;
515 JS::LimitedColumnNumberOneOrigin column;
516 tokenStream.computeLineAndColumn(prevPos, &line, &column);
517
518 const size_t MaxWidth = sizeof("4294967295");
519 char columnNumber[MaxWidth];
520 SprintfLiteral(columnNumber, "%" PRIu32"u", column.oneOriginValue());
521 char lineNumber[MaxWidth];
522 SprintfLiteral(lineNumber, "%" PRIu32"u", line);
523
524 if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
525 JS::ColumnNumberOneOrigin(column), GetErrorMessage,
526 nullptr, noteErrorNumber, lineNumber,
527 columnNumber)) {
528 return;
529 }
530
531 errorWithNotesAt(std::move(notes), pos.begin, errorNumber,
532 DeclarationKindString(prevKind), bytes.get());
533}
534
535template <class ParseHandler, typename Unit>
536void GeneralParser<ParseHandler, Unit>::reportRedeclaration(
537 TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
538 uint32_t prevPos) {
539 reportRedeclarationHelper(name, prevKind, pos, prevPos, JSMSG_REDECLARED_VAR,
540 JSMSG_PREV_DECLARATION);
541}
542
543template <class ParseHandler, typename Unit>
544void GeneralParser<ParseHandler, Unit>::reportMismatchedPlacement(
545 TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
546 uint32_t prevPos) {
547 reportRedeclarationHelper(name, prevKind, pos, prevPos,
548 JSMSG_MISMATCHED_PLACEMENT, JSMSG_PREV_DECLARATION);
549}
550
551// notePositionalFormalParameter is called for both the arguments of a regular
552// function definition and the arguments specified by the Function
553// constructor.
554//
555// The 'disallowDuplicateParams' bool indicates whether the use of another
556// feature (destructuring or default arguments) disables duplicate arguments.
557// (ECMA-262 requires us to support duplicate parameter names, but, for newer
558// features, we consider the code to have "opted in" to higher standards and
559// forbid duplicates.)
560template <class ParseHandler, typename Unit>
561bool GeneralParser<ParseHandler, Unit>::notePositionalFormalParameter(
562 FunctionNodeType funNode, TaggedParserAtomIndex name, uint32_t beginPos,
563 bool disallowDuplicateParams, bool* duplicatedParam) {
564 if (AddDeclaredNamePtr p =
565 pc_->functionScope().lookupDeclaredNameForAdd(name)) {
566 if (disallowDuplicateParams) {
567 error(JSMSG_BAD_DUP_ARGS);
568 return false;
569 }
570
571 // Strict-mode disallows duplicate args. We may not know whether we are
572 // in strict mode or not (since the function body hasn't been parsed).
573 // In such cases, report will queue up the potential error and return
574 // 'true'.
575 if (pc_->sc()->strict()) {
576 UniqueChars bytes = this->parserAtoms().toPrintableString(name);
577 if (!bytes) {
578 ReportOutOfMemory(this->fc_);
579 return false;
580 }
581 if (!strictModeError(JSMSG_DUPLICATE_FORMAL, bytes.get())) {
582 return false;
583 }
584 }
585
586 *duplicatedParam = true;
587 } else {
588 DeclarationKind kind = DeclarationKind::PositionalFormalParameter;
589 if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, beginPos)) {
590 return false;
591 }
592 }
593
594 if (!pc_->positionalFormalParameterNames().append(
595 TrivialTaggedParserAtomIndex::from(name))) {
596 ReportOutOfMemory(this->fc_);
597 return false;
598 }
599
600 NameNodeType paramNode;
601 MOZ_TRY_VAR_OR_RETURN(paramNode, newName(name), false)do { auto parserTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(paramNode) = parserTryVarTempResult_.unwrap(); } while (0)
;
602
603 handler_.addFunctionFormalParameter(funNode, paramNode);
604 return true;
605}
606
607template <class ParseHandler>
608bool PerHandlerParser<ParseHandler>::noteDestructuredPositionalFormalParameter(
609 FunctionNodeType funNode, Node destruct) {
610 // Append an empty name to the positional formals vector to keep track of
611 // argument slots when making FunctionScope::ParserData.
612 if (!pc_->positionalFormalParameterNames().append(
613 TrivialTaggedParserAtomIndex::null())) {
614 ReportOutOfMemory(fc_);
615 return false;
616 }
617
618 handler_.addFunctionFormalParameter(funNode, destruct);
619 return true;
620}
621
622template <class ParseHandler, typename Unit>
623bool GeneralParser<ParseHandler, Unit>::noteDeclaredName(
624 TaggedParserAtomIndex name, DeclarationKind kind, TokenPos pos,
625 ClosedOver isClosedOver) {
626 // The asm.js validator does all its own symbol-table management so, as an
627 // optimization, avoid doing any work here.
628 if (pc_->useAsmOrInsideUseAsm()) {
629 return true;
630 }
631
632 switch (kind) {
633 case DeclarationKind::Var:
634 case DeclarationKind::BodyLevelFunction: {
635 Maybe<DeclarationKind> redeclaredKind;
636 uint32_t prevPos;
637 if (!pc_->tryDeclareVar(name, this, kind, pos.begin, &redeclaredKind,
638 &prevPos)) {
639 return false;
640 }
641
642 if (redeclaredKind) {
643 reportRedeclaration(name, *redeclaredKind, pos, prevPos);
644 return false;
645 }
646
647 break;
648 }
649
650 case DeclarationKind::ModuleBodyLevelFunction: {
651 MOZ_ASSERT(pc_->atModuleLevel())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->atModuleLevel())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->atModuleLevel()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->atModuleLevel()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->atModuleLevel()"
")"); do { *((volatile int*)__null) = 651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
652
653 AddDeclaredNamePtr p = pc_->varScope().lookupDeclaredNameForAdd(name);
654 if (p) {
655 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
656 return false;
657 }
658
659 if (!pc_->varScope().addDeclaredName(pc_, p, name, kind, pos.begin,
660 isClosedOver)) {
661 return false;
662 }
663
664 // Body-level functions in modules are always closed over.
665 pc_->varScope().lookupDeclaredName(name)->value()->setClosedOver();
666
667 break;
668 }
669
670 case DeclarationKind::FormalParameter: {
671 // It is an early error if any non-positional formal parameter name
672 // (e.g., destructuring formal parameter) is duplicated.
673
674 AddDeclaredNamePtr p =
675 pc_->functionScope().lookupDeclaredNameForAdd(name);
676 if (p) {
677 error(JSMSG_BAD_DUP_ARGS);
678 return false;
679 }
680
681 if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, pos.begin,
682 isClosedOver)) {
683 return false;
684 }
685
686 break;
687 }
688
689 case DeclarationKind::LexicalFunction:
690 case DeclarationKind::PrivateName:
691 case DeclarationKind::Synthetic:
692 case DeclarationKind::PrivateMethod: {
693 ParseContext::Scope* scope = pc_->innermostScope();
694 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
695 if (p) {
696 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
697 return false;
698 }
699
700 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
701 isClosedOver)) {
702 return false;
703 }
704
705 break;
706 }
707
708 case DeclarationKind::SloppyLexicalFunction: {
709 // Functions in block have complex allowances in sloppy mode for being
710 // labelled that other lexical declarations do not have. Those checks
711 // are done in functionStmt.
712
713 ParseContext::Scope* scope = pc_->innermostScope();
714 if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
715 // It is usually an early error if there is another declaration
716 // with the same name in the same scope.
717 //
718 // Sloppy lexical functions may redeclare other sloppy lexical
719 // functions for web compatibility reasons.
720 if (p->value()->kind() != DeclarationKind::SloppyLexicalFunction) {
721 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
722 return false;
723 }
724 } else {
725 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
726 isClosedOver)) {
727 return false;
728 }
729 }
730
731 break;
732 }
733
734 case DeclarationKind::Let:
735 case DeclarationKind::Const:
736#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
737 case DeclarationKind::Using:
738 case DeclarationKind::AwaitUsing:
739#endif
740 case DeclarationKind::Class:
741 // The BoundNames of LexicalDeclaration and ForDeclaration must not
742 // contain 'let'. (CatchParameter is the only lexical binding form
743 // without this restriction.)
744 if (name == TaggedParserAtomIndex::WellKnown::let()) {
745 errorAt(pos.begin, JSMSG_LEXICAL_DECL_DEFINES_LET);
746 return false;
747 }
748
749 // For body-level lexically declared names in a function, it is an
750 // early error if there is a formal parameter of the same name. This
751 // needs a special check if there is an extra var scope due to
752 // parameter expressions.
753 if (pc_->isFunctionExtraBodyVarScopeInnermost()) {
754 DeclaredNamePtr p = pc_->functionScope().lookupDeclaredName(name);
755 if (p && DeclarationKindIsParameter(p->value()->kind())) {
756 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
757 return false;
758 }
759 }
760
761 [[fallthrough]];
762
763 case DeclarationKind::Import:
764 // Module code is always strict, so 'let' is always a keyword and never a
765 // name.
766 MOZ_ASSERT(name != TaggedParserAtomIndex::WellKnown::let())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name != TaggedParserAtomIndex::WellKnown::let())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(name != TaggedParserAtomIndex::WellKnown::let()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("name != TaggedParserAtomIndex::WellKnown::let()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 766); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name != TaggedParserAtomIndex::WellKnown::let()"
")"); do { *((volatile int*)__null) = 766; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
767 [[fallthrough]];
768
769 case DeclarationKind::SimpleCatchParameter:
770 case DeclarationKind::CatchParameter: {
771 ParseContext::Scope* scope = pc_->innermostScope();
772
773 // It is an early error if there is another declaration with the same
774 // name in the same scope.
775 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
776 if (p) {
777 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
778 return false;
779 }
780
781 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
782 isClosedOver)) {
783 return false;
784 }
785
786 break;
787 }
788
789 case DeclarationKind::CoverArrowParameter:
790 // CoverArrowParameter is only used as a placeholder declaration kind.
791 break;
792
793 case DeclarationKind::PositionalFormalParameter:
794 MOZ_CRASH(do { do { } while (false); MOZ_ReportCrash("" "Positional formal parameter names should use "
"notePositionalFormalParameter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 796); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 796; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
795 "Positional formal parameter names should use "do { do { } while (false); MOZ_ReportCrash("" "Positional formal parameter names should use "
"notePositionalFormalParameter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 796); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 796; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
796 "notePositionalFormalParameter")do { do { } while (false); MOZ_ReportCrash("" "Positional formal parameter names should use "
"notePositionalFormalParameter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 796); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 796; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
;
797 break;
798
799 case DeclarationKind::VarForAnnexBLexicalFunction:
800 MOZ_CRASH(do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 803); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 803; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
801 "Synthesized Annex B vars should go through "do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 803); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 803; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
802 "addPossibleAnnexBFunctionBox, and "do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 803); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 803; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
803 "propagateAndMarkAnnexBFunctionBoxes")do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 803); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 803; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
804 break;
805 }
806
807 return true;
808}
809
810template <class ParseHandler, typename Unit>
811bool GeneralParser<ParseHandler, Unit>::noteDeclaredPrivateName(
812 Node nameNode, TaggedParserAtomIndex name, PropertyType propType,
813 FieldPlacement placement, TokenPos pos) {
814 ParseContext::Scope* scope = pc_->innermostScope();
815 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
816
817 DeclarationKind declKind = DeclarationKind::PrivateName;
818
819 // Our strategy for enabling debugger functionality is to mark names as closed
820 // over, even if they don't necessarily need to be, to ensure that they are
821 // included in the environment object. This allows us to easily look them up
822 // by name when needed, even if there is no corresponding property on an
823 // object, as is the case with getter, setters and private methods.
824 ClosedOver closedOver = ClosedOver::Yes;
825 PrivateNameKind kind;
826 switch (propType) {
827 case PropertyType::Field:
828 kind = PrivateNameKind::Field;
829 closedOver = ClosedOver::No;
830 break;
831 case PropertyType::FieldWithAccessor:
832 // In this case, we create a new private field for the underlying storage,
833 // and use the current name for the getter and setter.
834 kind = PrivateNameKind::GetterSetter;
835 break;
836 case PropertyType::Method:
837 case PropertyType::GeneratorMethod:
838 case PropertyType::AsyncMethod:
839 case PropertyType::AsyncGeneratorMethod:
840 if (placement == FieldPlacement::Instance) {
841 // Optimized private method. Non-optimized paths still get
842 // DeclarationKind::Synthetic.
843 declKind = DeclarationKind::PrivateMethod;
844 }
845 kind = PrivateNameKind::Method;
846 break;
847 case PropertyType::Getter:
848 kind = PrivateNameKind::Getter;
849 break;
850 case PropertyType::Setter:
851 kind = PrivateNameKind::Setter;
852 break;
853 default:
854 MOZ_CRASH("Invalid Property Type for noteDeclarePrivateName")do { do { } while (false); MOZ_ReportCrash("" "Invalid Property Type for noteDeclarePrivateName"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 854); AnnotateMozCrashReason("MOZ_CRASH(" "Invalid Property Type for noteDeclarePrivateName"
")"); do { *((volatile int*)__null) = 854; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
855 }
856
857 if (p) {
858 PrivateNameKind prevKind = p->value()->privateNameKind();
859 if ((prevKind == PrivateNameKind::Getter &&
860 kind == PrivateNameKind::Setter) ||
861 (prevKind == PrivateNameKind::Setter &&
862 kind == PrivateNameKind::Getter)) {
863 // Private methods demands that
864 //
865 // class A {
866 // static set #x(_) {}
867 // get #x() { }
868 // }
869 //
870 // Report a SyntaxError.
871 if (placement == p->value()->placement()) {
872 p->value()->setPrivateNameKind(PrivateNameKind::GetterSetter);
873 handler_.setPrivateNameKind(nameNode, PrivateNameKind::GetterSetter);
874 return true;
875 }
876 }
877
878 reportMismatchedPlacement(name, p->value()->kind(), pos, p->value()->pos());
879 return false;
880 }
881
882 if (!scope->addDeclaredName(pc_, p, name, declKind, pos.begin, closedOver)) {
883 return false;
884 }
885
886 DeclaredNamePtr declared = scope->lookupDeclaredName(name);
887 declared->value()->setPrivateNameKind(kind);
888 declared->value()->setFieldPlacement(placement);
889 handler_.setPrivateNameKind(nameNode, kind);
890
891 return true;
892}
893
894bool ParserBase::noteUsedNameInternal(TaggedParserAtomIndex name,
895 NameVisibility visibility,
896 mozilla::Maybe<TokenPos> tokenPosition) {
897 // The asm.js validator does all its own symbol-table management so, as an
898 // optimization, avoid doing any work here.
899 if (pc_->useAsmOrInsideUseAsm()) {
900 return true;
901 }
902
903 // Global bindings are properties and not actual bindings; we don't need
904 // to know if they are closed over. So no need to track used name at the
905 // global scope. It is not incorrect to track them, this is an
906 // optimization.
907 //
908 // Exceptions:
909 // (a) Track private name references, as the used names tracker is used to
910 // provide early errors for undeclared private name references
911 // (b) If the script has extra bindings, track all references to detect
912 // references to extra bindings
913 ParseContext::Scope* scope = pc_->innermostScope();
914 if (pc_->sc()->isGlobalContext() && scope == &pc_->varScope() &&
915 visibility == NameVisibility::Public &&
916 !this->compilationState_.input.hasExtraBindings()) {
917 return true;
918 }
919
920 return usedNames_.noteUse(fc_, name, visibility, pc_->scriptId(), scope->id(),
921 tokenPosition);
922}
923
924template <class ParseHandler>
925bool PerHandlerParser<ParseHandler>::
926 propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope) {
927 // Now that we have all the declared names in the scope, check which
928 // functions should exhibit Annex B semantics.
929 if (!scope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
930 return false;
931 }
932
933 if (handler_.reuseClosedOverBindings()) {
934 MOZ_ASSERT(pc_->isOutermostOfCurrentCompile())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isOutermostOfCurrentCompile())>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(pc_->isOutermostOfCurrentCompile()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->isOutermostOfCurrentCompile()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 934); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isOutermostOfCurrentCompile()"
")"); do { *((volatile int*)__null) = 934; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
935
936 // Closed over bindings for all scopes are stored in a contiguous array, in
937 // the same order as the order in which scopes are visited, and seprated by
938 // TaggedParserAtomIndex::null().
939 uint32_t slotCount = scope.declaredCount();
940 while (auto parserAtom = handler_.nextLazyClosedOverBinding()) {
941 scope.lookupDeclaredName(parserAtom)->value()->setClosedOver();
942 MOZ_ASSERT(slotCount > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(slotCount > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(slotCount > 0))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("slotCount > 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "slotCount > 0"
")"); do { *((volatile int*)__null) = 942; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
943 slotCount--;
944 }
945
946 if (pc_->isGeneratorOrAsync()) {
947 scope.setOwnStackSlotCount(slotCount);
948 }
949 return true;
950 }
951
952 constexpr bool isSyntaxParser =
953 std::is_same_v<ParseHandler, SyntaxParseHandler>;
954 uint32_t scriptId = pc_->scriptId();
955 uint32_t scopeId = scope.id();
956
957 uint32_t slotCount = 0;
958 for (BindingIter bi = scope.bindings(pc_); bi; bi++) {
959 bool closedOver = false;
960 if (UsedNamePtr p = usedNames_.lookup(bi.name())) {
961 p->value().noteBoundInScope(scriptId, scopeId, &closedOver);
962 if (closedOver) {
963 bi.setClosedOver();
964
965 if constexpr (isSyntaxParser) {
966 if (!pc_->closedOverBindingsForLazy().append(
967 TrivialTaggedParserAtomIndex::from(bi.name()))) {
968 ReportOutOfMemory(fc_);
969 return false;
970 }
971 }
972 }
973 }
974
975 if constexpr (!isSyntaxParser) {
976 if (!closedOver) {
977 slotCount++;
978 }
979 }
980 }
981 if constexpr (!isSyntaxParser) {
982 if (pc_->isGeneratorOrAsync()) {
983 scope.setOwnStackSlotCount(slotCount);
984 }
985 }
986
987 // Append a nullptr to denote end-of-scope.
988 if constexpr (isSyntaxParser) {
989 if (!pc_->closedOverBindingsForLazy().append(
990 TrivialTaggedParserAtomIndex::null())) {
991 ReportOutOfMemory(fc_);
992 return false;
993 }
994 }
995
996 return true;
997}
998
999template <typename Unit>
1000bool Parser<FullParseHandler, Unit>::checkStatementsEOF() {
1001 // This is designed to be paired with parsing a statement list at the top
1002 // level.
1003 //
1004 // The statementList() call breaks on TokenKind::RightCurly, so make sure
1005 // we've reached EOF here.
1006 TokenKind tt;
1007 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
1008 return false;
1009 }
1010 if (tt != TokenKind::Eof) {
1011 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
1012 return false;
1013 }
1014 return true;
1015}
1016
1017template <typename ScopeT>
1018typename ScopeT::ParserData* NewEmptyBindingData(FrontendContext* fc,
1019 LifoAlloc& alloc,
1020 uint32_t numBindings) {
1021 using Data = typename ScopeT::ParserData;
1022 size_t allocSize = SizeOfScopeData<Data>(numBindings);
1023 auto* bindings = alloc.newWithSize<Data>(allocSize, numBindings);
1024 if (!bindings) {
1025 ReportOutOfMemory(fc);
1026 }
1027 return bindings;
1028}
1029
1030GlobalScope::ParserData* NewEmptyGlobalScopeData(FrontendContext* fc,
1031 LifoAlloc& alloc,
1032 uint32_t numBindings) {
1033 return NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
1034}
1035
1036LexicalScope::ParserData* NewEmptyLexicalScopeData(FrontendContext* fc,
1037 LifoAlloc& alloc,
1038 uint32_t numBindings) {
1039 return NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
1040}
1041
1042FunctionScope::ParserData* NewEmptyFunctionScopeData(FrontendContext* fc,
1043 LifoAlloc& alloc,
1044 uint32_t numBindings) {
1045 return NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
1046}
1047
1048namespace detail {
1049
1050template <class SlotInfo>
1051static MOZ_ALWAYS_INLINEinline ParserBindingName* InitializeIndexedBindings(
1052 SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor) {
1053 return cursor;
1054}
1055
1056template <class SlotInfo, typename UnsignedInteger, typename... Step>
1057static MOZ_ALWAYS_INLINEinline ParserBindingName* InitializeIndexedBindings(
1058 SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor,
1059 UnsignedInteger SlotInfo::*field, const ParserBindingNameVector& bindings,
1060 Step&&... step) {
1061 slotInfo.*field =
1062 AssertedCast<UnsignedInteger>(PointerRangeSize(start, cursor));
1063
1064 ParserBindingName* newCursor =
1065 std::uninitialized_copy(bindings.begin(), bindings.end(), cursor);
1066
1067 return InitializeIndexedBindings(slotInfo, start, newCursor,
1068 std::forward<Step>(step)...);
1069}
1070
1071} // namespace detail
1072
1073// Initialize the trailing name bindings of |data|, then set |data->length| to
1074// the count of bindings added (which must equal |count|).
1075//
1076// First, |firstBindings| are added to the trailing names. Then any
1077// "steps" present are performed first to last. Each step is 1) a pointer to a
1078// member of |data| to be set to the current number of bindings added, and 2) a
1079// vector of |ParserBindingName|s to then copy into |data->trailingNames|.
1080// (Thus each |data| member field indicates where the corresponding vector's
1081// names start.)
1082template <class Data, typename... Step>
1083static MOZ_ALWAYS_INLINEinline void InitializeBindingData(
1084 Data* data, uint32_t count, const ParserBindingNameVector& firstBindings,
1085 Step&&... step) {
1086 MOZ_ASSERT(data->length == 0, "data shouldn't be filled yet")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(data->length == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(data->length == 0))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("data->length == 0"
" (" "data shouldn't be filled yet" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1086); AnnotateMozCrashReason("MOZ_ASSERT" "(" "data->length == 0"
") (" "data shouldn't be filled yet" ")"); do { *((volatile int
*)__null) = 1086; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1087
1088 ParserBindingName* start = GetScopeDataTrailingNamesPointer(data);
1089 ParserBindingName* cursor = std::uninitialized_copy(
1090 firstBindings.begin(), firstBindings.end(), start);
1091
1092#ifdef DEBUG1
1093 ParserBindingName* end =
1094#endif
1095 detail::InitializeIndexedBindings(data->slotInfo, start, cursor,
1096 std::forward<Step>(step)...);
1097
1098 MOZ_ASSERT(PointerRangeSize(start, end) == count)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(PointerRangeSize(start, end) == count)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(PointerRangeSize(start, end) == count))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("PointerRangeSize(start, end) == count"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1098); AnnotateMozCrashReason("MOZ_ASSERT" "(" "PointerRangeSize(start, end) == count"
")"); do { *((volatile int*)__null) = 1098; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1099 data->length = count;
1100}
1101
1102static Maybe<GlobalScope::ParserData*> NewGlobalScopeData(
1103 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1104 ParseContext* pc) {
1105 ParserBindingNameVector vars(fc);
1106 ParserBindingNameVector lets(fc);
1107 ParserBindingNameVector consts(fc);
1108
1109 bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
1110 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1111 bool closedOver = allBindingsClosedOver || bi.closedOver();
1112
1113 switch (bi.kind()) {
1114 case BindingKind::Var: {
1115 bool isTopLevelFunction =
1116 bi.declarationKind() == DeclarationKind::BodyLevelFunction;
1117
1118 ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
1119 if (!vars.append(binding)) {
1120 return Nothing();
1121 }
1122 break;
1123 }
1124 case BindingKind::Let: {
1125 ParserBindingName binding(bi.name(), closedOver);
1126 if (!lets.append(binding)) {
1127 return Nothing();
1128 }
1129 break;
1130 }
1131 case BindingKind::Const: {
1132 ParserBindingName binding(bi.name(), closedOver);
1133 if (!consts.append(binding)) {
1134 return Nothing();
1135 }
1136 break;
1137 }
1138 default:
1139 MOZ_CRASH("Bad global scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "Bad global scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1139); AnnotateMozCrashReason("MOZ_CRASH(" "Bad global scope BindingKind"
")"); do { *((volatile int*)__null) = 1139; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1140 }
1141 }
1142
1143 GlobalScope::ParserData* bindings = nullptr;
1144 uint32_t numBindings = vars.length() + lets.length() + consts.length();
1145
1146 if (numBindings > 0) {
1147 bindings = NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
1148 if (!bindings) {
1149 return Nothing();
1150 }
1151
1152 // The ordering here is important. See comments in GlobalScope.
1153 InitializeBindingData(bindings, numBindings, vars,
1154 &ParserGlobalScopeSlotInfo::letStart, lets,
1155 &ParserGlobalScopeSlotInfo::constStart, consts);
1156 }
1157
1158 return Some(bindings);
1159}
1160
1161Maybe<GlobalScope::ParserData*> ParserBase::newGlobalScopeData(
1162 ParseContext::Scope& scope) {
1163 return NewGlobalScopeData(fc_, scope, stencilAlloc(), pc_);
1164}
1165
1166static Maybe<ModuleScope::ParserData*> NewModuleScopeData(
1167 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1168 ParseContext* pc) {
1169 ParserBindingNameVector imports(fc);
1170 ParserBindingNameVector vars(fc);
1171 ParserBindingNameVector lets(fc);
1172 ParserBindingNameVector consts(fc);
1173#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1174 ParserBindingNameVector usings(fc);
1175#endif
1176
1177 bool allBindingsClosedOver =
1178 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1179
1180 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1181 // Imports are indirect bindings and must not be given known slots.
1182 ParserBindingName binding(bi.name(),
1183 (allBindingsClosedOver || bi.closedOver()) &&
1184 bi.kind() != BindingKind::Import);
1185 switch (bi.kind()) {
1186 case BindingKind::Import:
1187 if (!imports.append(binding)) {
1188 return Nothing();
1189 }
1190 break;
1191 case BindingKind::Var:
1192 if (!vars.append(binding)) {
1193 return Nothing();
1194 }
1195 break;
1196 case BindingKind::Let:
1197 if (!lets.append(binding)) {
1198 return Nothing();
1199 }
1200 break;
1201 case BindingKind::Const:
1202 if (!consts.append(binding)) {
1203 return Nothing();
1204 }
1205 break;
1206#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1207 case BindingKind::Using:
1208 if (!usings.append(binding)) {
1209 return Nothing();
1210 }
1211 break;
1212#endif
1213 default:
1214 MOZ_CRASH("Bad module scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "Bad module scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1214); AnnotateMozCrashReason("MOZ_CRASH(" "Bad module scope BindingKind"
")"); do { *((volatile int*)__null) = 1214; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1215 }
1216 }
1217
1218 ModuleScope::ParserData* bindings = nullptr;
1219 uint32_t numBindings = imports.length() + vars.length() + lets.length() +
1220 consts.length()
1221#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1222 + usings.length()
1223#endif
1224 ;
1225
1226 if (numBindings > 0) {
1227 bindings = NewEmptyBindingData<ModuleScope>(fc, alloc, numBindings);
1228 if (!bindings) {
1229 return Nothing();
1230 }
1231
1232 // The ordering here is important. See comments in ModuleScope.
1233 InitializeBindingData(bindings, numBindings, imports,
1234 &ParserModuleScopeSlotInfo::varStart, vars,
1235 &ParserModuleScopeSlotInfo::letStart, lets,
1236 &ParserModuleScopeSlotInfo::constStart, consts
1237#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1238 ,
1239 &ParserModuleScopeSlotInfo::usingStart, usings
1240#endif
1241 );
1242 }
1243
1244 return Some(bindings);
1245}
1246
1247Maybe<ModuleScope::ParserData*> ParserBase::newModuleScopeData(
1248 ParseContext::Scope& scope) {
1249 return NewModuleScopeData(fc_, scope, stencilAlloc(), pc_);
1250}
1251
1252static Maybe<EvalScope::ParserData*> NewEvalScopeData(
1253 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1254 ParseContext* pc) {
1255 ParserBindingNameVector vars(fc);
1256
1257 // Treat all bindings as closed over in non-strict eval.
1258 bool allBindingsClosedOver =
1259 !pc->sc()->strict() || pc->sc()->allBindingsClosedOver();
1260 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1261 // Eval scopes only contain 'var' bindings.
1262 MOZ_ASSERT(bi.kind() == BindingKind::Var)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Var)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(bi.kind() == BindingKind::Var
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"bi.kind() == BindingKind::Var", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1262); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Var"
")"); do { *((volatile int*)__null) = 1262; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1263 bool isTopLevelFunction =
1264 bi.declarationKind() == DeclarationKind::BodyLevelFunction;
1265 bool closedOver = allBindingsClosedOver || bi.closedOver();
1266
1267 ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
1268 if (!vars.append(binding)) {
1269 return Nothing();
1270 }
1271 }
1272
1273 EvalScope::ParserData* bindings = nullptr;
1274 uint32_t numBindings = vars.length();
1275
1276 if (numBindings > 0) {
1277 bindings = NewEmptyBindingData<EvalScope>(fc, alloc, numBindings);
1278 if (!bindings) {
1279 return Nothing();
1280 }
1281
1282 InitializeBindingData(bindings, numBindings, vars);
1283 }
1284
1285 return Some(bindings);
1286}
1287
1288Maybe<EvalScope::ParserData*> ParserBase::newEvalScopeData(
1289 ParseContext::Scope& scope) {
1290 return NewEvalScopeData(fc_, scope, stencilAlloc(), pc_);
1291}
1292
1293static Maybe<FunctionScope::ParserData*> NewFunctionScopeData(
1294 FrontendContext* fc, ParseContext::Scope& scope, bool hasParameterExprs,
1295 LifoAlloc& alloc, ParseContext* pc) {
1296 ParserBindingNameVector positionalFormals(fc);
1297 ParserBindingNameVector formals(fc);
1298 ParserBindingNameVector vars(fc);
1299
1300 bool allBindingsClosedOver =
1301 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1302 bool argumentBindingsClosedOver =
1303 allBindingsClosedOver || pc->isGeneratorOrAsync();
1304 bool hasDuplicateParams = pc->functionBox()->hasDuplicateParameters;
1305
1306 // Positional parameter names must be added in order of appearance as they are
1307 // referenced using argument slots.
1308 for (size_t i = 0; i < pc->positionalFormalParameterNames().length(); i++) {
1309 TaggedParserAtomIndex name = pc->positionalFormalParameterNames()[i];
1310
1311 ParserBindingName bindName;
1312 if (name) {
1313 DeclaredNamePtr p = scope.lookupDeclaredName(name);
1314
1315 // Do not consider any positional formal parameters closed over if
1316 // there are parameter defaults. It is the binding in the defaults
1317 // scope that is closed over instead.
1318 bool closedOver =
1319 argumentBindingsClosedOver || (p && p->value()->closedOver());
1320
1321 // If the parameter name has duplicates, only the final parameter
1322 // name should be on the environment, as otherwise the environment
1323 // object would have multiple, same-named properties.
1324 if (hasDuplicateParams) {
1325 for (size_t j = pc->positionalFormalParameterNames().length() - 1;
1326 j > i; j--) {
1327 if (TaggedParserAtomIndex(pc->positionalFormalParameterNames()[j]) ==
1328 name) {
1329 closedOver = false;
1330 break;
1331 }
1332 }
1333 }
1334
1335 bindName = ParserBindingName(name, closedOver);
1336 }
1337
1338 if (!positionalFormals.append(bindName)) {
1339 return Nothing();
1340 }
1341 }
1342
1343 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1344 ParserBindingName binding(bi.name(),
1345 allBindingsClosedOver || bi.closedOver());
1346 switch (bi.kind()) {
1347 case BindingKind::FormalParameter:
1348 // Positional parameter names are already handled above.
1349 if (bi.declarationKind() == DeclarationKind::FormalParameter) {
1350 if (!formals.append(binding)) {
1351 return Nothing();
1352 }
1353 }
1354 break;
1355 case BindingKind::Var:
1356 // The only vars in the function scope when there are parameter
1357 // exprs, which induces a separate var environment, should be the
1358 // special bindings.
1359 MOZ_ASSERT_IF(hasParameterExprs,do { if (hasParameterExprs) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(FunctionScope::isSpecialName
(bi.name()))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(FunctionScope::isSpecialName(bi.name
())))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("FunctionScope::isSpecialName(bi.name())", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1360); AnnotateMozCrashReason("MOZ_ASSERT" "(" "FunctionScope::isSpecialName(bi.name())"
")"); do { *((volatile int*)__null) = 1360; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1360 FunctionScope::isSpecialName(bi.name()))do { if (hasParameterExprs) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(FunctionScope::isSpecialName
(bi.name()))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(FunctionScope::isSpecialName(bi.name
())))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("FunctionScope::isSpecialName(bi.name())", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1360); AnnotateMozCrashReason("MOZ_ASSERT" "(" "FunctionScope::isSpecialName(bi.name())"
")"); do { *((volatile int*)__null) = 1360; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1361 if (!vars.append(binding)) {
1362 return Nothing();
1363 }
1364 break;
1365 case BindingKind::Let:
1366 case BindingKind::Const:
1367#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1368 case BindingKind::Using:
1369#endif
1370 break;
1371 default:
1372 MOZ_CRASH("bad function scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "bad function scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1372); AnnotateMozCrashReason("MOZ_CRASH(" "bad function scope BindingKind"
")"); do { *((volatile int*)__null) = 1372; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1373 break;
1374 }
1375 }
1376
1377 FunctionScope::ParserData* bindings = nullptr;
1378 uint32_t numBindings =
1379 positionalFormals.length() + formals.length() + vars.length();
1380
1381 if (numBindings > 0) {
1382 bindings = NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
1383 if (!bindings) {
1384 return Nothing();
1385 }
1386
1387 // The ordering here is important. See comments in FunctionScope.
1388 InitializeBindingData(
1389 bindings, numBindings, positionalFormals,
1390 &ParserFunctionScopeSlotInfo::nonPositionalFormalStart, formals,
1391 &ParserFunctionScopeSlotInfo::varStart, vars);
1392 }
1393
1394 return Some(bindings);
1395}
1396
1397// Compute if `NewFunctionScopeData` would return any binding list with any
1398// entry marked as closed-over. This is done without the need to allocate the
1399// binding list. If true, an EnvironmentObject will be needed at runtime.
1400bool FunctionScopeHasClosedOverBindings(ParseContext* pc) {
1401 bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver() ||
1402 pc->functionScope().tooBigToOptimize();
1403
1404 for (BindingIter bi = pc->functionScope().bindings(pc); bi; bi++) {
1405 switch (bi.kind()) {
1406 case BindingKind::FormalParameter:
1407 case BindingKind::Var:
1408 if (allBindingsClosedOver || bi.closedOver()) {
1409 return true;
1410 }
1411 break;
1412
1413 default:
1414 break;
1415 }
1416 }
1417
1418 return false;
1419}
1420
1421Maybe<FunctionScope::ParserData*> ParserBase::newFunctionScopeData(
1422 ParseContext::Scope& scope, bool hasParameterExprs) {
1423 return NewFunctionScopeData(fc_, scope, hasParameterExprs, stencilAlloc(),
1424 pc_);
1425}
1426
1427VarScope::ParserData* NewEmptyVarScopeData(FrontendContext* fc,
1428 LifoAlloc& alloc,
1429 uint32_t numBindings) {
1430 return NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
1431}
1432
1433static Maybe<VarScope::ParserData*> NewVarScopeData(FrontendContext* fc,
1434 ParseContext::Scope& scope,
1435 LifoAlloc& alloc,
1436 ParseContext* pc) {
1437 ParserBindingNameVector vars(fc);
1438
1439 bool allBindingsClosedOver =
1440 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1441
1442 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1443 if (bi.kind() == BindingKind::Var) {
1444 ParserBindingName binding(bi.name(),
1445 allBindingsClosedOver || bi.closedOver());
1446 if (!vars.append(binding)) {
1447 return Nothing();
1448 }
1449 } else {
1450 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1452); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1452; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1451 bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1452); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1452; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1452 "bad var scope BindingKind")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1452); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1452; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1453 }
1454 }
1455
1456 VarScope::ParserData* bindings = nullptr;
1457 uint32_t numBindings = vars.length();
1458
1459 if (numBindings > 0) {
1460 bindings = NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
1461 if (!bindings) {
1462 return Nothing();
1463 }
1464
1465 InitializeBindingData(bindings, numBindings, vars);
1466 }
1467
1468 return Some(bindings);
1469}
1470
1471// Compute if `NewVarScopeData` would return any binding list. This is done
1472// without allocate the binding list.
1473static bool VarScopeHasBindings(ParseContext* pc) {
1474 for (BindingIter bi = pc->varScope().bindings(pc); bi; bi++) {
1475 if (bi.kind() == BindingKind::Var) {
1476 return true;
1477 }
1478 }
1479
1480 return false;
1481}
1482
1483Maybe<VarScope::ParserData*> ParserBase::newVarScopeData(
1484 ParseContext::Scope& scope) {
1485 return NewVarScopeData(fc_, scope, stencilAlloc(), pc_);
1486}
1487
1488static Maybe<LexicalScope::ParserData*> NewLexicalScopeData(
1489 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1490 ParseContext* pc) {
1491 ParserBindingNameVector lets(fc);
1492 ParserBindingNameVector consts(fc);
1493#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1494 ParserBindingNameVector usings(fc);
1495#endif
1496
1497 bool allBindingsClosedOver =
1498 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1499
1500 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1501 ParserBindingName binding(bi.name(),
1502 allBindingsClosedOver || bi.closedOver());
1503 switch (bi.kind()) {
1504 case BindingKind::Let:
1505 if (!lets.append(binding)) {
1506 return Nothing();
1507 }
1508 break;
1509 case BindingKind::Const:
1510 if (!consts.append(binding)) {
1511 return Nothing();
1512 }
1513 break;
1514#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1515 case BindingKind::Using:
1516 if (!usings.append(binding)) {
1517 return Nothing();
1518 }
1519 break;
1520#endif
1521 case BindingKind::Var:
1522 case BindingKind::FormalParameter:
1523 break;
1524 default:
1525 MOZ_CRASH("Bad lexical scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "Bad lexical scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1525); AnnotateMozCrashReason("MOZ_CRASH(" "Bad lexical scope BindingKind"
")"); do { *((volatile int*)__null) = 1525; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1526 break;
1527 }
1528 }
1529
1530 LexicalScope::ParserData* bindings = nullptr;
1531 uint32_t numBindings = lets.length() + consts.length()
1532#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1533 + usings.length()
1534#endif
1535 ;
1536
1537 if (numBindings > 0) {
1538 bindings = NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
1539 if (!bindings) {
1540 return Nothing();
1541 }
1542
1543 // The ordering here is important. See comments in LexicalScope.
1544 InitializeBindingData(bindings, numBindings, lets,
1545 &ParserLexicalScopeSlotInfo::constStart, consts
1546#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1547 ,
1548 &ParserLexicalScopeSlotInfo::usingStart, usings
1549#endif
1550 );
1551 }
1552
1553 return Some(bindings);
1554}
1555
1556// Compute if `NewLexicalScopeData` would return any binding list with any entry
1557// marked as closed-over. This is done without the need to allocate the binding
1558// list. If true, an EnvironmentObject will be needed at runtime.
1559bool LexicalScopeHasClosedOverBindings(ParseContext* pc,
1560 ParseContext::Scope& scope) {
1561 bool allBindingsClosedOver =
1562 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1563
1564 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1565 switch (bi.kind()) {
1566 case BindingKind::Let:
1567 case BindingKind::Const:
1568 if (allBindingsClosedOver || bi.closedOver()) {
1569 return true;
1570 }
1571 break;
1572
1573 default:
1574 break;
1575 }
1576 }
1577
1578 return false;
1579}
1580
1581Maybe<LexicalScope::ParserData*> ParserBase::newLexicalScopeData(
1582 ParseContext::Scope& scope) {
1583 return NewLexicalScopeData(fc_, scope, stencilAlloc(), pc_);
1584}
1585
1586static Maybe<ClassBodyScope::ParserData*> NewClassBodyScopeData(
1587 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1588 ParseContext* pc) {
1589 ParserBindingNameVector privateBrand(fc);
1590 ParserBindingNameVector synthetics(fc);
1591 ParserBindingNameVector privateMethods(fc);
1592
1593 bool allBindingsClosedOver =
1594 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
5
Assuming the condition is false
1595
1596 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
6
Loop condition is false. Execution continues on line 1627
1597 ParserBindingName binding(bi.name(),
1598 allBindingsClosedOver || bi.closedOver());
1599 switch (bi.kind()) {
1600 case BindingKind::Synthetic:
1601 if (bi.name() ==
1602 TaggedParserAtomIndex::WellKnown::dot_privateBrand_()) {
1603 MOZ_ASSERT(privateBrand.empty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(privateBrand.empty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(privateBrand.empty()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("privateBrand.empty()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1603); AnnotateMozCrashReason("MOZ_ASSERT" "(" "privateBrand.empty()"
")"); do { *((volatile int*)__null) = 1603; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1604 if (!privateBrand.append(binding)) {
1605 return Nothing();
1606 }
1607 } else {
1608 if (!synthetics.append(binding)) {
1609 return Nothing();
1610 }
1611 }
1612 break;
1613
1614 case BindingKind::PrivateMethod:
1615 if (!privateMethods.append(binding)) {
1616 return Nothing();
1617 }
1618 break;
1619
1620 default:
1621 MOZ_CRASH("bad class body scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "bad class body scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1621); AnnotateMozCrashReason("MOZ_CRASH(" "bad class body scope BindingKind"
")"); do { *((volatile int*)__null) = 1621; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1622 break;
1623 }
1624 }
1625
1626 // We should have zero or one private brands.
1627 MOZ_ASSERT(privateBrand.length() == 0 || privateBrand.length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(privateBrand.length() == 0 || privateBrand.length() ==
1)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(privateBrand.length() == 0 || privateBrand.length() ==
1))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("privateBrand.length() == 0 || privateBrand.length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1627); AnnotateMozCrashReason("MOZ_ASSERT" "(" "privateBrand.length() == 0 || privateBrand.length() == 1"
")"); do { *((volatile int*)__null) = 1627; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7
Assuming the condition is true
8
Taking false branch
9
Loop condition is false. Exiting loop
1628
1629 ClassBodyScope::ParserData* bindings = nullptr;
10
'bindings' initialized to a null pointer value
1630 uint32_t numBindings =
1631 privateBrand.length() + synthetics.length() + privateMethods.length();
1632
1633 if (numBindings > 0) {
11
Assuming 'numBindings' is <= 0
12
Taking false branch
1634 bindings = NewEmptyBindingData<ClassBodyScope>(fc, alloc, numBindings);
1635 if (!bindings) {
1636 return Nothing();
1637 }
1638 // To simplify initialization of the bindings, we concatenate the
1639 // synthetics+privateBrand vector such that the private brand is always the
1640 // first element, as ordering is important. See comments in ClassBodyScope.
1641 ParserBindingNameVector brandAndSynthetics(fc);
1642 if (!brandAndSynthetics.appendAll(privateBrand)) {
1643 return Nothing();
1644 }
1645 if (!brandAndSynthetics.appendAll(synthetics)) {
1646 return Nothing();
1647 }
1648
1649 // The ordering here is important. See comments in ClassBodyScope.
1650 InitializeBindingData(bindings, numBindings, brandAndSynthetics,
1651 &ParserClassBodyScopeSlotInfo::privateMethodStart,
1652 privateMethods);
1653 }
1654
1655 // `EmitterScope::lookupPrivate()` requires `.privateBrand` to be stored in a
1656 // predictable slot: the first slot available in the environment object,
1657 // `ClassBodyLexicalEnvironmentObject::privateBrandSlot()`. We assume that
1658 // if `.privateBrand` is first in the scope, it will be stored there.
1659 MOZ_ASSERT_IF(!privateBrand.empty(),do { if (!privateBrand.empty()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(GetScopeDataTrailingNames
(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex
::WellKnown::dot_privateBrand_()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
13
Assuming the condition is true
14
Taking true branch
15
Passing null pointer value via 1st parameter 'data'
16
Calling 'GetScopeDataTrailingNames<js::ParserScopeData<js::ClassBodyScope::SlotInfo>>'
1660 GetScopeDataTrailingNames(bindings)[0].name() ==do { if (!privateBrand.empty()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(GetScopeDataTrailingNames
(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex
::WellKnown::dot_privateBrand_()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1661 TaggedParserAtomIndex::WellKnown::dot_privateBrand_())do { if (!privateBrand.empty()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(GetScopeDataTrailingNames
(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex
::WellKnown::dot_privateBrand_()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1662
1663 return Some(bindings);
1664}
1665
1666Maybe<ClassBodyScope::ParserData*> ParserBase::newClassBodyScopeData(
1667 ParseContext::Scope& scope) {
1668 return NewClassBodyScopeData(fc_, scope, stencilAlloc(), pc_);
4
Calling 'NewClassBodyScopeData'
1669}
1670
1671template <>
1672SyntaxParseHandler::LexicalScopeNodeResult
1673PerHandlerParser<SyntaxParseHandler>::finishLexicalScope(
1674 ParseContext::Scope& scope, Node body, ScopeKind kind) {
1675 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1676 return errorResult();
1677 }
1678
1679 return handler_.newLexicalScope(body);
1680}
1681
1682template <>
1683FullParseHandler::LexicalScopeNodeResult
1684PerHandlerParser<FullParseHandler>::finishLexicalScope(
1685 ParseContext::Scope& scope, ParseNode* body, ScopeKind kind) {
1686 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1687 return errorResult();
1688 }
1689
1690 Maybe<LexicalScope::ParserData*> bindings = newLexicalScopeData(scope);
1691 if (!bindings) {
1692 return errorResult();
1693 }
1694
1695 return handler_.newLexicalScope(*bindings, body, kind);
1696}
1697
1698template <>
1699SyntaxParseHandler::ClassBodyScopeNodeResult
1700PerHandlerParser<SyntaxParseHandler>::finishClassBodyScope(
1701 ParseContext::Scope& scope, ListNodeType body) {
1702 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1703 return errorResult();
1704 }
1705
1706 return handler_.newClassBodyScope(body);
1707}
1708
1709template <>
1710FullParseHandler::ClassBodyScopeNodeResult
1711PerHandlerParser<FullParseHandler>::finishClassBodyScope(
1712 ParseContext::Scope& scope, ListNode* body) {
1713 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1
Assuming the condition is false
2
Taking false branch
1714 return errorResult();
1715 }
1716
1717 Maybe<ClassBodyScope::ParserData*> bindings = newClassBodyScopeData(scope);
3
Calling 'ParserBase::newClassBodyScopeData'
1718 if (!bindings) {
1719 return errorResult();
1720 }
1721
1722 return handler_.newClassBodyScope(*bindings, body);
1723}
1724
1725template <class ParseHandler>
1726bool PerHandlerParser<ParseHandler>::checkForUndefinedPrivateFields(
1727 EvalSharedContext* evalSc) {
1728 if (!this->compilationState_.isInitialStencil()) {
1729 // We're delazifying -- so we already checked private names during first
1730 // parse.
1731 return true;
1732 }
1733
1734 Vector<UnboundPrivateName, 8> unboundPrivateNames(fc_);
1735 if (!usedNames_.getUnboundPrivateNames(unboundPrivateNames)) {
1736 return false;
1737 }
1738
1739 // No unbound names, let's get out of here!
1740 if (unboundPrivateNames.empty()) {
1741 return true;
1742 }
1743
1744 // It is an early error if there's private name references unbound,
1745 // unless it's an eval, in which case we need to check the scope
1746 // chain.
1747 if (!evalSc) {
1748 // The unbound private names are sorted, so just grab the first one.
1749 UnboundPrivateName minimum = unboundPrivateNames[0];
1750 UniqueChars str = this->parserAtoms().toPrintableString(minimum.atom);
1751 if (!str) {
1752 ReportOutOfMemory(this->fc_);
1753 return false;
1754 }
1755
1756 errorAt(minimum.position.begin, JSMSG_MISSING_PRIVATE_DECL, str.get());
1757 return false;
1758 }
1759
1760 // It's important that the unbound private names are sorted, as we
1761 // want our errors to always be issued to the first textually.
1762 for (UnboundPrivateName unboundName : unboundPrivateNames) {
1763 // If the enclosingScope is non-syntactic, then we are in a
1764 // Debugger.Frame.prototype.eval call. In order to find the declared private
1765 // names, we must use the effective scope that was determined when creating
1766 // the scopeContext.
1767 if (!this->compilationState_.scopeContext
1768 .effectiveScopePrivateFieldCacheHas(unboundName.atom)) {
1769 UniqueChars str = this->parserAtoms().toPrintableString(unboundName.atom);
1770 if (!str) {
1771 ReportOutOfMemory(this->fc_);
1772 return false;
1773 }
1774 errorAt(unboundName.position.begin, JSMSG_MISSING_PRIVATE_DECL,
1775 str.get());
1776 return false;
1777 }
1778 }
1779
1780 return true;
1781}
1782
1783template <typename Unit>
1784FullParseHandler::LexicalScopeNodeResult
1785Parser<FullParseHandler, Unit>::evalBody(EvalSharedContext* evalsc) {
1786 SourceParseContext evalpc(this, evalsc, /* newDirectives = */ nullptr);
1787 if (!evalpc.init()) {
1788 return errorResult();
1789 }
1790
1791 ParseContext::VarScope varScope(this);
1792 if (!varScope.init(pc_)) {
1793 return errorResult();
1794 }
1795
1796 LexicalScopeNode* body;
1797 {
1798 // All evals have an implicit non-extensible lexical scope.
1799 ParseContext::Scope lexicalScope(this);
1800 if (!lexicalScope.init(pc_)) {
1801 return errorResult();
1802 }
1803
1804 ListNode* list;
1805 MOZ_TRY_VAR(list, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (list) = mozTryVarTempResult_
.unwrap(); } while (0)
;
1806
1807 if (!checkStatementsEOF()) {
1808 return errorResult();
1809 }
1810
1811 // Private names not lexically defined must trigger a syntax error.
1812 if (!checkForUndefinedPrivateFields(evalsc)) {
1813 return errorResult();
1814 }
1815
1816 MOZ_TRY_VAR(body, finishLexicalScope(lexicalScope, list))do { auto mozTryVarTempResult_ = (finishLexicalScope(lexicalScope
, list)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (body
) = mozTryVarTempResult_.unwrap(); } while (0)
;
1817 }
1818
1819#ifdef DEBUG1
1820 if (evalpc.superScopeNeedsHomeObject() &&
1821 !this->compilationState_.input.enclosingScope.isNull()) {
1822 // If superScopeNeedsHomeObject_ is set and we are an entry-point
1823 // ParseContext, then we must be emitting an eval script, and the
1824 // outer function must already be marked as needing a home object
1825 // since it contains an eval.
1826 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1829; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1827 this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1829; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1828 "Eval must have found an enclosing function box scope that "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1829; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1829 "allows super.property")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1829; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
1830 }
1831#endif
1832
1833 if (!CheckParseTree(this->fc_, alloc_, body)) {
1834 return errorResult();
1835 }
1836
1837 ParseNode* node = body;
1838 // Don't constant-fold inside "use asm" code, as this could create a parse
1839 // tree that doesn't type-check as asm.js.
1840 if (!pc_->useAsmOrInsideUseAsm()) {
1841 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
1842 return errorResult();
1843 }
1844 }
1845 body = handler_.asLexicalScopeNode(node);
1846
1847 if (!this->setSourceMapInfo()) {
1848 return errorResult();
1849 }
1850
1851 if (pc_->sc()->strict()) {
1852 if (!propagateFreeNamesAndMarkClosedOverBindings(varScope)) {
1853 return errorResult();
1854 }
1855 } else {
1856 // For non-strict eval scripts, since all bindings are automatically
1857 // considered closed over, we don't need to call propagateFreeNames-
1858 // AndMarkClosedOverBindings. However, Annex B.3.3 functions still need to
1859 // be marked.
1860 if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
1861 return errorResult();
1862 }
1863 }
1864
1865 Maybe<EvalScope::ParserData*> bindings = newEvalScopeData(pc_->varScope());
1866 if (!bindings) {
1867 return errorResult();
1868 }
1869 evalsc->bindings = *bindings;
1870
1871 return body;
1872}
1873
1874template <typename Unit>
1875FullParseHandler::ListNodeResult Parser<FullParseHandler, Unit>::globalBody(
1876 GlobalSharedContext* globalsc) {
1877 SourceParseContext globalpc(this, globalsc, /* newDirectives = */ nullptr);
1878 if (!globalpc.init()) {
1879 return errorResult();
1880 }
1881
1882 ParseContext::VarScope varScope(this);
1883 if (!varScope.init(pc_)) {
1884 return errorResult();
1885 }
1886
1887 ListNode* body;
1888 MOZ_TRY_VAR(body, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
1889
1890 if (!checkStatementsEOF()) {
1891 return errorResult();
1892 }
1893
1894 if (!CheckParseTree(this->fc_, alloc_, body)) {
1895 return errorResult();
1896 }
1897
1898 if (!checkForUndefinedPrivateFields()) {
1899 return errorResult();
1900 }
1901
1902 ParseNode* node = body;
1903 // Don't constant-fold inside "use asm" code, as this could create a parse
1904 // tree that doesn't type-check as asm.js.
1905 if (!pc_->useAsmOrInsideUseAsm()) {
1906 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
1907 return errorResult();
1908 }
1909 }
1910 body = &node->as<ListNode>();
1911
1912 if (!this->setSourceMapInfo()) {
1913 return errorResult();
1914 }
1915
1916 // For global scripts, whether bindings are closed over or not doesn't
1917 // matter, so no need to call propagateFreeNamesAndMarkClosedOver-
1918 // Bindings. However, Annex B.3.3 functions still need to be marked.
1919 if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
1920 return errorResult();
1921 }
1922
1923 Maybe<GlobalScope::ParserData*> bindings =
1924 newGlobalScopeData(pc_->varScope());
1925 if (!bindings) {
1926 return errorResult();
1927 }
1928 globalsc->bindings = *bindings;
1929
1930 return body;
1931}
1932
1933template <typename Unit>
1934FullParseHandler::ModuleNodeResult Parser<FullParseHandler, Unit>::moduleBody(
1935 ModuleSharedContext* modulesc) {
1936 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1936); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 1936; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1937
1938 this->compilationState_.moduleMetadata =
1939 fc_->getAllocator()->template new_<StencilModuleMetadata>();
1940 if (!this->compilationState_.moduleMetadata) {
1941 return errorResult();
1942 }
1943
1944 SourceParseContext modulepc(this, modulesc, nullptr);
1945 if (!modulepc.init()) {
1946 return errorResult();
1947 }
1948
1949 ParseContext::VarScope varScope(this);
1950 if (!varScope.init(pc_)) {
1951 return errorResult();
1952 }
1953
1954 ModuleNodeType moduleNode;
1955 MOZ_TRY_VAR(moduleNode, handler_.newModule(pos()))do { auto mozTryVarTempResult_ = (handler_.newModule(pos()));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (moduleNode)
= mozTryVarTempResult_.unwrap(); } while (0)
;
1956
1957 AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(
1958 this, AwaitIsModuleKeyword);
1959 ListNode* stmtList;
1960 MOZ_TRY_VAR(stmtList, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (stmtList) =
mozTryVarTempResult_.unwrap(); } while (0)
;
1961
1962 MOZ_ASSERT(stmtList->isKind(ParseNodeKind::StatementList))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(stmtList->isKind(ParseNodeKind::StatementList))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(stmtList->isKind(ParseNodeKind::StatementList))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("stmtList->isKind(ParseNodeKind::StatementList)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1962); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stmtList->isKind(ParseNodeKind::StatementList)"
")"); do { *((volatile int*)__null) = 1962; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1963 moduleNode->setBody(&stmtList->template as<ListNode>());
1964
1965 if (pc_->isAsync()) {
1966 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_generator_())) {
1967 return errorResult();
1968 }
1969
1970 if (!pc_->declareTopLevelDotGeneratorName()) {
1971 return errorResult();
1972 }
1973 }
1974
1975 TokenKind tt;
1976 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
1977 return errorResult();
1978 }
1979 if (tt != TokenKind::Eof) {
1980 error(JSMSG_GARBAGE_AFTER_INPUT, "module", TokenKindToDesc(tt));
1981 return errorResult();
1982 }
1983
1984 // Set the module to async if an await keyword was found at the top level.
1985 if (pc_->isAsync()) {
1986 pc_->sc()->asModuleContext()->builder.noteAsync(
1987 *this->compilationState_.moduleMetadata);
1988 }
1989
1990 // Generate the Import/Export tables and store in CompilationState.
1991 if (!modulesc->builder.buildTables(*this->compilationState_.moduleMetadata)) {
1992 return errorResult();
1993 }
1994
1995 // Check exported local bindings exist and mark them as closed over.
1996 StencilModuleMetadata& moduleMetadata =
1997 *this->compilationState_.moduleMetadata;
1998 for (auto entry : moduleMetadata.localExportEntries) {
1999 DeclaredNamePtr p = modulepc.varScope().lookupDeclaredName(entry.localName);
2000 if (!p) {
2001 UniqueChars str = this->parserAtoms().toPrintableString(entry.localName);
2002 if (!str) {
2003 ReportOutOfMemory(this->fc_);
2004 return errorResult();
2005 }
2006
2007 errorNoOffset(JSMSG_MISSING_EXPORT, str.get());
2008 return errorResult();
2009 }
2010
2011 p->value()->setClosedOver();
2012 }
2013
2014 // Reserve an environment slot for a "*namespace*" psuedo-binding and mark as
2015 // closed-over. We do not know until module linking if this will be used.
2016 if (!noteDeclaredName(
2017 TaggedParserAtomIndex::WellKnown::star_namespace_star_(),
2018 DeclarationKind::Const, pos())) {
2019 return errorResult();
2020 }
2021 modulepc.varScope()
2022 .lookupDeclaredName(
2023 TaggedParserAtomIndex::WellKnown::star_namespace_star_())
2024 ->value()
2025 ->setClosedOver();
2026
2027 if (options().deoptimizeModuleGlobalVars) {
2028 for (BindingIter bi = modulepc.varScope().bindings(pc_); bi; bi++) {
2029 bi.setClosedOver();
2030 }
2031 }
2032
2033 if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
2034 return errorResult();
2035 }
2036
2037 ParseNode* node = stmtList;
2038 // Don't constant-fold inside "use asm" code, as this could create a parse
2039 // tree that doesn't type-check as asm.js.
2040 if (!pc_->useAsmOrInsideUseAsm()) {
2041 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
2042 return errorResult();
2043 }
2044 }
2045 stmtList = &node->as<ListNode>();
2046
2047 if (!this->setSourceMapInfo()) {
2048 return errorResult();
2049 }
2050
2051 // Private names not lexically defined must trigger a syntax error.
2052 if (!checkForUndefinedPrivateFields()) {
2053 return errorResult();
2054 }
2055
2056 if (!propagateFreeNamesAndMarkClosedOverBindings(modulepc.varScope())) {
2057 return errorResult();
2058 }
2059
2060 Maybe<ModuleScope::ParserData*> bindings =
2061 newModuleScopeData(modulepc.varScope());
2062 if (!bindings) {
2063 return errorResult();
2064 }
2065
2066 modulesc->bindings = *bindings;
2067 return moduleNode;
2068}
2069
2070template <typename Unit>
2071SyntaxParseHandler::ModuleNodeResult
2072Parser<SyntaxParseHandler, Unit>::moduleBody(ModuleSharedContext* modulesc) {
2073 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2073); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 2073; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
2074 return errorResult();
2075}
2076
2077template <class ParseHandler>
2078typename ParseHandler::NameNodeResult
2079PerHandlerParser<ParseHandler>::newInternalDotName(TaggedParserAtomIndex name) {
2080 NameNodeType nameNode;
2081 MOZ_TRY_VAR(nameNode, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nameNode) = mozTryVarTempResult_.unwrap()
; } while (0)
;
2082 if (!noteUsedName(name)) {
2083 return errorResult();
2084 }
2085 return nameNode;
2086}
2087
2088template <class ParseHandler>
2089typename ParseHandler::NameNodeResult
2090PerHandlerParser<ParseHandler>::newThisName() {
2091 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_this_());
2092}
2093
2094template <class ParseHandler>
2095typename ParseHandler::NameNodeResult
2096PerHandlerParser<ParseHandler>::newNewTargetName() {
2097 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_newTarget_());
2098}
2099
2100template <class ParseHandler>
2101typename ParseHandler::NameNodeResult
2102PerHandlerParser<ParseHandler>::newDotGeneratorName() {
2103 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_generator_());
2104}
2105
2106template <class ParseHandler>
2107bool PerHandlerParser<ParseHandler>::finishFunctionScopes(
2108 bool isStandaloneFunction) {
2109 FunctionBox* funbox = pc_->functionBox();
2110
2111 if (funbox->hasParameterExprs) {
2112 if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->functionScope())) {
2113 return false;
2114 }
2115
2116 // Functions with parameter expressions utilize the FunctionScope for vars
2117 // generated by sloppy-direct-evals, as well as arguments (which are
2118 // lexicals bindings). If the function body has var bindings (or has a
2119 // sloppy-direct-eval that might), then an extra VarScope must be created
2120 // for them.
2121 if (VarScopeHasBindings(pc_) ||
2122 funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings()) {
2123 funbox->setFunctionHasExtraBodyVarScope();
2124 }
2125 }
2126
2127 // See: JSFunction::needsCallObject()
2128 if (FunctionScopeHasClosedOverBindings(pc_) ||
2129 funbox->needsCallObjectRegardlessOfBindings()) {
2130 funbox->setNeedsFunctionEnvironmentObjects();
2131 }
2132
2133 if (funbox->isNamedLambda() && !isStandaloneFunction) {
2134 if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->namedLambdaScope())) {
2135 return false;
2136 }
2137
2138 // See: JSFunction::needsNamedLambdaEnvironment()
2139 if (LexicalScopeHasClosedOverBindings(pc_, pc_->namedLambdaScope())) {
2140 funbox->setNeedsFunctionEnvironmentObjects();
2141 }
2142 }
2143
2144 return true;
2145}
2146
2147template <>
2148bool PerHandlerParser<FullParseHandler>::finishFunction(
2149 bool isStandaloneFunction /* = false */) {
2150 if (!finishFunctionScopes(isStandaloneFunction)) {
2151 return false;
2152 }
2153
2154 FunctionBox* funbox = pc_->functionBox();
2155 ScriptStencil& script = funbox->functionStencil();
2156
2157 if (funbox->isInterpreted()) {
2158 // BCE will need to generate bytecode for this.
2159 funbox->emitBytecode = true;
2160 this->compilationState_.nonLazyFunctionCount++;
2161 }
2162
2163 bool hasParameterExprs = funbox->hasParameterExprs;
2164
2165 if (hasParameterExprs) {
2166 Maybe<VarScope::ParserData*> bindings = newVarScopeData(pc_->varScope());
2167 if (!bindings) {
2168 return false;
2169 }
2170 funbox->setExtraVarScopeBindings(*bindings);
2171
2172 MOZ_ASSERT(bool(*bindings) == VarScopeHasBindings(pc_))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bool(*bindings) == VarScopeHasBindings(pc_))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(bool(*bindings) == VarScopeHasBindings(pc_)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("bool(*bindings) == VarScopeHasBindings(pc_)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2172); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == VarScopeHasBindings(pc_)"
")"); do { *((volatile int*)__null) = 2172; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2173 MOZ_ASSERT_IF(!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings(),do { if (!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings
()) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(bool(*bindings) == funbox->functionHasExtraBodyVarScope
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bool(*bindings) == funbox->functionHasExtraBodyVarScope
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2174); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
")"); do { *((volatile int*)__null) = 2174; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2174 bool(*bindings) == funbox->functionHasExtraBodyVarScope())do { if (!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings
()) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(bool(*bindings) == funbox->functionHasExtraBodyVarScope
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bool(*bindings) == funbox->functionHasExtraBodyVarScope
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2174); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
")"); do { *((volatile int*)__null) = 2174; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2175 }
2176
2177 {
2178 Maybe<FunctionScope::ParserData*> bindings =
2179 newFunctionScopeData(pc_->functionScope(), hasParameterExprs);
2180 if (!bindings) {
2181 return false;
2182 }
2183 funbox->setFunctionScopeBindings(*bindings);
2184 }
2185
2186 if (funbox->isNamedLambda() && !isStandaloneFunction) {
2187 Maybe<LexicalScope::ParserData*> bindings =
2188 newLexicalScopeData(pc_->namedLambdaScope());
2189 if (!bindings) {
2190 return false;
2191 }
2192 funbox->setNamedLambdaBindings(*bindings);
2193 }
2194
2195 funbox->finishScriptFlags();
2196 funbox->copyFunctionFields(script);
2197
2198 if (this->compilationState_.isInitialStencil()) {
2199 ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
2200 funbox->copyFunctionExtraFields(scriptExtra);
2201 funbox->copyScriptExtraFields(scriptExtra);
2202 }
2203
2204 return true;
2205}
2206
2207template <>
2208bool PerHandlerParser<SyntaxParseHandler>::finishFunction(
2209 bool isStandaloneFunction /* = false */) {
2210 // The BaseScript for a lazily parsed function needs to know its set of
2211 // free variables and inner functions so that when it is fully parsed, we
2212 // can skip over any already syntax parsed inner functions and still
2213 // retain correct scope information.
2214
2215 if (!finishFunctionScopes(isStandaloneFunction)) {
2216 return false;
2217 }
2218
2219 FunctionBox* funbox = pc_->functionBox();
2220 ScriptStencil& script = funbox->functionStencil();
2221
2222 funbox->finishScriptFlags();
2223 funbox->copyFunctionFields(script);
2224
2225 ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
2226 funbox->copyFunctionExtraFields(scriptExtra);
2227 funbox->copyScriptExtraFields(scriptExtra);
2228
2229 // Elide nullptr sentinels from end of binding list. These are inserted for
2230 // each scope regardless of if any bindings are actually closed over.
2231 {
2232 AtomVector& closedOver = pc_->closedOverBindingsForLazy();
2233 while (!closedOver.empty() && !closedOver.back()) {
2234 closedOver.popBack();
2235 }
2236 }
2237
2238 // Check if we will overflow the `ngcthings` field later.
2239 mozilla::CheckedUint32 ngcthings =
2240 mozilla::CheckedUint32(pc_->innerFunctionIndexesForLazy.length()) +
2241 mozilla::CheckedUint32(pc_->closedOverBindingsForLazy().length());
2242 if (!ngcthings.isValid()) {
2243 ReportAllocationOverflow(fc_);
2244 return false;
2245 }
2246
2247 // If there are no script-things, we can return early without allocating.
2248 if (ngcthings.value() == 0) {
2249 MOZ_ASSERT(!script.hasGCThings())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!script.hasGCThings())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!script.hasGCThings()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!script.hasGCThings()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2249); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!script.hasGCThings()"
")"); do { *((volatile int*)__null) = 2249; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2250 return true;
2251 }
2252
2253 TaggedScriptThingIndex* cursor = nullptr;
2254 if (!this->compilationState_.allocateGCThingsUninitialized(
2255 fc_, funbox->index(), ngcthings.value(), &cursor)) {
2256 return false;
2257 }
2258
2259 // Copy inner-function and closed-over-binding info for the stencil. The order
2260 // is important here. We emit functions first, followed by the bindings info.
2261 // The bindings list uses nullptr as delimiter to separates the bindings per
2262 // scope.
2263 //
2264 // See: FullParseHandler::nextLazyInnerFunction(),
2265 // FullParseHandler::nextLazyClosedOverBinding()
2266 for (const ScriptIndex& index : pc_->innerFunctionIndexesForLazy) {
2267 void* raw = &(*cursor++);
2268 new (raw) TaggedScriptThingIndex(index);
2269 }
2270 for (auto binding : pc_->closedOverBindingsForLazy()) {
2271 void* raw = &(*cursor++);
2272 if (binding) {
2273 this->parserAtoms().markUsedByStencil(binding, ParserAtom::Atomize::Yes);
2274 new (raw) TaggedScriptThingIndex(binding);
2275 } else {
2276 new (raw) TaggedScriptThingIndex();
2277 }
2278 }
2279
2280 return true;
2281}
2282
2283static YieldHandling GetYieldHandling(GeneratorKind generatorKind) {
2284 if (generatorKind == GeneratorKind::NotGenerator) {
2285 return YieldIsName;
2286 }
2287 return YieldIsKeyword;
2288}
2289
2290static AwaitHandling GetAwaitHandling(FunctionAsyncKind asyncKind) {
2291 if (asyncKind == FunctionAsyncKind::SyncFunction) {
2292 return AwaitIsName;
2293 }
2294 return AwaitIsKeyword;
2295}
2296
2297static FunctionFlags InitialFunctionFlags(FunctionSyntaxKind kind,
2298 GeneratorKind generatorKind,
2299 FunctionAsyncKind asyncKind,
2300 bool isSelfHosting) {
2301 FunctionFlags flags = {};
2302
2303 switch (kind) {
2304 case FunctionSyntaxKind::Expression:
2305 flags = (generatorKind == GeneratorKind::NotGenerator &&
2306 asyncKind == FunctionAsyncKind::SyncFunction
2307 ? FunctionFlags::INTERPRETED_LAMBDA
2308 : FunctionFlags::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC);
2309 break;
2310 case FunctionSyntaxKind::Arrow:
2311 flags = FunctionFlags::INTERPRETED_LAMBDA_ARROW;
2312 break;
2313 case FunctionSyntaxKind::Method:
2314 case FunctionSyntaxKind::FieldInitializer:
2315 case FunctionSyntaxKind::StaticClassBlock:
2316 flags = FunctionFlags::INTERPRETED_METHOD;
2317 break;
2318 case FunctionSyntaxKind::ClassConstructor:
2319 case FunctionSyntaxKind::DerivedClassConstructor:
2320 flags = FunctionFlags::INTERPRETED_CLASS_CTOR;
2321 break;
2322 case FunctionSyntaxKind::Getter:
2323 flags = FunctionFlags::INTERPRETED_GETTER;
2324 break;
2325 case FunctionSyntaxKind::Setter:
2326 flags = FunctionFlags::INTERPRETED_SETTER;
2327 break;
2328 default:
2329 MOZ_ASSERT(kind == FunctionSyntaxKind::Statement)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == FunctionSyntaxKind::Statement)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(kind == FunctionSyntaxKind::Statement))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("kind == FunctionSyntaxKind::Statement"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2329); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == FunctionSyntaxKind::Statement"
")"); do { *((volatile int*)__null) = 2329; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2330 flags = (generatorKind == GeneratorKind::NotGenerator &&
2331 asyncKind == FunctionAsyncKind::SyncFunction
2332 ? FunctionFlags::INTERPRETED_NORMAL
2333 : FunctionFlags::INTERPRETED_GENERATOR_OR_ASYNC);
2334 }
2335
2336 if (isSelfHosting) {
2337 flags.setIsSelfHostedBuiltin();
2338 }
2339
2340 return flags;
2341}
2342
2343template <typename Unit>
2344FullParseHandler::FunctionNodeResult
2345Parser<FullParseHandler, Unit>::standaloneFunction(
2346 const Maybe<uint32_t>& parameterListEnd, FunctionSyntaxKind syntaxKind,
2347 GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
2348 Directives inheritedDirectives, Directives* newDirectives) {
2349 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 2349; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2350 // Skip prelude.
2351 TokenKind tt;
2352 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2353 return errorResult();
2354 }
2355 if (asyncKind == FunctionAsyncKind::AsyncFunction) {
2356 MOZ_ASSERT(tt == TokenKind::Async)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::Async)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::Async))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("tt == TokenKind::Async"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2356); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Async"
")"); do { *((volatile int*)__null) = 2356; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2357 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2358 return errorResult();
2359 }
2360 }
2361 MOZ_ASSERT(tt == TokenKind::Function)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::Function)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::Function)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("tt == TokenKind::Function"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2361); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Function"
")"); do { *((volatile int*)__null) = 2361; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2362
2363 if (!tokenStream.getToken(&tt)) {
2364 return errorResult();
2365 }
2366 if (generatorKind == GeneratorKind::Generator) {
2367 MOZ_ASSERT(tt == TokenKind::Mul)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::Mul)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::Mul))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("tt == TokenKind::Mul"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2367); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Mul"
")"); do { *((volatile int*)__null) = 2367; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2368 if (!tokenStream.getToken(&tt)) {
2369 return errorResult();
2370 }
2371 }
2372
2373 // Skip function name, if present.
2374 TaggedParserAtomIndex explicitName;
2375 if (TokenKindIsPossibleIdentifierName(tt)) {
2376 explicitName = anyChars.currentName();
2377 } else {
2378 anyChars.ungetToken();
2379 }
2380
2381 FunctionNodeType funNode;
2382 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
2383
2384 ParamsBodyNodeType argsbody;
2385 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(pos()))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(pos(
))); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
2386 funNode->setBody(argsbody);
2387
2388 bool isSelfHosting = options().selfHostingMode;
2389 FunctionFlags flags =
2390 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
2391 FunctionBox* funbox =
2392 newFunctionBox(funNode, explicitName, flags, /* toStringStart = */ 0,
2393 inheritedDirectives, generatorKind, asyncKind);
2394 if (!funbox) {
2395 return errorResult();
2396 }
2397
2398 // Function is not syntactically part of another script.
2399 MOZ_ASSERT(funbox->index() == CompilationStencil::TopLevelIndex)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->index() == CompilationStencil::TopLevelIndex
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(funbox->index() == CompilationStencil::TopLevelIndex
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"funbox->index() == CompilationStencil::TopLevelIndex", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2399); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->index() == CompilationStencil::TopLevelIndex"
")"); do { *((volatile int*)__null) = 2399; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2400
2401 funbox->initStandalone(this->compilationState_.scopeContext, syntaxKind);
2402
2403 SourceParseContext funpc(this, funbox, newDirectives);
2404 if (!funpc.init()) {
2405 return errorResult();
2406 }
2407
2408 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
2409 AwaitHandling awaitHandling = GetAwaitHandling(asyncKind);
2410 AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(this,
2411 awaitHandling);
2412 if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
2413 syntaxKind, parameterListEnd,
2414 /* isStandaloneFunction = */ true)) {
2415 return errorResult();
2416 }
2417
2418 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2419 return errorResult();
2420 }
2421 if (tt != TokenKind::Eof) {
2422 error(JSMSG_GARBAGE_AFTER_INPUT, "function body", TokenKindToDesc(tt));
2423 return errorResult();
2424 }
2425
2426 if (!CheckParseTree(this->fc_, alloc_, funNode)) {
2427 return errorResult();
2428 }
2429
2430 ParseNode* node = funNode;
2431 // Don't constant-fold inside "use asm" code, as this could create a parse
2432 // tree that doesn't type-check as asm.js.
2433 if (!pc_->useAsmOrInsideUseAsm()) {
2434 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
2435 return errorResult();
2436 }
2437 }
2438 funNode = &node->as<FunctionNode>();
2439
2440 if (!checkForUndefinedPrivateFields(nullptr)) {
2441 return errorResult();
2442 }
2443
2444 if (!this->setSourceMapInfo()) {
2445 return errorResult();
2446 }
2447
2448 return funNode;
2449}
2450
2451template <class ParseHandler, typename Unit>
2452typename ParseHandler::LexicalScopeNodeResult
2453GeneralParser<ParseHandler, Unit>::functionBody(InHandling inHandling,
2454 YieldHandling yieldHandling,
2455 FunctionSyntaxKind kind,
2456 FunctionBodyType type) {
2457 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2457); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 2457; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2458
2459#ifdef DEBUG1
2460 uint32_t startYieldOffset = pc_->lastYieldOffset;
2461#endif
2462
2463 Node body;
2464 if (type == StatementListBody) {
2465 bool inheritedStrict = pc_->sc()->strict();
2466 MOZ_TRY_VAR(body, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
2467
2468 // When we transitioned from non-strict to strict mode, we need to
2469 // validate that all parameter names are valid strict mode names.
2470 if (!inheritedStrict && pc_->sc()->strict()) {
2471 MOZ_ASSERT(pc_->sc()->hasExplicitUseStrict(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2473; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2472 "strict mode should only change when a 'use strict' directive "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2473; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2473 "is present")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2473; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
2474 if (!hasValidSimpleStrictParameterNames()) {
2475 // Request that this function be reparsed as strict to report
2476 // the invalid parameter name at the correct source location.
2477 pc_->newDirectives->setStrict();
2478 return errorResult();
2479 }
2480 }
2481 } else {
2482 MOZ_ASSERT(type == ExpressionBody)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type == ExpressionBody)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(type == ExpressionBody))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("type == ExpressionBody"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2482); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == ExpressionBody"
")"); do { *((volatile int*)__null) = 2482; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2483
2484 // Async functions are implemented as generators, and generators are
2485 // assumed to be statement lists, to prepend initial `yield`.
2486 ListNodeType stmtList = null();
2487 if (pc_->isAsync()) {
2488 MOZ_TRY_VAR(stmtList, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
2489 }
2490
2491 Node kid;
2492 MOZ_TRY_VAR(kid,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
2493 assignExpr(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
2494
2495 MOZ_TRY_VAR(body, handler_.newExpressionBody(kid))do { auto mozTryVarTempResult_ = (handler_.newExpressionBody(
kid)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr())
, 0))) { return mozTryVarTempResult_.propagateErr(); } (body)
= mozTryVarTempResult_.unwrap(); } while (0)
;
2496
2497 if (pc_->isAsync()) {
2498 handler_.addStatementToList(stmtList, body);
2499 body = stmtList;
2500 }
2501 }
2502
2503 MOZ_ASSERT_IF(!pc_->isGenerator() && !pc_->isAsync(),do { if (!pc_->isGenerator() && !pc_->isAsync()
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(pc_->lastYieldOffset == startYieldOffset)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->lastYieldOffset == startYieldOffset))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("pc_->lastYieldOffset == startYieldOffset"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2504); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->lastYieldOffset == startYieldOffset"
")"); do { *((volatile int*)__null) = 2504; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2504 pc_->lastYieldOffset == startYieldOffset)do { if (!pc_->isGenerator() && !pc_->isAsync()
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(pc_->lastYieldOffset == startYieldOffset)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->lastYieldOffset == startYieldOffset))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("pc_->lastYieldOffset == startYieldOffset"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2504); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->lastYieldOffset == startYieldOffset"
")"); do { *((volatile int*)__null) = 2504; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2505 MOZ_ASSERT_IF(pc_->isGenerator(), kind != FunctionSyntaxKind::Arrow)do { if (pc_->isGenerator()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(kind != FunctionSyntaxKind
::Arrow)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind != FunctionSyntaxKind::Arrow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("kind != FunctionSyntaxKind::Arrow"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2505); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind != FunctionSyntaxKind::Arrow"
")"); do { *((volatile int*)__null) = 2505; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2506 MOZ_ASSERT_IF(pc_->isGenerator(), type == StatementListBody)do { if (pc_->isGenerator()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(type == StatementListBody
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == StatementListBody))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("type == StatementListBody", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2506); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == StatementListBody"
")"); do { *((volatile int*)__null) = 2506; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2507
2508 if (pc_->needsDotGeneratorName()) {
2509 MOZ_ASSERT_IF(!pc_->isAsync(), type == StatementListBody)do { if (!pc_->isAsync()) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(type == StatementListBody
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == StatementListBody))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("type == StatementListBody", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2509); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == StatementListBody"
")"); do { *((volatile int*)__null) = 2509; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2510 if (!pc_->declareDotGeneratorName()) {
2511 return errorResult();
2512 }
2513 if (pc_->isGenerator()) {
2514 NameNodeType generator;
2515 MOZ_TRY_VAR(generator, newDotGeneratorName())do { auto mozTryVarTempResult_ = (newDotGeneratorName()); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (generator) = mozTryVarTempResult_
.unwrap(); } while (0)
;
2516 if (!handler_.prependInitialYield(handler_.asListNode(body), generator)) {
2517 return errorResult();
2518 }
2519 }
2520 }
2521
2522 if (pc_->numberOfArgumentsNames > 0 || kind == FunctionSyntaxKind::Arrow) {
2523 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2523); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 2523; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2524 pc_->sc()->setIneligibleForArgumentsLength();
2525 }
2526
2527 // Declare the 'arguments', 'this', and 'new.target' bindings if necessary
2528 // before finishing up the scope so these special bindings get marked as
2529 // closed over if necessary. Arrow functions don't have these bindings.
2530 if (kind != FunctionSyntaxKind::Arrow) {
2531 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
2532 if (!pc_->declareFunctionArgumentsObject(usedNames_,
2533 canSkipLazyClosedOverBindings)) {
2534 return errorResult();
2535 }
2536 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
2537 return errorResult();
2538 }
2539 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
2540 return errorResult();
2541 }
2542 }
2543
2544 return finishLexicalScope(pc_->varScope(), body, ScopeKind::FunctionLexical);
2545}
2546
2547template <class ParseHandler, typename Unit>
2548bool GeneralParser<ParseHandler, Unit>::matchOrInsertSemicolon(
2549 Modifier modifier /* = TokenStream::SlashIsRegExp */) {
2550 TokenKind tt = TokenKind::Eof;
2551 if (!tokenStream.peekTokenSameLine(&tt, modifier)) {
2552 return false;
2553 }
2554 if (tt != TokenKind::Eof && tt != TokenKind::Eol && tt != TokenKind::Semi &&
2555 tt != TokenKind::RightCurly) {
2556 /*
2557 * When current token is `await` and it's outside of async function,
2558 * it's possibly intended to be an await expression.
2559 *
2560 * await f();
2561 * ^
2562 * |
2563 * tried to insert semicolon here
2564 *
2565 * Detect this situation and throw an understandable error. Otherwise
2566 * we'd throw a confusing "unexpected token: (unexpected token)" error.
2567 */
2568 if (!pc_->isAsync() && anyChars.currentToken().type == TokenKind::Await) {
2569 error(JSMSG_AWAIT_OUTSIDE_ASYNC_OR_MODULE);
2570 return false;
2571 }
2572 if (!yieldExpressionsSupported() &&
2573 anyChars.currentToken().type == TokenKind::Yield) {
2574 error(JSMSG_YIELD_OUTSIDE_GENERATOR);
2575 return false;
2576 }
2577
2578#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
2579 if (!this->pc_->isUsingSyntaxAllowed() &&
2580 anyChars.currentToken().type == TokenKind::Using) {
2581 error(JSMSG_USING_OUTSIDE_BLOCK_OR_MODULE);
2582 return false;
2583 }
2584#endif
2585
2586 /* Advance the scanner for proper error location reporting. */
2587 tokenStream.consumeKnownToken(tt, modifier);
2588 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(tt));
2589 return false;
2590 }
2591 bool matched;
2592 return tokenStream.matchToken(&matched, TokenKind::Semi, modifier);
2593}
2594
2595bool ParserBase::leaveInnerFunction(ParseContext* outerpc) {
2596 MOZ_ASSERT(pc_ != outerpc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_ != outerpc)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_ != outerpc))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("pc_ != outerpc"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_ != outerpc"
")"); do { *((volatile int*)__null) = 2596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2597
2598 MOZ_ASSERT_IF(outerpc->isFunctionBox(),do { if (outerpc->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(outerpc->functionBox
()->index() < pc_->functionBox()->index())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(outerpc->functionBox()->index() < pc_->functionBox
()->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("outerpc->functionBox()->index() < pc_->functionBox()->index()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2599); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outerpc->functionBox()->index() < pc_->functionBox()->index()"
")"); do { *((volatile int*)__null) = 2599; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2599 outerpc->functionBox()->index() < pc_->functionBox()->index())do { if (outerpc->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(outerpc->functionBox
()->index() < pc_->functionBox()->index())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(outerpc->functionBox()->index() < pc_->functionBox
()->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("outerpc->functionBox()->index() < pc_->functionBox()->index()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2599); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outerpc->functionBox()->index() < pc_->functionBox()->index()"
")"); do { *((volatile int*)__null) = 2599; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2600
2601 // If the current function allows super.property but cannot have a home
2602 // object, i.e., it is an arrow function, we need to propagate the flag to
2603 // the outer ParseContext.
2604 if (pc_->superScopeNeedsHomeObject()) {
2605 if (!pc_->isArrowFunction()) {
2606 MOZ_ASSERT(pc_->functionBox()->needsHomeObject())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->functionBox()->needsHomeObject())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->functionBox()->needsHomeObject()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("pc_->functionBox()->needsHomeObject()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2606); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->needsHomeObject()"
")"); do { *((volatile int*)__null) = 2606; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2607 } else {
2608 outerpc->setSuperScopeNeedsHomeObject();
2609 }
2610 }
2611
2612 // Lazy functions inner to another lazy function need to be remembered by
2613 // the inner function so that if the outer function is eventually parsed
2614 // we do not need any further parsing or processing of the inner function.
2615 //
2616 // Append the inner function index here unconditionally; the vector is only
2617 // used if the Parser using outerpc is a syntax parsing. See
2618 // GeneralParser<SyntaxParseHandler>::finishFunction.
2619 if (!outerpc->innerFunctionIndexesForLazy.append(
2620 pc_->functionBox()->index())) {
2621 return false;
2622 }
2623
2624 PropagateTransitiveParseFlags(pc_->functionBox(), outerpc->sc());
2625
2626 return true;
2627}
2628
2629TaggedParserAtomIndex ParserBase::prefixAccessorName(
2630 PropertyType propType, TaggedParserAtomIndex propAtom) {
2631 StringBuffer prefixed(fc_);
2632 if (propType == PropertyType::Setter) {
2633 if (!prefixed.append("set ")) {
2634 return TaggedParserAtomIndex::null();
2635 }
2636 } else {
2637 if (!prefixed.append("get ")) {
2638 return TaggedParserAtomIndex::null();
2639 }
2640 }
2641 if (!prefixed.append(this->parserAtoms(), propAtom)) {
2642 return TaggedParserAtomIndex::null();
2643 }
2644 return prefixed.finishParserAtom(this->parserAtoms(), fc_);
2645}
2646
2647template <class ParseHandler, typename Unit>
2648void GeneralParser<ParseHandler, Unit>::setFunctionStartAtPosition(
2649 FunctionBox* funbox, TokenPos pos) const {
2650 uint32_t startLine;
2651 JS::LimitedColumnNumberOneOrigin startColumn;
2652 tokenStream.computeLineAndColumn(pos.begin, &startLine, &startColumn);
2653
2654 // NOTE: `Debugger::CallData::findScripts` relies on sourceStart and
2655 // lineno/column referring to the same location.
2656 funbox->setStart(pos.begin, startLine, startColumn);
2657}
2658
2659template <class ParseHandler, typename Unit>
2660void GeneralParser<ParseHandler, Unit>::setFunctionStartAtCurrentToken(
2661 FunctionBox* funbox) const {
2662 setFunctionStartAtPosition(funbox, anyChars.currentToken().pos);
2663}
2664
2665template <class ParseHandler, typename Unit>
2666bool GeneralParser<ParseHandler, Unit>::functionArguments(
2667 YieldHandling yieldHandling, FunctionSyntaxKind kind,
2668 FunctionNodeType funNode) {
2669 FunctionBox* funbox = pc_->functionBox();
2670
2671 // Modifier for the following tokens.
2672 // TokenStream::SlashIsDiv for the following cases:
2673 // async a => 1
2674 // ^
2675 //
2676 // (a) => 1
2677 // ^
2678 //
2679 // async (a) => 1
2680 // ^
2681 //
2682 // function f(a) {}
2683 // ^
2684 //
2685 // TokenStream::SlashIsRegExp for the following case:
2686 // a => 1
2687 // ^
2688 Modifier firstTokenModifier =
2689 kind != FunctionSyntaxKind::Arrow || funbox->isAsync()
2690 ? TokenStream::SlashIsDiv
2691 : TokenStream::SlashIsRegExp;
2692 TokenKind tt;
2693 if (!tokenStream.getToken(&tt, firstTokenModifier)) {
2694 return false;
2695 }
2696
2697 if (kind == FunctionSyntaxKind::Arrow && TokenKindIsPossibleIdentifier(tt)) {
2698 // Record the start of function source (for FunctionToString).
2699 setFunctionStartAtCurrentToken(funbox);
2700
2701 ParamsBodyNodeType argsbody;
2702 MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newParamsBody(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2703 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
2704
2705 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
2706 if (!name) {
2707 return false;
2708 }
2709
2710 constexpr bool disallowDuplicateParams = true;
2711 bool duplicatedParam = false;
2712 if (!notePositionalFormalParameter(funNode, name, pos().begin,
2713 disallowDuplicateParams,
2714 &duplicatedParam)) {
2715 return false;
2716 }
2717 MOZ_ASSERT(!duplicatedParam)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!duplicatedParam)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!duplicatedParam))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!duplicatedParam"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2717); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!duplicatedParam"
")"); do { *((volatile int*)__null) = 2717; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2718 MOZ_ASSERT(pc_->positionalFormalParameterNames().length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->positionalFormalParameterNames().length() ==
1)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->positionalFormalParameterNames().length() ==
1))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->positionalFormalParameterNames().length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2718); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->positionalFormalParameterNames().length() == 1"
")"); do { *((volatile int*)__null) = 2718; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2719
2720 funbox->setLength(1);
2721 funbox->setArgCount(1);
2722 return true;
2723 }
2724
2725 if (tt != TokenKind::LeftParen) {
2726 error(kind == FunctionSyntaxKind::Arrow ? JSMSG_BAD_ARROW_ARGS
2727 : JSMSG_PAREN_BEFORE_FORMAL);
2728 return false;
2729 }
2730
2731 // Record the start of function source (for FunctionToString).
2732 setFunctionStartAtCurrentToken(funbox);
2733
2734 ParamsBodyNodeType argsbody;
2735 MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newParamsBody(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2736 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
2737
2738 bool matched;
2739 if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
2740 TokenStream::SlashIsRegExp)) {
2741 return false;
2742 }
2743 if (!matched) {
2744 bool hasRest = false;
2745 bool hasDefault = false;
2746 bool duplicatedParam = false;
2747 bool disallowDuplicateParams =
2748 kind == FunctionSyntaxKind::Arrow ||
2749 kind == FunctionSyntaxKind::Method ||
2750 kind == FunctionSyntaxKind::FieldInitializer ||
2751 kind == FunctionSyntaxKind::ClassConstructor;
2752 AtomVector& positionalFormals = pc_->positionalFormalParameterNames();
2753
2754 if (kind == FunctionSyntaxKind::Getter) {
2755 error(JSMSG_ACCESSOR_WRONG_ARGS, "getter", "no", "s");
2756 return false;
2757 }
2758
2759 while (true) {
2760 if (hasRest) {
2761 error(JSMSG_PARAMETER_AFTER_REST);
2762 return false;
2763 }
2764
2765 TokenKind tt;
2766 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2767 return false;
2768 }
2769
2770 if (tt == TokenKind::TripleDot) {
2771 if (kind == FunctionSyntaxKind::Setter) {
2772 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2773 return false;
2774 }
2775
2776 disallowDuplicateParams = true;
2777 if (duplicatedParam) {
2778 // Has duplicated args before the rest parameter.
2779 error(JSMSG_BAD_DUP_ARGS);
2780 return false;
2781 }
2782
2783 hasRest = true;
2784 funbox->setHasRest();
2785
2786 if (!tokenStream.getToken(&tt)) {
2787 return false;
2788 }
2789
2790 if (!TokenKindIsPossibleIdentifier(tt) &&
2791 tt != TokenKind::LeftBracket && tt != TokenKind::LeftCurly) {
2792 error(JSMSG_NO_REST_NAME);
2793 return false;
2794 }
2795 }
2796
2797 switch (tt) {
2798 case TokenKind::LeftBracket:
2799 case TokenKind::LeftCurly: {
2800 disallowDuplicateParams = true;
2801 if (duplicatedParam) {
2802 // Has duplicated args before the destructuring parameter.
2803 error(JSMSG_BAD_DUP_ARGS);
2804 return false;
2805 }
2806
2807 funbox->hasDestructuringArgs = true;
2808
2809 Node destruct;
2810 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2811 destruct,do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2812 destructuringDeclarationWithoutYieldOrAwait(do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2813 DeclarationKind::FormalParameter, yieldHandling, tt),do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2814 false)do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
;
2815
2816 if (!noteDestructuredPositionalFormalParameter(funNode, destruct)) {
2817 return false;
2818 }
2819
2820 break;
2821 }
2822
2823 default: {
2824 if (!TokenKindIsPossibleIdentifier(tt)) {
2825 error(JSMSG_MISSING_FORMAL);
2826 return false;
2827 }
2828
2829 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
2830 if (!name) {
2831 return false;
2832 }
2833
2834 if (!notePositionalFormalParameter(funNode, name, pos().begin,
2835 disallowDuplicateParams,
2836 &duplicatedParam)) {
2837 return false;
2838 }
2839 if (duplicatedParam) {
2840 funbox->hasDuplicateParameters = true;
2841 }
2842
2843 break;
2844 }
2845 }
2846
2847 if (positionalFormals.length() >= ARGNO_LIMIT) {
2848 error(JSMSG_TOO_MANY_FUN_ARGS);
2849 return false;
2850 }
2851
2852 bool matched;
2853 if (!tokenStream.matchToken(&matched, TokenKind::Assign,
2854 TokenStream::SlashIsRegExp)) {
2855 return false;
2856 }
2857 if (matched) {
2858 if (hasRest) {
2859 error(JSMSG_REST_WITH_DEFAULT);
2860 return false;
2861 }
2862 disallowDuplicateParams = true;
2863 if (duplicatedParam) {
2864 error(JSMSG_BAD_DUP_ARGS);
2865 return false;
2866 }
2867
2868 if (!hasDefault) {
2869 hasDefault = true;
2870
2871 // The Function.length property is the number of formals
2872 // before the first default argument.
2873 funbox->setLength(positionalFormals.length() - 1);
2874 }
2875 funbox->hasParameterExprs = true;
2876
2877 Node def_expr;
2878 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (assignExprWithoutYieldOrAwait
(yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (def_expr) = parserTryVarTempResult_
.unwrap(); } while (0)
2879 def_expr, assignExprWithoutYieldOrAwait(yieldHandling), false)do { auto parserTryVarTempResult_ = (assignExprWithoutYieldOrAwait
(yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (def_expr) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2880 if (!handler_.setLastFunctionFormalParameterDefault(funNode,
2881 def_expr)) {
2882 return false;
2883 }
2884 }
2885
2886 // Setter syntax uniquely requires exactly one argument.
2887 if (kind == FunctionSyntaxKind::Setter) {
2888 break;
2889 }
2890
2891 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
2892 TokenStream::SlashIsRegExp)) {
2893 return false;
2894 }
2895 if (!matched) {
2896 break;
2897 }
2898
2899 if (!hasRest) {
2900 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
2901 return false;
2902 }
2903 if (tt == TokenKind::RightParen) {
2904 break;
2905 }
2906 }
2907 }
2908
2909 TokenKind tt;
2910 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2911 return false;
2912 }
2913 if (tt != TokenKind::RightParen) {
2914 if (kind == FunctionSyntaxKind::Setter) {
2915 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2916 return false;
2917 }
2918
2919 error(JSMSG_PAREN_AFTER_FORMAL);
2920 return false;
2921 }
2922
2923 if (!hasDefault) {
2924 funbox->setLength(positionalFormals.length() - hasRest);
2925 }
2926
2927 funbox->setArgCount(positionalFormals.length());
2928 } else if (kind == FunctionSyntaxKind::Setter) {
2929 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2930 return false;
2931 }
2932
2933 return true;
2934}
2935
2936template <typename Unit>
2937bool Parser<FullParseHandler, Unit>::skipLazyInnerFunction(
2938 FunctionNode* funNode, uint32_t toStringStart, bool tryAnnexB) {
2939 // When a lazily-parsed function is called, we only fully parse (and emit)
2940 // that function, not any of its nested children. The initial syntax-only
2941 // parse recorded the free variables of nested functions and their extents,
2942 // so we can skip over them after accounting for their free variables.
2943
2944 MOZ_ASSERT(pc_->isOutermostOfCurrentCompile())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isOutermostOfCurrentCompile())>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(pc_->isOutermostOfCurrentCompile()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->isOutermostOfCurrentCompile()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2944); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isOutermostOfCurrentCompile()"
")"); do { *((volatile int*)__null) = 2944; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2945 handler_.nextLazyInnerFunction();
2946 const ScriptStencil& cachedData = handler_.cachedScriptData();
2947 const ScriptStencilExtra& cachedExtra = handler_.cachedScriptExtra();
2948 MOZ_ASSERT(toStringStart == cachedExtra.extent.toStringStart)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(toStringStart == cachedExtra.extent.toStringStart)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(toStringStart == cachedExtra.extent.toStringStart)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("toStringStart == cachedExtra.extent.toStringStart"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2948); AnnotateMozCrashReason("MOZ_ASSERT" "(" "toStringStart == cachedExtra.extent.toStringStart"
")"); do { *((volatile int*)__null) = 2948; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2949
2950 FunctionBox* funbox = newFunctionBox(funNode, cachedData, cachedExtra);
2951 if (!funbox) {
2952 return false;
2953 }
2954
2955 ScriptStencil& script = funbox->functionStencil();
2956 funbox->copyFunctionFields(script);
2957
2958 // If the inner lazy function is class constructor, connect it to the class
2959 // statement/expression we are parsing.
2960 if (funbox->isClassConstructor()) {
2961 auto classStmt =
2962 pc_->template findInnermostStatement<ParseContext::ClassStatement>();
2963 MOZ_ASSERT(!classStmt->constructorBox)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!classStmt->constructorBox)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!classStmt->constructorBox
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!classStmt->constructorBox", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!classStmt->constructorBox"
")"); do { *((volatile int*)__null) = 2963; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2964 classStmt->constructorBox = funbox;
2965 }
2966
2967 MOZ_ASSERT_IF(pc_->isFunctionBox(),do { if (pc_->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(pc_->functionBox
()->index() < funbox->index())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->functionBox()->index
() < funbox->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->functionBox()->index() < funbox->index()",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2968); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->index() < funbox->index()"
")"); do { *((volatile int*)__null) = 2968; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2968 pc_->functionBox()->index() < funbox->index())do { if (pc_->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(pc_->functionBox
()->index() < funbox->index())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->functionBox()->index
() < funbox->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->functionBox()->index() < funbox->index()",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2968); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->index() < funbox->index()"
")"); do { *((volatile int*)__null) = 2968; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2969
2970 PropagateTransitiveParseFlags(funbox, pc_->sc());
2971
2972 if (!tokenStream.advance(funbox->extent().sourceEnd)) {
2973 return false;
2974 }
2975
2976 // Append possible Annex B function box only upon successfully parsing.
2977 if (tryAnnexB &&
2978 !pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
2979 return false;
2980 }
2981
2982 return true;
2983}
2984
2985template <typename Unit>
2986bool Parser<SyntaxParseHandler, Unit>::skipLazyInnerFunction(
2987 FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
2988 MOZ_CRASH("Cannot skip lazy inner functions when syntax parsing")do { do { } while (false); MOZ_ReportCrash("" "Cannot skip lazy inner functions when syntax parsing"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2988); AnnotateMozCrashReason("MOZ_CRASH(" "Cannot skip lazy inner functions when syntax parsing"
")"); do { *((volatile int*)__null) = 2988; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
2989}
2990
2991template <class ParseHandler, typename Unit>
2992bool GeneralParser<ParseHandler, Unit>::skipLazyInnerFunction(
2993 FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
2994 return asFinalParser()->skipLazyInnerFunction(funNode, toStringStart,
2995 tryAnnexB);
2996}
2997
2998template <class ParseHandler, typename Unit>
2999bool GeneralParser<ParseHandler, Unit>::addExprAndGetNextTemplStrToken(
3000 YieldHandling yieldHandling, ListNodeType nodeList, TokenKind* ttp) {
3001 Node pn;
3002 MOZ_TRY_VAR_OR_RETURN(pn, expr(InAllowed, yieldHandling, TripledotProhibited),do { auto parserTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (pn) = parserTryVarTempResult_
.unwrap(); } while (0)
3003 false)do { auto parserTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (pn) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3004 handler_.addList(nodeList, pn);
3005
3006 TokenKind tt;
3007 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
3008 return false;
3009 }
3010 if (tt != TokenKind::RightCurly) {
3011 error(JSMSG_TEMPLSTR_UNTERM_EXPR);
3012 return false;
3013 }
3014
3015 return tokenStream.getTemplateToken(ttp);
3016}
3017
3018template <class ParseHandler, typename Unit>
3019bool GeneralParser<ParseHandler, Unit>::taggedTemplate(
3020 YieldHandling yieldHandling, ListNodeType tagArgsList, TokenKind tt) {
3021 CallSiteNodeType callSiteObjNode;
3022 MOZ_TRY_VAR_OR_RETURN(callSiteObjNode,do { auto parserTryVarTempResult_ = (handler_.newCallSiteObject
(pos().begin)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (callSiteObjNode) = parserTryVarTempResult_
.unwrap(); } while (0)
3023 handler_.newCallSiteObject(pos().begin), false)do { auto parserTryVarTempResult_ = (handler_.newCallSiteObject
(pos().begin)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (callSiteObjNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3024 handler_.addList(tagArgsList, callSiteObjNode);
3025
3026 pc_->sc()->setHasCallSiteObj();
3027
3028 while (true) {
3029 if (!appendToCallSiteObj(callSiteObjNode)) {
3030 return false;
3031 }
3032 if (tt != TokenKind::TemplateHead) {
3033 break;
3034 }
3035
3036 if (!addExprAndGetNextTemplStrToken(yieldHandling, tagArgsList, &tt)) {
3037 return false;
3038 }
3039 }
3040 handler_.setEndPosition(tagArgsList, callSiteObjNode);
3041 return true;
3042}
3043
3044template <class ParseHandler, typename Unit>
3045typename ParseHandler::ListNodeResult
3046GeneralParser<ParseHandler, Unit>::templateLiteral(
3047 YieldHandling yieldHandling) {
3048 NameNodeType literal;
3049 MOZ_TRY_VAR(literal, noSubstitutionUntaggedTemplate())do { auto mozTryVarTempResult_ = (noSubstitutionUntaggedTemplate
()); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
3050
3051 ListNodeType nodeList;
3052 MOZ_TRY_VAR(nodeList,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::TemplateStringListExpr, literal)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nodeList) = mozTryVarTempResult_.unwrap()
; } while (0)
3053 handler_.newList(ParseNodeKind::TemplateStringListExpr, literal))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::TemplateStringListExpr, literal)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nodeList) = mozTryVarTempResult_.unwrap()
; } while (0)
;
3054
3055 TokenKind tt;
3056 do {
3057 if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt)) {
3058 return errorResult();
3059 }
3060
3061 MOZ_TRY_VAR(literal, noSubstitutionUntaggedTemplate())do { auto mozTryVarTempResult_ = (noSubstitutionUntaggedTemplate
()); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
3062
3063 handler_.addList(nodeList, literal);
3064 } while (tt == TokenKind::TemplateHead);
3065 return nodeList;
3066}
3067
3068template <class ParseHandler, typename Unit>
3069typename ParseHandler::FunctionNodeResult
3070GeneralParser<ParseHandler, Unit>::functionDefinition(
3071 FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
3072 YieldHandling yieldHandling, TaggedParserAtomIndex funName,
3073 FunctionSyntaxKind kind, GeneratorKind generatorKind,
3074 FunctionAsyncKind asyncKind, bool tryAnnexB /* = false */) {
3075 MOZ_ASSERT_IF(kind == FunctionSyntaxKind::Statement, funName)do { if (kind == FunctionSyntaxKind::Statement) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(funName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(funName))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3075); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funName" ")"
); do { *((volatile int*)__null) = 3075; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3076
3077 // If we see any inner function, note it on our current context. The bytecode
3078 // emitter may eliminate the function later, but we use a conservative
3079 // definition for consistency between lazy and full parsing.
3080 pc_->sc()->setHasInnerFunctions();
3081
3082 // When fully parsing a lazy script, we do not fully reparse its inner
3083 // functions, which are also lazy. Instead, their free variables and source
3084 // extents are recorded and may be skipped.
3085 if (handler_.reuseLazyInnerFunctions()) {
3086 if (!skipLazyInnerFunction(funNode, toStringStart, tryAnnexB)) {
3087 return errorResult();
3088 }
3089
3090 return funNode;
3091 }
3092
3093 bool isSelfHosting = options().selfHostingMode;
3094 FunctionFlags flags =
3095 InitialFunctionFlags(kind, generatorKind, asyncKind, isSelfHosting);
3096
3097 // Self-hosted functions with special function names require extended slots
3098 // for various purposes.
3099 bool forceExtended =
3100 isSelfHosting && funName &&
3101 this->parserAtoms().isExtendedUnclonedSelfHostedFunctionName(funName);
3102 if (forceExtended) {
3103 flags.setIsExtended();
3104 }
3105
3106 // Speculatively parse using the directives of the parent parsing context.
3107 // If a directive is encountered (e.g., "use strict") that changes how the
3108 // function should have been parsed, we backup and reparse with the new set
3109 // of directives.
3110 Directives directives(pc_);
3111 Directives newDirectives = directives;
3112
3113 Position start(tokenStream);
3114 auto startObj = this->compilationState_.getPosition();
3115
3116 // Parse the inner function. The following is a loop as we may attempt to
3117 // reparse a function due to failed syntax parsing and encountering new
3118 // "use foo" directives.
3119 while (true) {
3120 if (trySyntaxParseInnerFunction(&funNode, funName, flags, toStringStart,
3121 inHandling, yieldHandling, kind,
3122 generatorKind, asyncKind, tryAnnexB,
3123 directives, &newDirectives)) {
3124 break;
3125 }
3126
3127 // Return on error.
3128 if (anyChars.hadError() || directives == newDirectives) {
3129 return errorResult();
3130 }
3131
3132 // Assignment must be monotonic to prevent infinitely attempting to
3133 // reparse.
3134 MOZ_ASSERT_IF(directives.strict(), newDirectives.strict())do { if (directives.strict()) { do { static_assert( mozilla::
detail::AssertionConditionType<decltype(newDirectives.strict
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(newDirectives.strict()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("newDirectives.strict()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3134); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newDirectives.strict()"
")"); do { *((volatile int*)__null) = 3134; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3135 MOZ_ASSERT_IF(directives.asmJS(), newDirectives.asmJS())do { if (directives.asmJS()) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(newDirectives.asmJS())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(newDirectives.asmJS()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("newDirectives.asmJS()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3135); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newDirectives.asmJS()"
")"); do { *((volatile int*)__null) = 3135; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3136 directives = newDirectives;
3137
3138 // Rewind to retry parsing with new directives applied.
3139 tokenStream.rewind(start);
3140 this->compilationState_.rewind(startObj);
3141
3142 // functionFormalParametersAndBody may have already set body before failing.
3143 handler_.setFunctionFormalParametersAndBody(funNode, null());
3144 }
3145
3146 return funNode;
3147}
3148
3149template <typename Unit>
3150bool Parser<FullParseHandler, Unit>::advancePastSyntaxParsedFunction(
3151 SyntaxParser* syntaxParser) {
3152 MOZ_ASSERT(getSyntaxParser() == syntaxParser)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(getSyntaxParser() == syntaxParser)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(getSyntaxParser() == syntaxParser
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"getSyntaxParser() == syntaxParser", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3152); AnnotateMozCrashReason("MOZ_ASSERT" "(" "getSyntaxParser() == syntaxParser"
")"); do { *((volatile int*)__null) = 3152; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3153
3154 // Advance this parser over tokens processed by the syntax parser.
3155 Position currentSyntaxPosition(syntaxParser->tokenStream);
3156 if (!tokenStream.fastForward(currentSyntaxPosition, syntaxParser->anyChars)) {
3157 return false;
3158 }
3159
3160 anyChars.adoptState(syntaxParser->anyChars);
3161 tokenStream.adoptState(syntaxParser->tokenStream);
3162 return true;
3163}
3164
3165template <typename Unit>
3166bool Parser<FullParseHandler, Unit>::trySyntaxParseInnerFunction(
3167 FunctionNode** funNode, TaggedParserAtomIndex explicitName,
3168 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3169 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3170 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3171 Directives inheritedDirectives, Directives* newDirectives) {
3172 // Try a syntax parse for this inner function.
3173 do {
3174 // If we're assuming this function is an IIFE, always perform a full
3175 // parse to avoid the overhead of a lazy syntax-only parse. Although
3176 // the prediction may be incorrect, IIFEs are common enough that it
3177 // pays off for lots of code.
3178 if ((*funNode)->isLikelyIIFE() &&
3179 generatorKind == GeneratorKind::NotGenerator &&
3180 asyncKind == FunctionAsyncKind::SyncFunction) {
3181 break;
3182 }
3183
3184 SyntaxParser* syntaxParser = getSyntaxParser();
3185 if (!syntaxParser) {
3186 break;
3187 }
3188
3189 UsedNameTracker::RewindToken token = usedNames_.getRewindToken();
3190 auto statePosition = this->compilationState_.getPosition();
3191
3192 // Move the syntax parser to the current position in the stream. In the
3193 // common case this seeks forward, but it'll also seek backward *at least*
3194 // when arrow functions appear inside arrow function argument defaults
3195 // (because we rewind to reparse arrow functions once we're certain they're
3196 // arrow functions):
3197 //
3198 // var x = (y = z => 2) => q;
3199 // // ^ we first seek to here to syntax-parse this function
3200 // // ^ then we seek back to here to syntax-parse the outer function
3201 Position currentPosition(tokenStream);
3202 if (!syntaxParser->tokenStream.seekTo(currentPosition, anyChars)) {
3203 return false;
3204 }
3205
3206 // Make a FunctionBox before we enter the syntax parser, because |pn|
3207 // still expects a FunctionBox to be attached to it during BCE, and
3208 // the syntax parser cannot attach one to it.
3209 FunctionBox* funbox =
3210 newFunctionBox(*funNode, explicitName, flags, toStringStart,
3211 inheritedDirectives, generatorKind, asyncKind);
3212 if (!funbox) {
3213 return false;
3214 }
3215 funbox->initWithEnclosingParseContext(pc_, kind);
3216
3217 auto syntaxNodeResult = syntaxParser->innerFunctionForFunctionBox(
3218 SyntaxParseHandler::Node::NodeGeneric, pc_, funbox, inHandling,
3219 yieldHandling, kind, newDirectives);
3220 if (syntaxNodeResult.isErr()) {
3221 if (syntaxParser->hadAbortedSyntaxParse()) {
3222 // Try again with a full parse. UsedNameTracker needs to be
3223 // rewound to just before we tried the syntax parse for
3224 // correctness.
3225 syntaxParser->clearAbortedSyntaxParse();
3226 usedNames_.rewind(token);
3227 this->compilationState_.rewind(statePosition);
3228 MOZ_ASSERT(!fc_->hadErrors())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!fc_->hadErrors())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!fc_->hadErrors()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!fc_->hadErrors()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3228); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!fc_->hadErrors()"
")"); do { *((volatile int*)__null) = 3228; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3229 break;
3230 }
3231 return false;
3232 }
3233
3234 if (!advancePastSyntaxParsedFunction(syntaxParser)) {
3235 return false;
3236 }
3237
3238 // Update the end position of the parse node.
3239 (*funNode)->pn_pos.end = anyChars.currentToken().pos.end;
3240
3241 // Append possible Annex B function box only upon successfully parsing.
3242 if (tryAnnexB) {
3243 if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
3244 return false;
3245 }
3246 }
3247
3248 return true;
3249 } while (false);
3250
3251 // We failed to do a syntax parse above, so do the full parse.
3252 FunctionNodeType innerFunc;
3253 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3254 innerFunc,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3255 innerFunction(*funNode, pc_, explicitName, flags, toStringStart,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3256 inHandling, yieldHandling, kind, generatorKind, asyncKind,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3257 tryAnnexB, inheritedDirectives, newDirectives),do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3258 false)do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3259
3260 *funNode = innerFunc;
3261 return true;
3262}
3263
3264template <typename Unit>
3265bool Parser<SyntaxParseHandler, Unit>::trySyntaxParseInnerFunction(
3266 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
3267 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3268 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3269 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3270 Directives inheritedDirectives, Directives* newDirectives) {
3271 // This is already a syntax parser, so just parse the inner function.
3272 FunctionNodeType innerFunc;
3273 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3274 innerFunc,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3275 innerFunction(*funNode, pc_, explicitName, flags, toStringStart,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3276 inHandling, yieldHandling, kind, generatorKind, asyncKind,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3277 tryAnnexB, inheritedDirectives, newDirectives),do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3278 false)do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3279
3280 *funNode = innerFunc;
3281 return true;
3282}
3283
3284template <class ParseHandler, typename Unit>
3285inline bool GeneralParser<ParseHandler, Unit>::trySyntaxParseInnerFunction(
3286 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
3287 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3288 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3289 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3290 Directives inheritedDirectives, Directives* newDirectives) {
3291 return asFinalParser()->trySyntaxParseInnerFunction(
3292 funNode, explicitName, flags, toStringStart, inHandling, yieldHandling,
3293 kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives,
3294 newDirectives);
3295}
3296
3297template <class ParseHandler, typename Unit>
3298typename ParseHandler::FunctionNodeResult
3299GeneralParser<ParseHandler, Unit>::innerFunctionForFunctionBox(
3300 FunctionNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
3301 InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
3302 Directives* newDirectives) {
3303 // Note that it is possible for outerpc != this->pc_, as we may be
3304 // attempting to syntax parse an inner function from an outer full
3305 // parser. In that case, outerpc is a SourceParseContext from the full parser
3306 // instead of the current top of the stack of the syntax parser.
3307
3308 // Push a new ParseContext.
3309 SourceParseContext funpc(this, funbox, newDirectives);
3310 if (!funpc.init()) {
3311 return errorResult();
3312 }
3313
3314 if (!functionFormalParametersAndBody(inHandling, yieldHandling, &funNode,
3315 kind)) {
3316 return errorResult();
3317 }
3318
3319 if (!leaveInnerFunction(outerpc)) {
3320 return errorResult();
3321 }
3322
3323 return funNode;
3324}
3325
3326template <class ParseHandler, typename Unit>
3327typename ParseHandler::FunctionNodeResult
3328GeneralParser<ParseHandler, Unit>::innerFunction(
3329 FunctionNodeType funNode, ParseContext* outerpc,
3330 TaggedParserAtomIndex explicitName, FunctionFlags flags,
3331 uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
3332 FunctionSyntaxKind kind, GeneratorKind generatorKind,
3333 FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
3334 Directives* newDirectives) {
3335 // Note that it is possible for outerpc != this->pc_, as we may be
3336 // attempting to syntax parse an inner function from an outer full
3337 // parser. In that case, outerpc is a SourceParseContext from the full parser
3338 // instead of the current top of the stack of the syntax parser.
3339
3340 FunctionBox* funbox =
3341 newFunctionBox(funNode, explicitName, flags, toStringStart,
3342 inheritedDirectives, generatorKind, asyncKind);
3343 if (!funbox) {
3344 return errorResult();
3345 }
3346 funbox->initWithEnclosingParseContext(outerpc, kind);
3347
3348 FunctionNodeType innerFunc;
3349 MOZ_TRY_VAR(innerFunc,do { auto mozTryVarTempResult_ = (innerFunctionForFunctionBox
(funNode, outerpc, funbox, inHandling, yieldHandling, kind, newDirectives
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerFunc
) = mozTryVarTempResult_.unwrap(); } while (0)
3350 innerFunctionForFunctionBox(funNode, outerpc, funbox, inHandling,do { auto mozTryVarTempResult_ = (innerFunctionForFunctionBox
(funNode, outerpc, funbox, inHandling, yieldHandling, kind, newDirectives
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerFunc
) = mozTryVarTempResult_.unwrap(); } while (0)
3351 yieldHandling, kind, newDirectives))do { auto mozTryVarTempResult_ = (innerFunctionForFunctionBox
(funNode, outerpc, funbox, inHandling, yieldHandling, kind, newDirectives
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerFunc
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3352
3353 // Append possible Annex B function box only upon successfully parsing.
3354 if (tryAnnexB) {
3355 if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
3356 return errorResult();
3357 }
3358 }
3359
3360 return innerFunc;
3361}
3362
3363template <class ParseHandler, typename Unit>
3364bool GeneralParser<ParseHandler, Unit>::appendToCallSiteObj(
3365 CallSiteNodeType callSiteObj) {
3366 Node cookedNode;
3367 MOZ_TRY_VAR_OR_RETURN(cookedNode, noSubstitutionTaggedTemplate(), false)do { auto parserTryVarTempResult_ = (noSubstitutionTaggedTemplate
()); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()
), 0))) { return (false); } (cookedNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3368
3369 auto atom = tokenStream.getRawTemplateStringAtom();
3370 if (!atom) {
3371 return false;
3372 }
3373 NameNodeType rawNode;
3374 MOZ_TRY_VAR_OR_RETURN(rawNode, handler_.newTemplateStringLiteral(atom, pos()),do { auto parserTryVarTempResult_ = (handler_.newTemplateStringLiteral
(atom, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (rawNode) = parserTryVarTempResult_
.unwrap(); } while (0)
3375 false)do { auto parserTryVarTempResult_ = (handler_.newTemplateStringLiteral
(atom, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (rawNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3376
3377 handler_.addToCallSiteObject(callSiteObj, rawNode, cookedNode);
3378 return true;
3379}
3380
3381template <typename Unit>
3382FullParseHandler::FunctionNodeResult
3383Parser<FullParseHandler, Unit>::standaloneLazyFunction(
3384 CompilationInput& input, uint32_t toStringStart, bool strict,
3385 GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
3386 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3386); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 3386; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3387
3388 FunctionSyntaxKind syntaxKind = input.functionSyntaxKind();
3389 FunctionNodeType funNode;
3390 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3391
3392 TaggedParserAtomIndex displayAtom =
3393 this->getCompilationState().previousParseCache.displayAtom();
3394
3395 Directives directives(strict);
3396 FunctionBox* funbox =
3397 newFunctionBox(funNode, displayAtom, input.functionFlags(), toStringStart,
3398 directives, generatorKind, asyncKind);
3399 if (!funbox) {
3400 return errorResult();
3401 }
3402 const ScriptStencilExtra& funExtra =
3403 this->getCompilationState().previousParseCache.funExtra();
3404 funbox->initFromLazyFunction(
3405 funExtra, this->getCompilationState().scopeContext, syntaxKind);
3406 if (funbox->useMemberInitializers()) {
3407 funbox->setMemberInitializers(funExtra.memberInitializers());
3408 }
3409
3410 Directives newDirectives = directives;
3411 SourceParseContext funpc(this, funbox, &newDirectives);
3412 if (!funpc.init()) {
3413 return errorResult();
3414 }
3415
3416 // Our tokenStream has no current token, so funNode's position is garbage.
3417 // Substitute the position of the first token in our source. If the
3418 // function is a not-async arrow, use TokenStream::SlashIsRegExp to keep
3419 // verifyConsistentModifier from complaining (we will use
3420 // TokenStream::SlashIsRegExp in functionArguments).
3421 Modifier modifier = (input.functionFlags().isArrow() &&
3422 asyncKind == FunctionAsyncKind::SyncFunction)
3423 ? TokenStream::SlashIsRegExp
3424 : TokenStream::SlashIsDiv;
3425 if (!tokenStream.peekTokenPos(&funNode->pn_pos, modifier)) {
3426 return errorResult();
3427 }
3428
3429 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
3430
3431 if (funbox->isSyntheticFunction()) {
3432 // Currently default class constructors are the only synthetic function that
3433 // supports delazification.
3434 MOZ_ASSERT(funbox->isClassConstructor())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isClassConstructor())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isClassConstructor
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isClassConstructor()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3434); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isClassConstructor()"
")"); do { *((volatile int*)__null) = 3434; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3435 MOZ_ASSERT(funbox->extent().toStringStart == funbox->extent().sourceStart)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->extent().toStringStart == funbox->extent
().sourceStart)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(funbox->extent().toStringStart
== funbox->extent().sourceStart))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("funbox->extent().toStringStart == funbox->extent().sourceStart"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3435); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->extent().toStringStart == funbox->extent().sourceStart"
")"); do { *((volatile int*)__null) = 3435; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3436
3437 HasHeritage hasHeritage = funbox->isDerivedClassConstructor()
3438 ? HasHeritage::Yes
3439 : HasHeritage::No;
3440 TokenPos synthesizedBodyPos(funbox->extent().toStringStart,
3441 funbox->extent().toStringEnd);
3442
3443 // Reset pos() to the `class` keyword for predictable results.
3444 tokenStream.consumeKnownToken(TokenKind::Class);
3445
3446 if (!this->synthesizeConstructorBody(synthesizedBodyPos, hasHeritage,
3447 funNode, funbox)) {
3448 return errorResult();
3449 }
3450 } else {
3451 if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
3452 syntaxKind)) {
3453 MOZ_ASSERT(directives == newDirectives)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(directives == newDirectives)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(directives == newDirectives)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("directives == newDirectives"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "directives == newDirectives"
")"); do { *((volatile int*)__null) = 3453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3454 return errorResult();
3455 }
3456 }
3457
3458 if (!CheckParseTree(this->fc_, alloc_, funNode)) {
3459 return errorResult();
3460 }
3461
3462 ParseNode* node = funNode;
3463 // Don't constant-fold inside "use asm" code, as this could create a parse
3464 // tree that doesn't type-check as asm.js.
3465 if (!pc_->useAsmOrInsideUseAsm()) {
3466 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
3467 return errorResult();
3468 }
3469 }
3470 funNode = &node->as<FunctionNode>();
3471
3472 return funNode;
3473}
3474
3475void ParserBase::setFunctionEndFromCurrentToken(FunctionBox* funbox) const {
3476 if (compilationState_.isInitialStencil()) {
3477 MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type != TokenKind::Eof)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type != TokenKind::Eof))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type != TokenKind::Eof"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3477); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type != TokenKind::Eof"
")"); do { *((volatile int*)__null) = 3477; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3478 MOZ_ASSERT(anyChars.currentToken().type < TokenKind::Limit)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type < TokenKind::Limit)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type < TokenKind::Limit))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type < TokenKind::Limit"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3478); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type < TokenKind::Limit"
")"); do { *((volatile int*)__null) = 3478; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3479 funbox->setEnd(anyChars.currentToken().pos.end);
3480 } else {
3481 // If we're delazifying an arrow function with expression body and
3482 // the expression is also a function, we arrive here immediately after
3483 // skipping the function by Parser::skipLazyInnerFunction.
3484 //
3485 // a => b => c
3486 // ^
3487 // |
3488 // we're here
3489 //
3490 // In that case, the current token's type field is either Limit or
3491 // poisoned.
3492 // We shouldn't read the value if it's poisoned.
3493 // See TokenStreamSpecific<Unit, AnyCharsAccess>::advance and
3494 // mfbt/MemoryChecking.h for more details.
3495 //
3496 // Also, in delazification, the FunctionBox should already have the
3497 // correct extent, and we shouldn't overwrite it here.
3498 // See ScriptStencil variant of PerHandlerParser::newFunctionBox.
3499#if !defined(MOZ_ASAN) && !defined(MOZ_MSAN) && !defined(MOZ_VALGRIND)
3500 MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type != TokenKind::Eof)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type != TokenKind::Eof))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type != TokenKind::Eof"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3500); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type != TokenKind::Eof"
")"); do { *((volatile int*)__null) = 3500; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3501#endif
3502 MOZ_ASSERT(funbox->extent().sourceEnd == anyChars.currentToken().pos.end)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->extent().sourceEnd == anyChars.currentToken
().pos.end)>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(funbox->extent().sourceEnd == anyChars
.currentToken().pos.end))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->extent().sourceEnd == anyChars.currentToken().pos.end"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3502); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->extent().sourceEnd == anyChars.currentToken().pos.end"
")"); do { *((volatile int*)__null) = 3502; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3503 }
3504}
3505
3506template <class ParseHandler, typename Unit>
3507bool GeneralParser<ParseHandler, Unit>::functionFormalParametersAndBody(
3508 InHandling inHandling, YieldHandling yieldHandling,
3509 FunctionNodeType* funNode, FunctionSyntaxKind kind,
3510 const Maybe<uint32_t>& parameterListEnd /* = Nothing() */,
3511 bool isStandaloneFunction /* = false */) {
3512 // Given a properly initialized parse context, try to parse an actual
3513 // function without concern for conversion to strict mode, use of lazy
3514 // parsing and such.
3515
3516 FunctionBox* funbox = pc_->functionBox();
3517
3518 if (kind == FunctionSyntaxKind::ClassConstructor ||
3519 kind == FunctionSyntaxKind::DerivedClassConstructor) {
3520 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
3521 return false;
3522 }
3523#ifdef ENABLE_DECORATORS
3524 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
3525 dot_instanceExtraInitializers_())) {
3526 return false;
3527 }
3528#endif
3529 }
3530
3531 // See below for an explanation why arrow function parameters and arrow
3532 // function bodies are parsed with different yield/await settings.
3533 {
3534 AwaitHandling awaitHandling =
3535 kind == FunctionSyntaxKind::StaticClassBlock ? AwaitIsDisallowed
3536 : (funbox->isAsync() ||
3537 (kind == FunctionSyntaxKind::Arrow && awaitIsKeyword()))
3538 ? AwaitIsKeyword
3539 : AwaitIsName;
3540 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this, awaitHandling);
3541 AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(
3542 this, funbox->isAsync());
3543 if (!functionArguments(yieldHandling, kind, *funNode)) {
3544 return false;
3545 }
3546 }
3547
3548 Maybe<ParseContext::VarScope> varScope;
3549 if (funbox->hasParameterExprs) {
3550 varScope.emplace(this);
3551 if (!varScope->init(pc_)) {
3552 return false;
3553 }
3554 } else {
3555 pc_->functionScope().useAsVarScope(pc_);
3556 }
3557
3558 if (kind == FunctionSyntaxKind::Arrow) {
3559 TokenKind tt;
3560 if (!tokenStream.peekTokenSameLine(&tt)) {
3561 return false;
3562 }
3563
3564 if (tt == TokenKind::Eol) {
3565 error(JSMSG_UNEXPECTED_TOKEN,
3566 "'=>' on the same line after an argument list",
3567 TokenKindToDesc(tt));
3568 return false;
3569 }
3570 if (tt != TokenKind::Arrow) {
3571 error(JSMSG_BAD_ARROW_ARGS);
3572 return false;
3573 }
3574 tokenStream.consumeKnownToken(TokenKind::Arrow);
3575 }
3576
3577 // When parsing something for new Function() we have to make sure to
3578 // only treat a certain part of the source as a parameter list.
3579 if (parameterListEnd.isSome() && parameterListEnd.value() != pos().begin) {
3580 error(JSMSG_UNEXPECTED_PARAMLIST_END);
3581 return false;
3582 }
3583
3584 // Parse the function body.
3585 FunctionBodyType bodyType = StatementListBody;
3586 TokenKind tt;
3587 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
3588 return false;
3589 }
3590 uint32_t openedPos = 0;
3591 if (tt != TokenKind::LeftCurly) {
3592 if (kind != FunctionSyntaxKind::Arrow) {
3593 error(JSMSG_CURLY_BEFORE_BODY);
3594 return false;
3595 }
3596
3597 anyChars.ungetToken();
3598 bodyType = ExpressionBody;
3599 funbox->setHasExprBody();
3600 } else {
3601 openedPos = pos().begin;
3602 }
3603
3604 // Arrow function parameters inherit yieldHandling from the enclosing
3605 // context, but the arrow body doesn't. E.g. in |(a = yield) => yield|,
3606 // |yield| in the parameters is either a name or keyword, depending on
3607 // whether the arrow function is enclosed in a generator function or not.
3608 // Whereas the |yield| in the function body is always parsed as a name.
3609 // The same goes when parsing |await| in arrow functions.
3610 YieldHandling bodyYieldHandling = GetYieldHandling(pc_->generatorKind());
3611 AwaitHandling bodyAwaitHandling = GetAwaitHandling(pc_->asyncKind());
3612 bool inheritedStrict = pc_->sc()->strict();
3613 LexicalScopeNodeType body;
3614 {
3615 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this,
3616 bodyAwaitHandling);
3617 AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(this,
3618 false);
3619 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
3620 body, functionBody(inHandling, bodyYieldHandling, kind, bodyType),do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
3621 false)do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
;
3622 }
3623
3624 // Revalidate the function name when we transitioned to strict mode.
3625 if ((kind == FunctionSyntaxKind::Statement ||
3626 kind == FunctionSyntaxKind::Expression) &&
3627 funbox->explicitName() && !inheritedStrict && pc_->sc()->strict()) {
3628 MOZ_ASSERT(pc_->sc()->hasExplicitUseStrict(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3630); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3630; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
3629 "strict mode should only change when a 'use strict' directive "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3630); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3630; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
3630 "is present")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3630); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3630; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
3631
3632 auto propertyName = funbox->explicitName();
3633 YieldHandling nameYieldHandling;
3634 if (kind == FunctionSyntaxKind::Expression) {
3635 // Named lambda has binding inside it.
3636 nameYieldHandling = bodyYieldHandling;
3637 } else {
3638 // Otherwise YieldHandling cannot be checked at this point
3639 // because of different context.
3640 // It should already be checked before this point.
3641 nameYieldHandling = YieldIsName;
3642 }
3643
3644 // We already use the correct await-handling at this point, therefore
3645 // we don't need call AutoAwaitIsKeyword here.
3646
3647 uint32_t nameOffset = handler_.getFunctionNameOffset(*funNode, anyChars);
3648 if (!checkBindingIdentifier(propertyName, nameOffset, nameYieldHandling)) {
3649 return false;
3650 }
3651 }
3652
3653 if (bodyType == StatementListBody) {
3654 // Cannot use mustMatchToken here because of internal compiler error on
3655 // gcc 6.4.0, with linux 64 SM hazard build.
3656 TokenKind actual;
3657 if (!tokenStream.getToken(&actual, TokenStream::SlashIsRegExp)) {
3658 return false;
3659 }
3660 if (actual != TokenKind::RightCurly) {
3661 reportMissingClosing(JSMSG_CURLY_AFTER_BODY, JSMSG_CURLY_OPENED,
3662 openedPos);
3663 return false;
3664 }
3665
3666 setFunctionEndFromCurrentToken(funbox);
3667 } else {
3668 MOZ_ASSERT(kind == FunctionSyntaxKind::Arrow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == FunctionSyntaxKind::Arrow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == FunctionSyntaxKind::
Arrow))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == FunctionSyntaxKind::Arrow", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3668); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == FunctionSyntaxKind::Arrow"
")"); do { *((volatile int*)__null) = 3668; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3669
3670 if (anyChars.hadError()) {
3671 return false;
3672 }
3673
3674 setFunctionEndFromCurrentToken(funbox);
3675
3676 if (kind == FunctionSyntaxKind::Statement) {
3677 if (!matchOrInsertSemicolon()) {
3678 return false;
3679 }
3680 }
3681 }
3682
3683 if (IsMethodDefinitionKind(kind) && pc_->superScopeNeedsHomeObject()) {
3684 funbox->setNeedsHomeObject();
3685 }
3686
3687 if (!finishFunction(isStandaloneFunction)) {
3688 return false;
3689 }
3690
3691 handler_.setEndPosition(body, pos().begin);
3692 handler_.setEndPosition(*funNode, pos().end);
3693 handler_.setFunctionBody(*funNode, body);
3694
3695 return true;
3696}
3697
3698template <class ParseHandler, typename Unit>
3699typename ParseHandler::FunctionNodeResult
3700GeneralParser<ParseHandler, Unit>::functionStmt(uint32_t toStringStart,
3701 YieldHandling yieldHandling,
3702 DefaultHandling defaultHandling,
3703 FunctionAsyncKind asyncKind) {
3704 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3704); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 3704; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3705
3706 // In sloppy mode, Annex B.3.2 allows labelled function declarations.
3707 // Otherwise it's a parse error.
3708 ParseContext::Statement* declaredInStmt = pc_->innermostStatement();
3709 if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
3710 MOZ_ASSERT(!pc_->sc()->strict(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!pc_->sc()->strict())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!pc_->sc()->strict()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!pc_->sc()->strict()"
" (" "labeled functions shouldn't be parsed in strict mode" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3711); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc_->sc()->strict()"
") (" "labeled functions shouldn't be parsed in strict mode"
")"); do { *((volatile int*)__null) = 3711; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3711 "labeled functions shouldn't be parsed in strict mode")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!pc_->sc()->strict())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!pc_->sc()->strict()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!pc_->sc()->strict()"
" (" "labeled functions shouldn't be parsed in strict mode" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3711); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc_->sc()->strict()"
") (" "labeled functions shouldn't be parsed in strict mode"
")"); do { *((volatile int*)__null) = 3711; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3712
3713 // Find the innermost non-label statement. Report an error if it's
3714 // unbraced: functions can't appear in it. Otherwise the statement
3715 // (or its absence) determines the scope the function's bound in.
3716 while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
3717 declaredInStmt = declaredInStmt->enclosing();
3718 }
3719
3720 if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
3721 error(JSMSG_SLOPPY_FUNCTION_LABEL);
3722 return errorResult();
3723 }
3724 }
3725
3726 TokenKind tt;
3727 if (!tokenStream.getToken(&tt)) {
3728 return errorResult();
3729 }
3730
3731 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
3732 if (tt == TokenKind::Mul) {
3733 generatorKind = GeneratorKind::Generator;
3734 if (!tokenStream.getToken(&tt)) {
3735 return errorResult();
3736 }
3737 }
3738
3739 TaggedParserAtomIndex name;
3740 if (TokenKindIsPossibleIdentifier(tt)) {
3741 name = bindingIdentifier(yieldHandling);
3742 if (!name) {
3743 return errorResult();
3744 }
3745 } else if (defaultHandling == AllowDefaultName) {
3746 name = TaggedParserAtomIndex::WellKnown::default_();
3747 anyChars.ungetToken();
3748 } else {
3749 /* Unnamed function expressions are forbidden in statement context. */
3750 error(JSMSG_UNNAMED_FUNCTION_STMT);
3751 return errorResult();
3752 }
3753
3754 // Note the declared name and check for early errors.
3755 DeclarationKind kind;
3756 if (declaredInStmt) {
3757 MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(declaredInStmt->kind() != StatementKind::Label)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(declaredInStmt->kind() != StatementKind::Label)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("declaredInStmt->kind() != StatementKind::Label"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3757); AnnotateMozCrashReason("MOZ_ASSERT" "(" "declaredInStmt->kind() != StatementKind::Label"
")"); do { *((volatile int*)__null) = 3757; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3758 MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StatementKindIsBraced(declaredInStmt->kind()))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(StatementKindIsBraced(declaredInStmt->kind())))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("StatementKindIsBraced(declaredInStmt->kind())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3758); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StatementKindIsBraced(declaredInStmt->kind())"
")"); do { *((volatile int*)__null) = 3758; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3759
3760 kind =
3761 (!pc_->sc()->strict() && generatorKind == GeneratorKind::NotGenerator &&
3762 asyncKind == FunctionAsyncKind::SyncFunction)
3763 ? DeclarationKind::SloppyLexicalFunction
3764 : DeclarationKind::LexicalFunction;
3765 } else {
3766 kind = pc_->atModuleLevel() ? DeclarationKind::ModuleBodyLevelFunction
3767 : DeclarationKind::BodyLevelFunction;
3768 }
3769
3770 if (!noteDeclaredName(name, kind, pos())) {
3771 return errorResult();
3772 }
3773
3774 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
3775 FunctionNodeType funNode;
3776 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3777
3778 // Under sloppy mode, try Annex B.3.3 semantics. If making an additional
3779 // 'var' binding of the same name does not throw an early error, do so.
3780 // This 'var' binding would be assigned the function object when its
3781 // declaration is reached, not at the start of the block.
3782 //
3783 // This semantics is implemented upon Scope exit in
3784 // Scope::propagateAndMarkAnnexBFunctionBoxes.
3785 bool tryAnnexB = kind == DeclarationKind::SloppyLexicalFunction;
3786
3787 YieldHandling newYieldHandling = GetYieldHandling(generatorKind);
3788 return functionDefinition(funNode, toStringStart, InAllowed, newYieldHandling,
3789 name, syntaxKind, generatorKind, asyncKind,
3790 tryAnnexB);
3791}
3792
3793template <class ParseHandler, typename Unit>
3794typename ParseHandler::FunctionNodeResult
3795GeneralParser<ParseHandler, Unit>::functionExpr(uint32_t toStringStart,
3796 InvokedPrediction invoked,
3797 FunctionAsyncKind asyncKind) {
3798 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3798); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 3798; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3799
3800 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(
3801 this, GetAwaitHandling(asyncKind));
3802 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
3803 TokenKind tt;
3804 if (!tokenStream.getToken(&tt)) {
3805 return errorResult();
3806 }
3807
3808 if (tt == TokenKind::Mul) {
3809 generatorKind = GeneratorKind::Generator;
3810 if (!tokenStream.getToken(&tt)) {
3811 return errorResult();
3812 }
3813 }
3814
3815 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
3816
3817 TaggedParserAtomIndex name;
3818 if (TokenKindIsPossibleIdentifier(tt)) {
3819 name = bindingIdentifier(yieldHandling);
3820 if (!name) {
3821 return errorResult();
3822 }
3823 } else {
3824 anyChars.ungetToken();
3825 }
3826
3827 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Expression;
3828 FunctionNodeType funNode;
3829 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3830
3831 if (invoked) {
3832 funNode = handler_.setLikelyIIFE(funNode);
3833 }
3834
3835 return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
3836 name, syntaxKind, generatorKind, asyncKind);
3837}
3838
3839/*
3840 * Return true if this node, known to be an unparenthesized string literal
3841 * that never contain escape sequences, could be the string of a directive in a
3842 * Directive Prologue. Directive strings never contain escape sequences or line
3843 * continuations.
3844 */
3845static inline bool IsUseStrictDirective(const TokenPos& pos,
3846 TaggedParserAtomIndex atom) {
3847 // the length of "use strict", including quotation.
3848 static constexpr size_t useStrictLength = 12;
3849 return atom == TaggedParserAtomIndex::WellKnown::use_strict_() &&
3850 pos.begin + useStrictLength == pos.end;
3851}
3852static inline bool IsUseAsmDirective(const TokenPos& pos,
3853 TaggedParserAtomIndex atom) {
3854 // the length of "use asm", including quotation.
3855 static constexpr size_t useAsmLength = 9;
3856 return atom == TaggedParserAtomIndex::WellKnown::use_asm_() &&
3857 pos.begin + useAsmLength == pos.end;
3858}
3859
3860template <typename Unit>
3861bool Parser<SyntaxParseHandler, Unit>::asmJS(ListNodeType list) {
3862 // While asm.js could technically be validated and compiled during syntax
3863 // parsing, we have no guarantee that some later JS wouldn't abort the
3864 // syntax parse and cause us to re-parse (and re-compile) the asm.js module.
3865 // For simplicity, unconditionally abort the syntax parse when "use asm" is
3866 // encountered so that asm.js is always validated/compiled exactly once
3867 // during a full parse.
3868 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3868); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 3868; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
3869 return false;
3870}
3871
3872template <typename Unit>
3873bool Parser<FullParseHandler, Unit>::asmJS(ListNodeType list) {
3874 // Disable syntax parsing in anything nested inside the asm.js module.
3875 disableSyntaxParser();
3876
3877 // We should be encountering the "use asm" directive for the first time; if
3878 // the directive is already, we must have failed asm.js validation and we're
3879 // reparsing. In that case, don't try to validate again. A non-null
3880 // newDirectives means we're not in a normal function.
3881 if (!pc_->newDirectives || pc_->newDirectives->asmJS()) {
3882 return true;
3883 }
3884
3885 // If there is no ScriptSource, then we are doing a non-compiling parse and
3886 // so we shouldn't (and can't, without a ScriptSource) compile.
3887 if (ss == nullptr) {
3888 return true;
3889 }
3890
3891 pc_->functionBox()->useAsm = true;
3892
3893 // Attempt to validate and compile this asm.js module. On success, the
3894 // tokenStream has been advanced to the closing }. On failure, the
3895 // tokenStream is in an indeterminate state and we must reparse the
3896 // function from the beginning. Reparsing is triggered by marking that a
3897 // new directive has been encountered and returning 'false'.
3898 bool validated;
3899 if (!CompileAsmJS(this->fc_, this->parserAtoms(), *this, list, &validated)) {
3900 return false;
3901 }
3902 if (!validated) {
3903 pc_->newDirectives->setAsmJS();
3904 return false;
3905 }
3906
3907 return true;
3908}
3909
3910template <class ParseHandler, typename Unit>
3911inline bool GeneralParser<ParseHandler, Unit>::asmJS(ListNodeType list) {
3912 return asFinalParser()->asmJS(list);
3913}
3914
3915/*
3916 * Recognize Directive Prologue members and directives. Assuming |pn| is a
3917 * candidate for membership in a directive prologue, recognize directives and
3918 * set |pc_|'s flags accordingly. If |pn| is indeed part of a prologue, set its
3919 * |prologue| flag.
3920 *
3921 * Note that the following is a strict mode function:
3922 *
3923 * function foo() {
3924 * "blah" // inserted semi colon
3925 * "blurgh"
3926 * "use\x20loose"
3927 * "use strict"
3928 * }
3929 *
3930 * That is, even though "use\x20loose" can never be a directive, now or in the
3931 * future (because of the hex escape), the Directive Prologue extends through it
3932 * to the "use strict" statement, which is indeed a directive.
3933 */
3934template <class ParseHandler, typename Unit>
3935bool GeneralParser<ParseHandler, Unit>::maybeParseDirective(
3936 ListNodeType list, Node possibleDirective, bool* cont) {
3937 TokenPos directivePos;
3938 TaggedParserAtomIndex directive =
3939 handler_.isStringExprStatement(possibleDirective, &directivePos);
3940
3941 *cont = !!directive;
3942 if (!*cont) {
3943 return true;
3944 }
3945
3946 if (IsUseStrictDirective(directivePos, directive)) {
3947 // Functions with non-simple parameter lists (destructuring,
3948 // default or rest parameters) must not contain a "use strict"
3949 // directive.
3950 if (pc_->isFunctionBox()) {
3951 FunctionBox* funbox = pc_->functionBox();
3952 if (!funbox->hasSimpleParameterList()) {
3953 const char* parameterKind = funbox->hasDestructuringArgs
3954 ? "destructuring"
3955 : funbox->hasParameterExprs ? "default"
3956 : "rest";
3957 errorAt(directivePos.begin, JSMSG_STRICT_NON_SIMPLE_PARAMS,
3958 parameterKind);
3959 return false;
3960 }
3961 }
3962
3963 // We're going to be in strict mode. Note that this scope explicitly
3964 // had "use strict";
3965 pc_->sc()->setExplicitUseStrict();
3966 if (!pc_->sc()->strict()) {
3967 // Some strict mode violations can appear before a Use Strict Directive
3968 // is applied. (See the |DeprecatedContent| enum initializers.) These
3969 // violations can manifest in two ways.
3970 //
3971 // First, the violation can appear *before* the Use Strict Directive.
3972 // Numeric literals (and therefore octal literals) can only precede a
3973 // Use Strict Directive if this function's parameter list is not simple,
3974 // but we reported an error for non-simple parameter lists above, so
3975 // octal literals present no issue. But octal escapes and \8 and \9 can
3976 // appear in the directive prologue before a Use Strict Directive:
3977 //
3978 // function f()
3979 // {
3980 // "hell\157 world"; // octal escape
3981 // "\8"; "\9"; // NonOctalDecimalEscape
3982 // "use strict"; // retroactively makes all the above errors
3983 // }
3984 //
3985 // Second, the violation can appear *after* the Use Strict Directive but
3986 // *before* the directive is recognized as terminated. This only
3987 // happens when a directive is terminated by ASI, and the next token
3988 // contains a violation:
3989 //
3990 // function a()
3991 // {
3992 // "use strict" // ASI
3993 // 0755;
3994 // }
3995 // function b()
3996 // {
3997 // "use strict" // ASI
3998 // "hell\157 world";
3999 // }
4000 // function c()
4001 // {
4002 // "use strict" // ASI
4003 // "\8";
4004 // }
4005 //
4006 // We note such violations when tokenizing. Then, if a violation has
4007 // been observed at the time a "use strict" is applied, we report the
4008 // error.
4009 switch (anyChars.sawDeprecatedContent()) {
4010 case DeprecatedContent::None:
4011 break;
4012 case DeprecatedContent::OctalLiteral:
4013 error(JSMSG_DEPRECATED_OCTAL_LITERAL);
4014 return false;
4015 case DeprecatedContent::OctalEscape:
4016 error(JSMSG_DEPRECATED_OCTAL_ESCAPE);
4017 return false;
4018 case DeprecatedContent::EightOrNineEscape:
4019 error(JSMSG_DEPRECATED_EIGHT_OR_NINE_ESCAPE);
4020 return false;
4021 }
4022
4023 pc_->sc()->setStrictScript();
4024 }
4025 } else if (IsUseAsmDirective(directivePos, directive)) {
4026 if (pc_->isFunctionBox()) {
4027 return asmJS(list);
4028 }
4029 return warningAt(directivePos.begin, JSMSG_USE_ASM_DIRECTIVE_FAIL);
4030 }
4031 return true;
4032}
4033
4034template <class ParseHandler, typename Unit>
4035typename ParseHandler::ListNodeResult
4036GeneralParser<ParseHandler, Unit>::statementList(YieldHandling yieldHandling) {
4037 AutoCheckRecursionLimit recursion(this->fc_);
4038 if (!recursion.check(this->fc_)) {
4039 return errorResult();
4040 }
4041
4042 ListNodeType stmtList;
4043 MOZ_TRY_VAR(stmtList, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
4044
4045 bool canHaveDirectives = pc_->atBodyLevel();
4046 if (canHaveDirectives) {
4047 // Clear flags for deprecated content that might have been seen in an
4048 // enclosing context.
4049 anyChars.clearSawDeprecatedContent();
4050 }
4051
4052 bool canHaveHashbangComment = pc_->atTopLevel();
4053 if (canHaveHashbangComment) {
4054 tokenStream.consumeOptionalHashbangComment();
4055 }
4056
4057 bool afterReturn = false;
4058 bool warnedAboutStatementsAfterReturn = false;
4059 uint32_t statementBegin = 0;
4060 for (;;) {
4061 TokenKind tt = TokenKind::Eof;
4062 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
4063 if (anyChars.isEOF()) {
4064 isUnexpectedEOF_ = true;
4065 }
4066 return errorResult();
4067 }
4068 if (tt == TokenKind::Eof || tt == TokenKind::RightCurly) {
4069 TokenPos pos;
4070 if (!tokenStream.peekTokenPos(&pos, TokenStream::SlashIsRegExp)) {
4071 return errorResult();
4072 }
4073 handler_.setListEndPosition(stmtList, pos);
4074 break;
4075 }
4076 if (afterReturn) {
4077 if (!tokenStream.peekOffset(&statementBegin,
4078 TokenStream::SlashIsRegExp)) {
4079 return errorResult();
4080 }
4081 }
4082 auto nextResult = statementListItem(yieldHandling, canHaveDirectives);
4083 if (nextResult.isErr()) {
4084 if (anyChars.isEOF()) {
4085 isUnexpectedEOF_ = true;
4086 }
4087 return errorResult();
4088 }
4089 Node next = nextResult.unwrap();
4090 if (!warnedAboutStatementsAfterReturn) {
4091 if (afterReturn) {
4092 if (!handler_.isStatementPermittedAfterReturnStatement(next)) {
4093 if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
4094 return errorResult();
4095 }
4096
4097 warnedAboutStatementsAfterReturn = true;
4098 }
4099 } else if (handler_.isReturnStatement(next)) {
4100 afterReturn = true;
4101 }
4102 }
4103
4104 if (canHaveDirectives) {
4105 if (!maybeParseDirective(stmtList, next, &canHaveDirectives)) {
4106 return errorResult();
4107 }
4108 }
4109
4110 handler_.addStatementToList(stmtList, next);
4111 }
4112
4113 return stmtList;
4114}
4115
4116template <class ParseHandler, typename Unit>
4117typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::condition(
4118 InHandling inHandling, YieldHandling yieldHandling) {
4119 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_COND)) {
4120 return errorResult();
4121 }
4122
4123 Node pn;
4124 MOZ_TRY_VAR(pn, exprInParens(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (exprInParens(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (pn) = mozTryVarTempResult_.unwrap(); } while (0)
;
4125
4126 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_COND)) {
4127 return errorResult();
4128 }
4129
4130 return pn;
4131}
4132
4133template <class ParseHandler, typename Unit>
4134bool GeneralParser<ParseHandler, Unit>::matchLabel(
4135 YieldHandling yieldHandling, TaggedParserAtomIndex* labelOut) {
4136 MOZ_ASSERT(labelOut != nullptr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(labelOut != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(labelOut != nullptr))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("labelOut != nullptr"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4136); AnnotateMozCrashReason("MOZ_ASSERT" "(" "labelOut != nullptr"
")"); do { *((volatile int*)__null) = 4136; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4137 TokenKind tt = TokenKind::Eof;
4138 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
4139 return false;
4140 }
4141
4142 if (TokenKindIsPossibleIdentifier(tt)) {
4143 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
4144
4145 *labelOut = labelIdentifier(yieldHandling);
4146 if (!*labelOut) {
4147 return false;
4148 }
4149 } else {
4150 *labelOut = TaggedParserAtomIndex::null();
4151 }
4152 return true;
4153}
4154
4155template <class ParseHandler, typename Unit>
4156GeneralParser<ParseHandler, Unit>::PossibleError::PossibleError(
4157 GeneralParser<ParseHandler, Unit>& parser)
4158 : parser_(parser) {}
4159
4160template <class ParseHandler, typename Unit>
4161typename GeneralParser<ParseHandler, Unit>::PossibleError::Error&
4162GeneralParser<ParseHandler, Unit>::PossibleError::error(ErrorKind kind) {
4163 if (kind == ErrorKind::Expression) {
4164 return exprError_;
4165 }
4166 if (kind == ErrorKind::Destructuring) {
4167 return destructuringError_;
4168 }
4169 MOZ_ASSERT(kind == ErrorKind::DestructuringWarning)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ErrorKind::DestructuringWarning)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == ErrorKind::DestructuringWarning))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("kind == ErrorKind::DestructuringWarning"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4169); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ErrorKind::DestructuringWarning"
")"); do { *((volatile int*)__null) = 4169; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4170 return destructuringWarning_;
4171}
4172
4173template <class ParseHandler, typename Unit>
4174void GeneralParser<ParseHandler, Unit>::PossibleError::setResolved(
4175 ErrorKind kind) {
4176 error(kind).state_ = ErrorState::None;
4177}
4178
4179template <class ParseHandler, typename Unit>
4180bool GeneralParser<ParseHandler, Unit>::PossibleError::hasError(
4181 ErrorKind kind) {
4182 return error(kind).state_ == ErrorState::Pending;
4183}
4184
4185template <class ParseHandler, typename Unit>
4186bool GeneralParser<ParseHandler,
4187 Unit>::PossibleError::hasPendingDestructuringError() {
4188 return hasError(ErrorKind::Destructuring);
4189}
4190
4191template <class ParseHandler, typename Unit>
4192void GeneralParser<ParseHandler, Unit>::PossibleError::setPending(
4193 ErrorKind kind, const TokenPos& pos, unsigned errorNumber) {
4194 // Don't overwrite a previously recorded error.
4195 if (hasError(kind)) {
4196 return;
4197 }
4198
4199 // If we report an error later, we'll do it from the position where we set
4200 // the state to pending.
4201 Error& err = error(kind);
4202 err.offset_ = pos.begin;
4203 err.errorNumber_ = errorNumber;
4204 err.state_ = ErrorState::Pending;
4205}
4206
4207template <class ParseHandler, typename Unit>
4208void GeneralParser<ParseHandler, Unit>::PossibleError::
4209 setPendingDestructuringErrorAt(const TokenPos& pos, unsigned errorNumber) {
4210 setPending(ErrorKind::Destructuring, pos, errorNumber);
4211}
4212
4213template <class ParseHandler, typename Unit>
4214void GeneralParser<ParseHandler, Unit>::PossibleError::
4215 setPendingDestructuringWarningAt(const TokenPos& pos,
4216 unsigned errorNumber) {
4217 setPending(ErrorKind::DestructuringWarning, pos, errorNumber);
4218}
4219
4220template <class ParseHandler, typename Unit>
4221void GeneralParser<ParseHandler, Unit>::PossibleError::
4222 setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber) {
4223 setPending(ErrorKind::Expression, pos, errorNumber);
4224}
4225
4226template <class ParseHandler, typename Unit>
4227bool GeneralParser<ParseHandler, Unit>::PossibleError::checkForError(
4228 ErrorKind kind) {
4229 if (!hasError(kind)) {
4230 return true;
4231 }
4232
4233 Error& err = error(kind);
4234 parser_.errorAt(err.offset_, err.errorNumber_);
4235 return false;
4236}
4237
4238template <class ParseHandler, typename Unit>
4239bool GeneralParser<ParseHandler,
4240 Unit>::PossibleError::checkForDestructuringErrorOrWarning() {
4241 // Clear pending expression error, because we're definitely not in an
4242 // expression context.
4243 setResolved(ErrorKind::Expression);
4244
4245 // Report any pending destructuring error.
4246 return checkForError(ErrorKind::Destructuring);
4247}
4248
4249template <class ParseHandler, typename Unit>
4250bool GeneralParser<ParseHandler,
4251 Unit>::PossibleError::checkForExpressionError() {
4252 // Clear pending destructuring error, because we're definitely not
4253 // in a destructuring context.
4254 setResolved(ErrorKind::Destructuring);
4255 setResolved(ErrorKind::DestructuringWarning);
4256
4257 // Report any pending expression error.
4258 return checkForError(ErrorKind::Expression);
4259}
4260
4261template <class ParseHandler, typename Unit>
4262void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorTo(
4263 ErrorKind kind, PossibleError* other) {
4264 if (hasError(kind) && !other->hasError(kind)) {
4265 Error& err = error(kind);
4266 Error& otherErr = other->error(kind);
4267 otherErr.offset_ = err.offset_;
4268 otherErr.errorNumber_ = err.errorNumber_;
4269 otherErr.state_ = err.state_;
4270 }
4271}
4272
4273template <class ParseHandler, typename Unit>
4274void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorsTo(
4275 PossibleError* other) {
4276 MOZ_ASSERT(other)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(other)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(other))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("other", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "other" ")")
; do { *((volatile int*)__null) = 4276; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4277 MOZ_ASSERT(this != other)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this != other)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(this != other))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("this != other",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4277); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this != other"
")"); do { *((volatile int*)__null) = 4277; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4278 MOZ_ASSERT(&parser_ == &other->parser_,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(&parser_ == &other->parser_)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(&parser_ == &other->parser_))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("&parser_ == &other->parser_"
" (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4280); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4280
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
4279 "Can't transfer fields to an instance which belongs to a "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(&parser_ == &other->parser_)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(&parser_ == &other->parser_))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("&parser_ == &other->parser_"
" (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4280); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4280
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
4280 "different parser")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(&parser_ == &other->parser_)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(&parser_ == &other->parser_))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("&parser_ == &other->parser_"
" (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4280); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4280
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
4281
4282 transferErrorTo(ErrorKind::Destructuring, other);
4283 transferErrorTo(ErrorKind::Expression, other);
4284}
4285
4286template <class ParseHandler, typename Unit>
4287typename ParseHandler::BinaryNodeResult
4288GeneralParser<ParseHandler, Unit>::bindingInitializer(
4289 Node lhs, DeclarationKind kind, YieldHandling yieldHandling) {
4290 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assign))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Assign)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Assign)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4290); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assign)"
")"); do { *((volatile int*)__null) = 4290; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4291
4292 if (kind == DeclarationKind::FormalParameter) {
4293 pc_->functionBox()->hasParameterExprs = true;
4294 }
4295
4296 Node rhs;
4297 MOZ_TRY_VAR(rhs, assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
4298
4299 BinaryNodeType assign;
4300 MOZ_TRY_VAR(assign,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assign) = mozTryVarTempResult_.unwrap(); } while (0)
4301 handler_.newAssignment(ParseNodeKind::AssignExpr, lhs, rhs))do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assign) = mozTryVarTempResult_.unwrap(); } while (0)
;
4302
4303 return assign;
4304}
4305
4306template <class ParseHandler, typename Unit>
4307typename ParseHandler::NameNodeResult
4308GeneralParser<ParseHandler, Unit>::bindingIdentifier(
4309 DeclarationKind kind, YieldHandling yieldHandling) {
4310 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
4311 if (!name) {
4312 return errorResult();
4313 }
4314
4315 NameNodeType binding;
4316 MOZ_TRY_VAR(binding, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (binding) = mozTryVarTempResult_.unwrap();
} while (0)
;
4317 if (!noteDeclaredName(name, kind, pos())) {
4318 return errorResult();
4319 }
4320
4321 return binding;
4322}
4323
4324template <class ParseHandler, typename Unit>
4325typename ParseHandler::NodeResult
4326GeneralParser<ParseHandler, Unit>::bindingIdentifierOrPattern(
4327 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4328 if (tt == TokenKind::LeftBracket) {
4329 return arrayBindingPattern(kind, yieldHandling);
4330 }
4331
4332 if (tt == TokenKind::LeftCurly) {
4333 return objectBindingPattern(kind, yieldHandling);
4334 }
4335
4336 if (!TokenKindIsPossibleIdentifierName(tt)) {
4337 error(JSMSG_NO_VARIABLE_NAME);
4338 return errorResult();
4339 }
4340
4341 return bindingIdentifier(kind, yieldHandling);
4342}
4343
4344template <class ParseHandler, typename Unit>
4345typename ParseHandler::ListNodeResult
4346GeneralParser<ParseHandler, Unit>::objectBindingPattern(
4347 DeclarationKind kind, YieldHandling yieldHandling) {
4348 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4348); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4348; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4349
4350 AutoCheckRecursionLimit recursion(this->fc_);
4351 if (!recursion.check(this->fc_)) {
4352 return errorResult();
4353 }
4354
4355 uint32_t begin = pos().begin;
4356 ListNodeType literal;
4357 MOZ_TRY_VAR(literal, handler_.newObjectLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newObjectLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4358
4359 Maybe<DeclarationKind> declKind = Some(kind);
4360 TaggedParserAtomIndex propAtom;
4361 for (;;) {
4362 TokenKind tt;
4363 if (!tokenStream.peekToken(&tt)) {
4364 return errorResult();
4365 }
4366 if (tt == TokenKind::RightCurly) {
4367 break;
4368 }
4369
4370 if (tt == TokenKind::TripleDot) {
4371 tokenStream.consumeKnownToken(TokenKind::TripleDot);
4372 uint32_t begin = pos().begin;
4373
4374 TokenKind tt;
4375 if (!tokenStream.getToken(&tt)) {
4376 return errorResult();
4377 }
4378
4379 if (!TokenKindIsPossibleIdentifierName(tt)) {
4380 error(JSMSG_NO_VARIABLE_NAME);
4381 return errorResult();
4382 }
4383
4384 NameNodeType inner;
4385 MOZ_TRY_VAR(inner, bindingIdentifier(kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(kind, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (inner) =
mozTryVarTempResult_.unwrap(); } while (0)
;
4386
4387 if (!handler_.addSpreadProperty(literal, begin, inner)) {
4388 return errorResult();
4389 }
4390 } else {
4391 TokenPos namePos = anyChars.nextToken().pos;
4392
4393 PropertyType propType;
4394 Node propName;
4395 MOZ_TRY_VAR(propName, propertyOrMethodName(do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInPattern, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
4396 yieldHandling, PropertyNameInPattern, declKind,do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInPattern, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
4397 literal, &propType, &propAtom))do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInPattern, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
4398
4399 if (propType == PropertyType::Normal) {
4400 // Handle e.g., |var {p: x} = o| and |var {p: x=0} = o|.
4401
4402 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
4403 return errorResult();
4404 }
4405
4406 Node binding;
4407 MOZ_TRY_VAR(binding,do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (binding) = mozTryVarTempResult_.unwrap(); } while (0)
4408 bindingIdentifierOrPattern(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (binding) = mozTryVarTempResult_.unwrap(); } while (0)
;
4409
4410 bool hasInitializer;
4411 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
4412 TokenStream::SlashIsRegExp)) {
4413 return errorResult();
4414 }
4415
4416 Node bindingExpr;
4417 if (hasInitializer) {
4418 MOZ_TRY_VAR(bindingExpr,do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
4419 bindingInitializer(binding, kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
4420 } else {
4421 bindingExpr = binding;
4422 }
4423
4424 if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
4425 return errorResult();
4426 }
4427 } else if (propType == PropertyType::Shorthand) {
4428 // Handle e.g., |var {x, y} = o| as destructuring shorthand
4429 // for |var {x: x, y: y} = o|.
4430 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(tt))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(TokenKindIsPossibleIdentifierName(tt)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifierName(tt)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4430); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(tt)"
")"); do { *((volatile int*)__null) = 4430; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4431
4432 NameNodeType binding;
4433 MOZ_TRY_VAR(binding, bindingIdentifier(kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(kind, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4434
4435 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
4436 binding)) {
4437 return errorResult();
4438 }
4439 } else if (propType == PropertyType::CoverInitializedName) {
4440 // Handle e.g., |var {x=1, y=2} = o| as destructuring
4441 // shorthand with default values.
4442 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(tt))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(TokenKindIsPossibleIdentifierName(tt)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifierName(tt)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(tt)"
")"); do { *((volatile int*)__null) = 4442; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4443
4444 NameNodeType binding;
4445 MOZ_TRY_VAR(binding, bindingIdentifier(kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(kind, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4446
4447 tokenStream.consumeKnownToken(TokenKind::Assign);
4448
4449 BinaryNodeType bindingExpr;
4450 MOZ_TRY_VAR(bindingExpr,do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
4451 bindingInitializer(binding, kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
4452
4453 if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
4454 return errorResult();
4455 }
4456 } else {
4457 errorAt(namePos.begin, JSMSG_NO_VARIABLE_NAME);
4458 return errorResult();
4459 }
4460 }
4461
4462 bool matched;
4463 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
4464 TokenStream::SlashIsInvalid)) {
4465 return errorResult();
4466 }
4467 if (!matched) {
4468 break;
4469 }
4470 if (tt == TokenKind::TripleDot) {
4471 error(JSMSG_REST_WITH_COMMA);
4472 return errorResult();
4473 }
4474 }
4475
4476 if (!mustMatchToken(TokenKind::RightCurly, [this, begin](TokenKind actual) {
4477 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST, JSMSG_CURLY_OPENED,
4478 begin);
4479 })) {
4480 return errorResult();
4481 }
4482
4483 handler_.setEndPosition(literal, pos().end);
4484 return literal;
4485}
4486
4487template <class ParseHandler, typename Unit>
4488typename ParseHandler::ListNodeResult
4489GeneralParser<ParseHandler, Unit>::arrayBindingPattern(
4490 DeclarationKind kind, YieldHandling yieldHandling) {
4491 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 4491; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4492
4493 AutoCheckRecursionLimit recursion(this->fc_);
4494 if (!recursion.check(this->fc_)) {
4495 return errorResult();
4496 }
4497
4498 uint32_t begin = pos().begin;
4499 ListNodeType literal;
4500 MOZ_TRY_VAR(literal, handler_.newArrayLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newArrayLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4501
4502 uint32_t index = 0;
4503 for (;; index++) {
4504 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
4505 error(JSMSG_ARRAY_INIT_TOO_BIG);
4506 return errorResult();
4507 }
4508
4509 TokenKind tt;
4510 if (!tokenStream.getToken(&tt)) {
4511 return errorResult();
4512 }
4513
4514 if (tt == TokenKind::RightBracket) {
4515 anyChars.ungetToken();
4516 break;
4517 }
4518
4519 if (tt == TokenKind::Comma) {
4520 if (!handler_.addElision(literal, pos())) {
4521 return errorResult();
4522 }
4523 } else if (tt == TokenKind::TripleDot) {
4524 uint32_t begin = pos().begin;
4525
4526 TokenKind tt;
4527 if (!tokenStream.getToken(&tt)) {
4528 return errorResult();
4529 }
4530
4531 Node inner;
4532 MOZ_TRY_VAR(inner, bindingIdentifierOrPattern(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
;
4533
4534 if (!handler_.addSpreadElement(literal, begin, inner)) {
4535 return errorResult();
4536 }
4537 } else {
4538 Node binding;
4539 MOZ_TRY_VAR(binding, bindingIdentifierOrPattern(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (binding) = mozTryVarTempResult_.unwrap(); } while (0)
;
4540
4541 bool hasInitializer;
4542 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
4543 TokenStream::SlashIsRegExp)) {
4544 return errorResult();
4545 }
4546
4547 Node element;
4548 if (hasInitializer) {
4549 MOZ_TRY_VAR(element, bindingInitializer(binding, kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (element) = mozTryVarTempResult_.unwrap(); } while (0)
;
4550 } else {
4551 element = binding;
4552 }
4553
4554 handler_.addArrayElement(literal, element);
4555 }
4556
4557 if (tt != TokenKind::Comma) {
4558 // If we didn't already match TokenKind::Comma in above case.
4559 bool matched;
4560 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
4561 TokenStream::SlashIsRegExp)) {
4562 return errorResult();
4563 }
4564 if (!matched) {
4565 break;
4566 }
4567
4568 if (tt == TokenKind::TripleDot) {
4569 error(JSMSG_REST_WITH_COMMA);
4570 return errorResult();
4571 }
4572 }
4573 }
4574
4575 if (!mustMatchToken(TokenKind::RightBracket, [this, begin](TokenKind actual) {
4576 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
4577 JSMSG_BRACKET_OPENED, begin);
4578 })) {
4579 return errorResult();
4580 }
4581
4582 handler_.setEndPosition(literal, pos().end);
4583 return literal;
4584}
4585
4586template <class ParseHandler, typename Unit>
4587typename ParseHandler::NodeResult
4588GeneralParser<ParseHandler, Unit>::destructuringDeclaration(
4589 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4590 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 4590; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4591 MOZ_ASSERT(tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4591); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly"
")"); do { *((volatile int*)__null) = 4591; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4592
4593 if (tt == TokenKind::LeftBracket) {
4594 return arrayBindingPattern(kind, yieldHandling);
4595 }
4596 return objectBindingPattern(kind, yieldHandling);
4597}
4598
4599template <class ParseHandler, typename Unit>
4600typename ParseHandler::NodeResult
4601GeneralParser<ParseHandler, Unit>::destructuringDeclarationWithoutYieldOrAwait(
4602 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4603 uint32_t startYieldOffset = pc_->lastYieldOffset;
4604 uint32_t startAwaitOffset = pc_->lastAwaitOffset;
4605
4606 Node res;
4607 MOZ_TRY_VAR(res, destructuringDeclaration(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (destructuringDeclaration(kind
, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (res) = mozTryVarTempResult_.unwrap(); } while (0)
;
4608
4609 if (pc_->lastYieldOffset != startYieldOffset) {
4610 errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
4611 return errorResult();
4612 }
4613 if (pc_->lastAwaitOffset != startAwaitOffset) {
4614 errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
4615 return errorResult();
4616 }
4617 return res;
4618}
4619
4620template <class ParseHandler, typename Unit>
4621typename ParseHandler::LexicalScopeNodeResult
4622GeneralParser<ParseHandler, Unit>::blockStatement(YieldHandling yieldHandling,
4623 unsigned errorNumber) {
4624 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4624); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4624; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4625 uint32_t openedPos = pos().begin;
4626
4627 ParseContext::Statement stmt(pc_, StatementKind::Block);
4628 ParseContext::Scope scope(this);
4629 if (!scope.init(pc_)) {
4630 return errorResult();
4631 }
4632
4633 ListNodeType list;
4634 MOZ_TRY_VAR(list, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (list) = mozTryVarTempResult_
.unwrap(); } while (0)
;
4635
4636 if (!mustMatchToken(TokenKind::RightCurly, [this, errorNumber,
4637 openedPos](TokenKind actual) {
4638 this->reportMissingClosing(errorNumber, JSMSG_CURLY_OPENED, openedPos);
4639 })) {
4640 return errorResult();
4641 }
4642
4643 return finishLexicalScope(scope, list);
4644}
4645
4646template <class ParseHandler, typename Unit>
4647typename ParseHandler::NodeResult
4648GeneralParser<ParseHandler, Unit>::expressionAfterForInOrOf(
4649 ParseNodeKind forHeadKind, YieldHandling yieldHandling) {
4650 MOZ_ASSERT(forHeadKind == ParseNodeKind::ForIn ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(forHeadKind == ParseNodeKind::ForIn || forHeadKind ==
ParseNodeKind::ForOf)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(forHeadKind == ParseNodeKind
::ForIn || forHeadKind == ParseNodeKind::ForOf))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 4651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4651 forHeadKind == ParseNodeKind::ForOf)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(forHeadKind == ParseNodeKind::ForIn || forHeadKind ==
ParseNodeKind::ForOf)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(forHeadKind == ParseNodeKind
::ForIn || forHeadKind == ParseNodeKind::ForOf))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 4651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4652 if (forHeadKind == ParseNodeKind::ForOf) {
4653 return assignExpr(InAllowed, yieldHandling, TripledotProhibited);
4654 }
4655
4656 return expr(InAllowed, yieldHandling, TripledotProhibited);
4657}
4658
4659template <class ParseHandler, typename Unit>
4660typename ParseHandler::NodeResult
4661GeneralParser<ParseHandler, Unit>::declarationPattern(
4662 DeclarationKind declKind, TokenKind tt, bool initialDeclaration,
4663 YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
4664 Node* forInOrOfExpression) {
4665 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket) ||
anyChars.isCurrentTokenType(TokenKind::LeftCurly))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars
.isCurrentTokenType(TokenKind::LeftCurly)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4666); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4666; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4666 anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket) ||
anyChars.isCurrentTokenType(TokenKind::LeftCurly))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars
.isCurrentTokenType(TokenKind::LeftCurly)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4666); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4666; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4667
4668 Node pattern;
4669 MOZ_TRY_VAR(pattern, destructuringDeclaration(declKind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (destructuringDeclaration(declKind
, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (pattern) = mozTryVarTempResult_.unwrap(); } while (0)
;
4670
4671 if (initialDeclaration && forHeadKind) {
4672 bool isForIn, isForOf;
4673 if (!matchInOrOf(&isForIn, &isForOf)) {
4674 return errorResult();
4675 }
4676
4677 if (isForIn) {
4678 *forHeadKind = ParseNodeKind::ForIn;
4679 } else if (isForOf) {
4680 *forHeadKind = ParseNodeKind::ForOf;
4681 } else {
4682 *forHeadKind = ParseNodeKind::ForHead;
4683 }
4684
4685 if (*forHeadKind != ParseNodeKind::ForHead) {
4686 MOZ_TRY_VAR(*forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4687 expressionAfterForInOrOf(*forHeadKind, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4688
4689 return pattern;
4690 }
4691 }
4692
4693 if (!mustMatchToken(TokenKind::Assign, JSMSG_BAD_DESTRUCT_DECL)) {
4694 return errorResult();
4695 }
4696
4697 Node init;
4698 MOZ_TRY_VAR(init, assignExpr(forHeadKind ? InProhibited : InAllowed,do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (init) = mozTryVarTempResult_.unwrap(); } while
(0)
4699 yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (init) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4700
4701 return handler_.newAssignment(ParseNodeKind::AssignExpr, pattern, init);
4702}
4703
4704template <class ParseHandler, typename Unit>
4705typename ParseHandler::AssignmentNodeResult
4706GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
4707 NameNodeType binding, DeclarationKind declKind, bool initialDeclaration,
4708 YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
4709 Node* forInOrOfExpression) {
4710 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assign))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Assign)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Assign)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4710); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assign)"
")"); do { *((volatile int*)__null) = 4710; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4711
4712 uint32_t initializerOffset;
4713 if (!tokenStream.peekOffset(&initializerOffset, TokenStream::SlashIsRegExp)) {
4714 return errorResult();
4715 }
4716
4717 Node initializer;
4718 MOZ_TRY_VAR(initializer, assignExpr(forHeadKind ? InProhibited : InAllowed,do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializer) = mozTryVarTempResult_.unwrap
(); } while (0)
4719 yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializer) = mozTryVarTempResult_.unwrap
(); } while (0)
;
4720
4721 if (forHeadKind && initialDeclaration) {
4722 bool isForIn, isForOf;
4723 if (!matchInOrOf(&isForIn, &isForOf)) {
4724 return errorResult();
4725 }
4726
4727 // An initialized declaration can't appear in a for-of:
4728 //
4729 // for (var/let/const x = ... of ...); // BAD
4730 if (isForOf) {
4731 errorAt(initializerOffset, JSMSG_OF_AFTER_FOR_LOOP_DECL);
4732 return errorResult();
4733 }
4734
4735 if (isForIn) {
4736 // Lexical declarations in for-in loops can't be initialized:
4737 //
4738 // for (let/const x = ... in ...); // BAD
4739 if (DeclarationKindIsLexical(declKind)) {
4740 errorAt(initializerOffset, JSMSG_IN_AFTER_LEXICAL_FOR_DECL);
4741 return errorResult();
4742 }
4743
4744 // This leaves only initialized for-in |var| declarations. ES6
4745 // forbids these; later ES un-forbids in non-strict mode code.
4746 *forHeadKind = ParseNodeKind::ForIn;
4747 if (!strictModeErrorAt(initializerOffset,
4748 JSMSG_INVALID_FOR_IN_DECL_WITH_INIT)) {
4749 return errorResult();
4750 }
4751
4752 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4753 *forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4754 expressionAfterForInOrOf(ParseNodeKind::ForIn, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4755 } else {
4756 *forHeadKind = ParseNodeKind::ForHead;
4757 }
4758 }
4759
4760 return handler_.finishInitializerAssignment(binding, initializer);
4761}
4762
4763template <class ParseHandler, typename Unit>
4764typename ParseHandler::NodeResult
4765GeneralParser<ParseHandler, Unit>::declarationName(DeclarationKind declKind,
4766 TokenKind tt,
4767 bool initialDeclaration,
4768 YieldHandling yieldHandling,
4769 ParseNodeKind* forHeadKind,
4770 Node* forInOrOfExpression) {
4771 // Anything other than possible identifier is an error.
4772 if (!TokenKindIsPossibleIdentifier(tt)) {
4773 error(JSMSG_NO_VARIABLE_NAME);
4774 return errorResult();
4775 }
4776
4777 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
4778 if (!name) {
4779 return errorResult();
4780 }
4781
4782 NameNodeType binding;
4783 MOZ_TRY_VAR(binding, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (binding) = mozTryVarTempResult_.unwrap();
} while (0)
;
4784
4785 TokenPos namePos = pos();
4786
4787 // The '=' context after a variable name in a declaration is an opportunity
4788 // for ASI, and thus for the next token to start an ExpressionStatement:
4789 //
4790 // var foo // VariableDeclaration
4791 // /bar/g; // ExpressionStatement
4792 //
4793 // Therefore get the token here with SlashIsRegExp.
4794 bool matched;
4795 if (!tokenStream.matchToken(&matched, TokenKind::Assign,
4796 TokenStream::SlashIsRegExp)) {
4797 return errorResult();
4798 }
4799
4800 Node declaration;
4801 if (matched) {
4802 MOZ_TRY_VAR(declaration,do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
4803 initializerInNameDeclaration(binding, declKind,do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
4804 initialDeclaration, yieldHandling,do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
4805 forHeadKind, forInOrOfExpression))do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
;
4806 } else {
4807 declaration = binding;
4808
4809 if (initialDeclaration && forHeadKind) {
4810 bool isForIn, isForOf;
4811 if (!matchInOrOf(&isForIn, &isForOf)) {
4812 return errorResult();
4813 }
4814
4815 if (isForIn) {
4816 *forHeadKind = ParseNodeKind::ForIn;
4817#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
4818 if (declKind == DeclarationKind::Using ||
4819 declKind == DeclarationKind::AwaitUsing) {
4820 errorAt(namePos.begin, JSMSG_NO_IN_WITH_USING);
4821 return errorResult();
4822 }
4823#endif
4824 } else if (isForOf) {
4825 *forHeadKind = ParseNodeKind::ForOf;
4826 } else {
4827 *forHeadKind = ParseNodeKind::ForHead;
4828 }
4829 }
4830
4831 if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
4832 MOZ_TRY_VAR(*forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4833 expressionAfterForInOrOf(*forHeadKind, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4834 } else {
4835 // Normal const declarations, and const declarations in for(;;)
4836 // heads, must be initialized.
4837 if (declKind == DeclarationKind::Const) {
4838 errorAt(namePos.begin, JSMSG_BAD_CONST_DECL);
4839 return errorResult();
4840 }
4841 }
4842 }
4843
4844 // Note the declared name after knowing whether or not we are in a for-of
4845 // loop, due to special early error semantics in Annex B.3.5.
4846 if (!noteDeclaredName(name, declKind, namePos)) {
4847 return errorResult();
4848 }
4849
4850 return declaration;
4851}
4852
4853template <class ParseHandler, typename Unit>
4854typename ParseHandler::DeclarationListNodeResult
4855GeneralParser<ParseHandler, Unit>::declarationList(
4856 YieldHandling yieldHandling, ParseNodeKind kind,
4857 ParseNodeKind* forHeadKind /* = nullptr */,
4858 Node* forInOrOfExpression /* = nullptr */) {
4859 MOZ_ASSERT(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4860 kind == ParseNodeKind::ConstDecldo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4861#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENTdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4862 || kind == ParseNodeKind::UsingDecl ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4863 kind == ParseNodeKind::AwaitUsingDecldo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4864#endifdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4865 )do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4866
4867 DeclarationKind declKind;
4868 switch (kind) {
4869 case ParseNodeKind::VarStmt:
4870 declKind = DeclarationKind::Var;
4871 break;
4872 case ParseNodeKind::ConstDecl:
4873 declKind = DeclarationKind::Const;
4874 break;
4875 case ParseNodeKind::LetDecl:
4876 declKind = DeclarationKind::Let;
4877 break;
4878#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
4879 case ParseNodeKind::UsingDecl:
4880 declKind = DeclarationKind::Using;
4881 break;
4882 case ParseNodeKind::AwaitUsingDecl:
4883 declKind = DeclarationKind::AwaitUsing;
4884 break;
4885#endif
4886 default:
4887 MOZ_CRASH("Unknown declaration kind")do { do { } while (false); MOZ_ReportCrash("" "Unknown declaration kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4887); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown declaration kind"
")"); do { *((volatile int*)__null) = 4887; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4888 }
4889
4890 DeclarationListNodeType decl;
4891 MOZ_TRY_VAR(decl, handler_.newDeclarationList(kind, pos()))do { auto mozTryVarTempResult_ = (handler_.newDeclarationList
(kind, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decl) = mozTryVarTempResult_.unwrap(); } while (0)
;
4892
4893 bool moreDeclarations;
4894 bool initialDeclaration = true;
4895 do {
4896 MOZ_ASSERT_IF(!initialDeclaration && forHeadKind,do { if (!initialDeclaration && forHeadKind) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(*forHeadKind
== ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*forHeadKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("*forHeadKind == ParseNodeKind::ForHead", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4897); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*forHeadKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 4897; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
4897 *forHeadKind == ParseNodeKind::ForHead)do { if (!initialDeclaration && forHeadKind) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(*forHeadKind
== ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*forHeadKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("*forHeadKind == ParseNodeKind::ForHead", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4897); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*forHeadKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 4897; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4898
4899 TokenKind tt;
4900 if (!tokenStream.getToken(&tt)) {
4901 return errorResult();
4902 }
4903
4904 Node binding;
4905 if (tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly) {
4906 MOZ_TRY_VAR(binding, declarationPattern(declKind, tt, initialDeclaration,do { auto mozTryVarTempResult_ = (declarationPattern(declKind
, tt, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4907 yieldHandling, forHeadKind,do { auto mozTryVarTempResult_ = (declarationPattern(declKind
, tt, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4908 forInOrOfExpression))do { auto mozTryVarTempResult_ = (declarationPattern(declKind
, tt, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4909 } else {
4910 MOZ_TRY_VAR(binding, declarationName(declKind, tt, initialDeclaration,do { auto mozTryVarTempResult_ = (declarationName(declKind, tt
, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4911 yieldHandling, forHeadKind,do { auto mozTryVarTempResult_ = (declarationName(declKind, tt
, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4912 forInOrOfExpression))do { auto mozTryVarTempResult_ = (declarationName(declKind, tt
, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4913 }
4914
4915 handler_.addList(decl, binding);
4916
4917 // If we have a for-in/of loop, the above call matches the entirety
4918 // of the loop head (up to the closing parenthesis).
4919 if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
4920 break;
4921 }
4922
4923 initialDeclaration = false;
4924
4925 if (!tokenStream.matchToken(&moreDeclarations, TokenKind::Comma,
4926 TokenStream::SlashIsRegExp)) {
4927 return errorResult();
4928 }
4929 } while (moreDeclarations);
4930
4931 return decl;
4932}
4933
4934template <class ParseHandler, typename Unit>
4935typename ParseHandler::DeclarationListNodeResult
4936GeneralParser<ParseHandler, Unit>::lexicalDeclaration(
4937 YieldHandling yieldHandling, DeclarationKind kind) {
4938 MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Letdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4939#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENTdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4940 || kind == DeclarationKind::Using ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4941 kind == DeclarationKind::AwaitUsingdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4942#endifdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4943 )do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4944
4945 if (options().selfHostingMode) {
4946 error(JSMSG_SELFHOSTED_LEXICAL);
4947 return errorResult();
4948 }
4949
4950 /*
4951 * Parse body-level lets without a new block object. ES6 specs
4952 * that an execution environment's initial lexical environment
4953 * is the VariableEnvironment, i.e., body-level lets are in
4954 * the same environment record as vars.
4955 *
4956 * However, they cannot be parsed exactly as vars, as ES6
4957 * requires that uninitialized lets throw ReferenceError on use.
4958 *
4959 * See 8.1.1.1.6 and the note in 13.2.1.
4960 */
4961 DeclarationListNodeType decl;
4962 ParseNodeKind pnk;
4963 switch (kind) {
4964 case DeclarationKind::Const:
4965 pnk = ParseNodeKind::ConstDecl;
4966 break;
4967#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
4968 case DeclarationKind::Using:
4969 pnk = ParseNodeKind::UsingDecl;
4970 break;
4971 case DeclarationKind::AwaitUsing:
4972 pnk = ParseNodeKind::AwaitUsingDecl;
4973 break;
4974#endif
4975 case DeclarationKind::Let:
4976 pnk = ParseNodeKind::LetDecl;
4977 break;
4978 default:
4979 MOZ_CRASH("unexpected node kind")do { do { } while (false); MOZ_ReportCrash("" "unexpected node kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4979); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected node kind"
")"); do { *((volatile int*)__null) = 4979; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4980 }
4981 MOZ_TRY_VAR(decl, declarationList(yieldHandling, pnk))do { auto mozTryVarTempResult_ = (declarationList(yieldHandling
, pnk)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr(
)), 0))) { return mozTryVarTempResult_.propagateErr(); } (decl
) = mozTryVarTempResult_.unwrap(); } while (0)
;
4982 if (!matchOrInsertSemicolon()) {
4983 return errorResult();
4984 }
4985
4986 return decl;
4987}
4988
4989template <class ParseHandler, typename Unit>
4990typename ParseHandler::NameNodeResult
4991GeneralParser<ParseHandler, Unit>::moduleExportName() {
4992 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::String)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::String)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::String)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type == TokenKind::String"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4992); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::String"
")"); do { *((volatile int*)__null) = 4992; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4993 TaggedParserAtomIndex name = anyChars.currentToken().atom();
4994 if (!this->parserAtoms().isModuleExportName(name)) {
4995 error(JSMSG_UNPAIRED_SURROGATE_EXPORT);
4996 return errorResult();
4997 }
4998 return handler_.newStringLiteral(name, pos());
4999}
5000
5001template <class ParseHandler, typename Unit>
5002bool GeneralParser<ParseHandler, Unit>::withClause(ListNodeType attributesSet) {
5003 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assert) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars
.isCurrentTokenType(TokenKind::With))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::
With)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5004); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 5004; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5004 anyChars.isCurrentTokenType(TokenKind::With))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars
.isCurrentTokenType(TokenKind::With))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::
With)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5004); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 5004; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5005
5006 if (!options().importAttributes()) {
5007 error(JSMSG_IMPORT_ASSERTIONS_NOT_SUPPORTED);
5008 return false;
5009 }
5010
5011 if (!abortIfSyntaxParser()) {
5012 return false;
5013 }
5014
5015 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_AFTER_ASSERT)) {
5016 return false;
5017 }
5018
5019 // Handle the form |... assert {}|
5020 TokenKind token;
5021 if (!tokenStream.getToken(&token)) {
5022 return false;
5023 }
5024 if (token == TokenKind::RightCurly) {
5025 return true;
5026 }
5027
5028 js::HashSet<TaggedParserAtomIndex, TaggedParserAtomIndexHasher,
5029 js::SystemAllocPolicy>
5030 usedAssertionKeys;
5031
5032 for (;;) {
5033 TaggedParserAtomIndex keyName;
5034 if (TokenKindIsPossibleIdentifierName(token)) {
5035 keyName = anyChars.currentName();
5036 } else if (token == TokenKind::String) {
5037 keyName = anyChars.currentToken().atom();
5038 } else {
5039 error(JSMSG_ASSERT_KEY_EXPECTED);
5040 return false;
5041 }
5042
5043 auto p = usedAssertionKeys.lookupForAdd(keyName);
5044 if (p) {
5045 UniqueChars str = this->parserAtoms().toPrintableString(keyName);
5046 if (!str) {
5047 ReportOutOfMemory(this->fc_);
5048 return false;
5049 }
5050 error(JSMSG_DUPLICATE_ASSERT_KEY, str.get());
5051 return false;
5052 }
5053 if (!usedAssertionKeys.add(p, keyName)) {
5054 ReportOutOfMemory(this->fc_);
5055 return false;
5056 }
5057
5058 NameNodeType keyNode;
5059 MOZ_TRY_VAR_OR_RETURN(keyNode, newName(keyName), false)do { auto parserTryVarTempResult_ = (newName(keyName)); if ((
__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) { return
(false); } (keyNode) = parserTryVarTempResult_.unwrap(); } while
(0)
;
5060
5061 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_ASSERT_KEY)) {
5062 return false;
5063 }
5064 if (!mustMatchToken(TokenKind::String, JSMSG_ASSERT_STRING_LITERAL)) {
5065 return false;
5066 }
5067
5068 NameNodeType valueNode;
5069 MOZ_TRY_VAR_OR_RETURN(valueNode, stringLiteral(), false)do { auto parserTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(valueNode) = parserTryVarTempResult_.unwrap(); } while (0)
;
5070
5071 BinaryNodeType importAttributeNode;
5072 MOZ_TRY_VAR_OR_RETURN(importAttributeNode,do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
5073 handler_.newImportAttribute(keyNode, valueNode),do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
5074 false)do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5075
5076 handler_.addList(attributesSet, importAttributeNode);
5077
5078 if (!tokenStream.getToken(&token)) {
5079 return false;
5080 }
5081 if (token == TokenKind::Comma) {
5082 if (!tokenStream.getToken(&token)) {
5083 return false;
5084 }
5085 }
5086 if (token == TokenKind::RightCurly) {
5087 break;
5088 }
5089 }
5090
5091 return true;
5092}
5093
5094template <class ParseHandler, typename Unit>
5095bool GeneralParser<ParseHandler, Unit>::namedImports(
5096 ListNodeType importSpecSet) {
5097 if (!abortIfSyntaxParser()) {
5098 return false;
5099 }
5100
5101 while (true) {
5102 // Handle the forms |import {} from 'a'| and
5103 // |import { ..., } from 'a'| (where ... is non empty), by
5104 // escaping the loop early if the next token is }.
5105 TokenKind tt;
5106 if (!tokenStream.getToken(&tt)) {
5107 return false;
5108 }
5109
5110 if (tt == TokenKind::RightCurly) {
5111 break;
5112 }
5113
5114 TaggedParserAtomIndex importName;
5115 NameNodeType importNameNode = null();
5116 if (TokenKindIsPossibleIdentifierName(tt)) {
5117 importName = anyChars.currentName();
5118 MOZ_TRY_VAR_OR_RETURN(importNameNode, newName(importName), false)do { auto parserTryVarTempResult_ = (newName(importName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (importNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5119 } else if (tt == TokenKind::String) {
5120 MOZ_TRY_VAR_OR_RETURN(importNameNode, moduleExportName(), false)do { auto parserTryVarTempResult_ = (moduleExportName()); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (importNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5121 } else {
5122 error(JSMSG_NO_IMPORT_NAME);
5123 return false;
5124 }
5125
5126 bool matched;
5127 if (!tokenStream.matchToken(&matched, TokenKind::As)) {
5128 return false;
5129 }
5130
5131 if (matched) {
5132 TokenKind afterAs;
5133 if (!tokenStream.getToken(&afterAs)) {
5134 return false;
5135 }
5136
5137 if (!TokenKindIsPossibleIdentifierName(afterAs)) {
5138 error(JSMSG_NO_BINDING_NAME);
5139 return false;
5140 }
5141 } else {
5142 // String export names can't refer to local bindings.
5143 if (tt == TokenKind::String) {
5144 error(JSMSG_AS_AFTER_STRING);
5145 return false;
5146 }
5147
5148 // Keywords cannot be bound to themselves, so an import name
5149 // that is a keyword is a syntax error if it is not followed
5150 // by the keyword 'as'.
5151 // See the ImportSpecifier production in ES6 section 15.2.2.
5152 MOZ_ASSERT(importName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(importName)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(importName))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("importName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5152); AnnotateMozCrashReason("MOZ_ASSERT" "(" "importName"
")"); do { *((volatile int*)__null) = 5152; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5153 if (IsKeyword(importName)) {
5154 error(JSMSG_AS_AFTER_RESERVED_WORD, ReservedWordToCharZ(importName));
5155 return false;
5156 }
5157 }
5158
5159 TaggedParserAtomIndex bindingAtom = importedBinding();
5160 if (!bindingAtom) {
5161 return false;
5162 }
5163
5164 NameNodeType bindingName;
5165 MOZ_TRY_VAR_OR_RETURN(bindingName, newName(bindingAtom), false)do { auto parserTryVarTempResult_ = (newName(bindingAtom)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (bindingName) = parserTryVarTempResult_.
unwrap(); } while (0)
;
5166 if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
5167 return false;
5168 }
5169
5170 BinaryNodeType importSpec;
5171 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newImportSpec(importNameNode
, bindingName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5172 importSpec, handler_.newImportSpec(importNameNode, bindingName), false)do { auto parserTryVarTempResult_ = (handler_.newImportSpec(importNameNode
, bindingName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5173
5174 handler_.addList(importSpecSet, importSpec);
5175
5176 TokenKind next;
5177 if (!tokenStream.getToken(&next)) {
5178 return false;
5179 }
5180
5181 if (next == TokenKind::RightCurly) {
5182 break;
5183 }
5184
5185 if (next != TokenKind::Comma) {
5186 error(JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
5187 return false;
5188 }
5189 }
5190
5191 return true;
5192}
5193
5194template <class ParseHandler, typename Unit>
5195bool GeneralParser<ParseHandler, Unit>::namespaceImport(
5196 ListNodeType importSpecSet) {
5197 if (!abortIfSyntaxParser()) {
5198 return false;
5199 }
5200
5201 if (!mustMatchToken(TokenKind::As, JSMSG_AS_AFTER_IMPORT_STAR)) {
5202 return false;
5203 }
5204 uint32_t begin = pos().begin;
5205
5206 if (!mustMatchToken(TokenKindIsPossibleIdentifierName,
5207 JSMSG_NO_BINDING_NAME)) {
5208 return false;
5209 }
5210
5211 // Namespace imports are not indirect bindings but lexical
5212 // definitions that hold a module namespace object. They are treated
5213 // as const variables which are initialized during the
5214 // ModuleInstantiate step.
5215 TaggedParserAtomIndex bindingName = importedBinding();
5216 if (!bindingName) {
5217 return false;
5218 }
5219 NameNodeType bindingNameNode;
5220 MOZ_TRY_VAR_OR_RETURN(bindingNameNode, newName(bindingName), false)do { auto parserTryVarTempResult_ = (newName(bindingName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (bindingNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5221 if (!noteDeclaredName(bindingName, DeclarationKind::Const, pos())) {
5222 return false;
5223 }
5224
5225 // The namespace import name is currently required to live on the
5226 // environment.
5227 pc_->varScope().lookupDeclaredName(bindingName)->value()->setClosedOver();
5228
5229 UnaryNodeType importSpec;
5230 MOZ_TRY_VAR_OR_RETURN(importSpec,do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5231 handler_.newImportNamespaceSpec(begin, bindingNameNode),do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5232 false)do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5233
5234 handler_.addList(importSpecSet, importSpec);
5235
5236 return true;
5237}
5238
5239template <class ParseHandler, typename Unit>
5240typename ParseHandler::BinaryNodeResult
5241GeneralParser<ParseHandler, Unit>::importDeclaration() {
5242 if (!abortIfSyntaxParser()) {
5243 return errorResult();
5244 }
5245
5246 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Import))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Import)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Import)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5246); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 5246; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5247
5248 if (!pc_->atModuleLevel()) {
5249 error(JSMSG_IMPORT_DECL_AT_TOP_LEVEL);
5250 return errorResult();
5251 }
5252
5253 uint32_t begin = pos().begin;
5254 TokenKind tt;
5255 if (!tokenStream.getToken(&tt)) {
5256 return errorResult();
5257 }
5258
5259 ListNodeType importSpecSet;
5260 MOZ_TRY_VAR(importSpecSet,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importSpecSet) = mozTryVarTempResult_.unwrap(); } while (
0)
5261 handler_.newList(ParseNodeKind::ImportSpecList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importSpecSet) = mozTryVarTempResult_.unwrap(); } while (
0)
;
5262
5263 if (tt == TokenKind::String) {
5264 // Handle the form |import 'a'| by leaving the list empty. This is
5265 // equivalent to |import {} from 'a'|.
5266 handler_.setEndPosition(importSpecSet, pos().begin);
5267 } else {
5268 if (tt == TokenKind::LeftCurly) {
5269 if (!namedImports(importSpecSet)) {
5270 return errorResult();
5271 }
5272 } else if (tt == TokenKind::Mul) {
5273 if (!namespaceImport(importSpecSet)) {
5274 return errorResult();
5275 }
5276 } else if (TokenKindIsPossibleIdentifierName(tt)) {
5277 // Handle the form |import a from 'b'|, by adding a single import
5278 // specifier to the list, with 'default' as the import name and
5279 // 'a' as the binding name. This is equivalent to
5280 // |import { default as a } from 'b'|.
5281 NameNodeType importName;
5282 MOZ_TRY_VAR(importName,do { auto mozTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::default_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importName) = mozTryVarTempResult_.unwrap(); } while (0)
5283 newName(TaggedParserAtomIndex::WellKnown::default_()))do { auto mozTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::default_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importName) = mozTryVarTempResult_.unwrap(); } while (0)
;
5284
5285 TaggedParserAtomIndex bindingAtom = importedBinding();
5286 if (!bindingAtom) {
5287 return errorResult();
5288 }
5289
5290 NameNodeType bindingName;
5291 MOZ_TRY_VAR(bindingName, newName(bindingAtom))do { auto mozTryVarTempResult_ = (newName(bindingAtom)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (bindingName) = mozTryVarTempResult_
.unwrap(); } while (0)
;
5292
5293 if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
5294 return errorResult();
5295 }
5296
5297 BinaryNodeType importSpec;
5298 MOZ_TRY_VAR(importSpec, handler_.newImportSpec(importName, bindingName))do { auto mozTryVarTempResult_ = (handler_.newImportSpec(importName
, bindingName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importSpec) = mozTryVarTempResult_.unwrap(); } while (0)
;
5299
5300 handler_.addList(importSpecSet, importSpec);
5301
5302 if (!tokenStream.peekToken(&tt)) {
5303 return errorResult();
5304 }
5305
5306 if (tt == TokenKind::Comma) {
5307 tokenStream.consumeKnownToken(tt);
5308 if (!tokenStream.getToken(&tt)) {
5309 return errorResult();
5310 }
5311
5312 if (tt == TokenKind::LeftCurly) {
5313 if (!namedImports(importSpecSet)) {
5314 return errorResult();
5315 }
5316 } else if (tt == TokenKind::Mul) {
5317 if (!namespaceImport(importSpecSet)) {
5318 return errorResult();
5319 }
5320 } else {
5321 error(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT);
5322 return errorResult();
5323 }
5324 }
5325 } else {
5326 error(JSMSG_DECLARATION_AFTER_IMPORT);
5327 return errorResult();
5328 }
5329
5330 if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_IMPORT_CLAUSE)) {
5331 return errorResult();
5332 }
5333
5334 if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
5335 return errorResult();
5336 }
5337 }
5338
5339 NameNodeType moduleSpec;
5340 MOZ_TRY_VAR(moduleSpec, stringLiteral())do { auto mozTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleSpec) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5341
5342 // The `assert` keyword has a [no LineTerminator here] production before it in
5343 // the grammar -- `with` does not. We need to handle this distinction.
5344 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
5345 return errorResult();
5346 }
5347
5348 // `with` may have an EOL prior, so peek the next token and replace
5349 // EOL if the next token is `with`.
5350 if (tt == TokenKind::Eol) {
5351 // Doing a regular peek won't produce Eol, but the actual next token.
5352 TokenKind peekedToken;
5353 if (!tokenStream.peekToken(&peekedToken, TokenStream::SlashIsRegExp)) {
5354 return errorResult();
5355 }
5356
5357 if (peekedToken == TokenKind::With) {
5358 tt = TokenKind::With;
5359 }
5360 }
5361
5362 ListNodeType importAttributeList;
5363 MOZ_TRY_VAR(importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
5364 handler_.newList(ParseNodeKind::ImportAttributeList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
;
5365
5366 if (tt == TokenKind::With ||
5367 (tt == TokenKind::Assert && options().importAttributesAssertSyntax())) {
5368 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
5369
5370 if (!withClause(importAttributeList)) {
5371 return errorResult();
5372 }
5373 }
5374
5375 if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
5376 return errorResult();
5377 }
5378
5379 BinaryNodeType moduleRequest;
5380 MOZ_TRY_VAR(moduleRequest,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleRequest) = mozTryVarTempResult_.unwrap
(); } while (0)
5381 handler_.newModuleRequest(moduleSpec, importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleRequest) = mozTryVarTempResult_.unwrap
(); } while (0)
5382 TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleRequest) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5383
5384 BinaryNodeType node;
5385 MOZ_TRY_VAR(node, handler_.newImportDeclaration(importSpecSet, moduleRequest,do { auto mozTryVarTempResult_ = (handler_.newImportDeclaration
(importSpecSet, moduleRequest, TokenPos(begin, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (node) = mozTryVarTempResult_
.unwrap(); } while (0)
5386 TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newImportDeclaration
(importSpecSet, moduleRequest, TokenPos(begin, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (node) = mozTryVarTempResult_
.unwrap(); } while (0)
;
5387 if (!processImport(node)) {
5388 return errorResult();
5389 }
5390
5391 return node;
5392}
5393
5394template <class ParseHandler, typename Unit>
5395inline typename ParseHandler::NodeResult
5396GeneralParser<ParseHandler, Unit>::importDeclarationOrImportExpr(
5397 YieldHandling yieldHandling) {
5398 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Import))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Import)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Import)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5398); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 5398; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5399
5400 TokenKind tt;
5401 if (!tokenStream.peekToken(&tt)) {
5402 return errorResult();
5403 }
5404
5405 if (tt == TokenKind::Dot || tt == TokenKind::LeftParen) {
5406 return expressionStatement(yieldHandling);
5407 }
5408
5409 return importDeclaration();
5410}
5411
5412template <typename Unit>
5413bool Parser<FullParseHandler, Unit>::checkExportedName(
5414 TaggedParserAtomIndex exportName) {
5415 switch (pc_->sc()->asModuleContext()->builder.noteExportedName(exportName)) {
5416 case ModuleBuilder::NoteExportedNameResult::Success:
5417 return true;
5418 case ModuleBuilder::NoteExportedNameResult::OutOfMemory:
5419 return false;
5420 case ModuleBuilder::NoteExportedNameResult::AlreadyDeclared:
5421 break;
5422 }
5423
5424 UniqueChars str = this->parserAtoms().toPrintableString(exportName);
5425 if (!str) {
5426 ReportOutOfMemory(this->fc_);
5427 return false;
5428 }
5429
5430 error(JSMSG_DUPLICATE_EXPORT_NAME, str.get());
5431 return false;
5432}
5433
5434template <typename Unit>
5435inline bool Parser<SyntaxParseHandler, Unit>::checkExportedName(
5436 TaggedParserAtomIndex exportName) {
5437 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5437); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5437; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5438 return false;
5439}
5440
5441template <class ParseHandler, typename Unit>
5442inline bool GeneralParser<ParseHandler, Unit>::checkExportedName(
5443 TaggedParserAtomIndex exportName) {
5444 return asFinalParser()->checkExportedName(exportName);
5445}
5446
5447template <typename Unit>
5448bool Parser<FullParseHandler, Unit>::checkExportedNamesForArrayBinding(
5449 ListNode* array) {
5450 MOZ_ASSERT(array->isKind(ParseNodeKind::ArrayExpr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(array->isKind(ParseNodeKind::ArrayExpr))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(array->isKind(ParseNodeKind::ArrayExpr)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("array->isKind(ParseNodeKind::ArrayExpr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5450); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array->isKind(ParseNodeKind::ArrayExpr)"
")"); do { *((volatile int*)__null) = 5450; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5451
5452 for (ParseNode* node : array->contents()) {
5453 if (node->isKind(ParseNodeKind::Elision)) {
5454 continue;
5455 }
5456
5457 ParseNode* binding;
5458 if (node->isKind(ParseNodeKind::Spread)) {
5459 binding = node->as<UnaryNode>().kid();
5460 } else if (node->isKind(ParseNodeKind::AssignExpr)) {
5461 binding = node->as<AssignmentNode>().left();
5462 } else {
5463 binding = node;
5464 }
5465
5466 if (!checkExportedNamesForDeclaration(binding)) {
5467 return false;
5468 }
5469 }
5470
5471 return true;
5472}
5473
5474template <typename Unit>
5475inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForArrayBinding(
5476 ListNodeType array) {
5477 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5477); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5477; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5478 return false;
5479}
5480
5481template <class ParseHandler, typename Unit>
5482inline bool
5483GeneralParser<ParseHandler, Unit>::checkExportedNamesForArrayBinding(
5484 ListNodeType array) {
5485 return asFinalParser()->checkExportedNamesForArrayBinding(array);
5486}
5487
5488template <typename Unit>
5489bool Parser<FullParseHandler, Unit>::checkExportedNamesForObjectBinding(
5490 ListNode* obj) {
5491 MOZ_ASSERT(obj->isKind(ParseNodeKind::ObjectExpr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(obj->isKind(ParseNodeKind::ObjectExpr))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(obj->isKind(ParseNodeKind::ObjectExpr)))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("obj->isKind(ParseNodeKind::ObjectExpr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->isKind(ParseNodeKind::ObjectExpr)"
")"); do { *((volatile int*)__null) = 5491; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5492
5493 for (ParseNode* node : obj->contents()) {
5494 MOZ_ASSERT(node->isKind(ParseNodeKind::MutateProto) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5497; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5495 node->isKind(ParseNodeKind::PropertyDefinition) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5497; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5496 node->isKind(ParseNodeKind::Shorthand) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5497; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5497 node->isKind(ParseNodeKind::Spread))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5497; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5498
5499 ParseNode* target;
5500 if (node->isKind(ParseNodeKind::Spread)) {
5501 target = node->as<UnaryNode>().kid();
5502 } else {
5503 if (node->isKind(ParseNodeKind::MutateProto)) {
5504 target = node->as<UnaryNode>().kid();
5505 } else {
5506 target = node->as<BinaryNode>().right();
5507 }
5508
5509 if (target->isKind(ParseNodeKind::AssignExpr)) {
5510 target = target->as<AssignmentNode>().left();
5511 }
5512 }
5513
5514 if (!checkExportedNamesForDeclaration(target)) {
5515 return false;
5516 }
5517 }
5518
5519 return true;
5520}
5521
5522template <typename Unit>
5523inline bool Parser<SyntaxParseHandler,
5524 Unit>::checkExportedNamesForObjectBinding(ListNodeType obj) {
5525 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5525); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5525; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5526 return false;
5527}
5528
5529template <class ParseHandler, typename Unit>
5530inline bool
5531GeneralParser<ParseHandler, Unit>::checkExportedNamesForObjectBinding(
5532 ListNodeType obj) {
5533 return asFinalParser()->checkExportedNamesForObjectBinding(obj);
5534}
5535
5536template <typename Unit>
5537bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclaration(
5538 ParseNode* node) {
5539 if (node->isKind(ParseNodeKind::Name)) {
5540 if (!checkExportedName(node->as<NameNode>().atom())) {
5541 return false;
5542 }
5543 } else if (node->isKind(ParseNodeKind::ArrayExpr)) {
5544 if (!checkExportedNamesForArrayBinding(&node->as<ListNode>())) {
5545 return false;
5546 }
5547 } else {
5548 MOZ_ASSERT(node->isKind(ParseNodeKind::ObjectExpr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::ObjectExpr))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(node->isKind(ParseNodeKind::ObjectExpr)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("node->isKind(ParseNodeKind::ObjectExpr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5548); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::ObjectExpr)"
")"); do { *((volatile int*)__null) = 5548; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5549 if (!checkExportedNamesForObjectBinding(&node->as<ListNode>())) {
5550 return false;
5551 }
5552 }
5553
5554 return true;
5555}
5556
5557template <typename Unit>
5558inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForDeclaration(
5559 Node node) {
5560 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5560); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5560; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5561 return false;
5562}
5563
5564template <class ParseHandler, typename Unit>
5565inline bool GeneralParser<ParseHandler, Unit>::checkExportedNamesForDeclaration(
5566 Node node) {
5567 return asFinalParser()->checkExportedNamesForDeclaration(node);
5568}
5569
5570template <typename Unit>
5571bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclarationList(
5572 DeclarationListNodeType node) {
5573 for (ParseNode* binding : node->contents()) {
5574 if (binding->isKind(ParseNodeKind::AssignExpr)) {
5575 binding = binding->as<AssignmentNode>().left();
5576 } else {
5577 MOZ_ASSERT(binding->isKind(ParseNodeKind::Name))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(binding->isKind(ParseNodeKind::Name))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(binding->isKind(ParseNodeKind::Name)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("binding->isKind(ParseNodeKind::Name)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5577); AnnotateMozCrashReason("MOZ_ASSERT" "(" "binding->isKind(ParseNodeKind::Name)"
")"); do { *((volatile int*)__null) = 5577; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5578 }
5579
5580 if (!checkExportedNamesForDeclaration(binding)) {
5581 return false;
5582 }
5583 }
5584
5585 return true;
5586}
5587
5588template <typename Unit>
5589inline bool
5590Parser<SyntaxParseHandler, Unit>::checkExportedNamesForDeclarationList(
5591 DeclarationListNodeType node) {
5592 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5592); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5592; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5593 return false;
5594}
5595
5596template <class ParseHandler, typename Unit>
5597inline bool
5598GeneralParser<ParseHandler, Unit>::checkExportedNamesForDeclarationList(
5599 DeclarationListNodeType node) {
5600 return asFinalParser()->checkExportedNamesForDeclarationList(node);
5601}
5602
5603template <typename Unit>
5604inline bool Parser<FullParseHandler, Unit>::checkExportedNameForClause(
5605 NameNode* nameNode) {
5606 return checkExportedName(nameNode->atom());
5607}
5608
5609template <typename Unit>
5610inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForClause(
5611 NameNodeType nameNode) {
5612 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5612); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5612; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5613 return false;
5614}
5615
5616template <class ParseHandler, typename Unit>
5617inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForClause(
5618 NameNodeType nameNode) {
5619 return asFinalParser()->checkExportedNameForClause(nameNode);
5620}
5621
5622template <typename Unit>
5623bool Parser<FullParseHandler, Unit>::checkExportedNameForFunction(
5624 FunctionNode* funNode) {
5625 return checkExportedName(funNode->funbox()->explicitName());
5626}
5627
5628template <typename Unit>
5629inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForFunction(
5630 FunctionNodeType funNode) {
5631 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5631); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5631; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5632 return false;
5633}
5634
5635template <class ParseHandler, typename Unit>
5636inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForFunction(
5637 FunctionNodeType funNode) {
5638 return asFinalParser()->checkExportedNameForFunction(funNode);
5639}
5640
5641template <typename Unit>
5642bool Parser<FullParseHandler, Unit>::checkExportedNameForClass(
5643 ClassNode* classNode) {
5644 MOZ_ASSERT(classNode->names())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(classNode->names())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(classNode->names()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("classNode->names()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5644); AnnotateMozCrashReason("MOZ_ASSERT" "(" "classNode->names()"
")"); do { *((volatile int*)__null) = 5644; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5645 return checkExportedName(classNode->names()->innerBinding()->atom());
5646}
5647
5648template <typename Unit>
5649inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForClass(
5650 ClassNodeType classNode) {
5651 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5651); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5651; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5652 return false;
5653}
5654
5655template <class ParseHandler, typename Unit>
5656inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForClass(
5657 ClassNodeType classNode) {
5658 return asFinalParser()->checkExportedNameForClass(classNode);
5659}
5660
5661template <>
5662inline bool PerHandlerParser<FullParseHandler>::processExport(ParseNode* node) {
5663 return pc_->sc()->asModuleContext()->builder.processExport(node);
5664}
5665
5666template <>
5667inline bool PerHandlerParser<SyntaxParseHandler>::processExport(Node node) {
5668 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5668); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5668; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5669 return false;
5670}
5671
5672template <>
5673inline bool PerHandlerParser<FullParseHandler>::processExportFrom(
5674 BinaryNodeType node) {
5675 return pc_->sc()->asModuleContext()->builder.processExportFrom(node);
5676}
5677
5678template <>
5679inline bool PerHandlerParser<SyntaxParseHandler>::processExportFrom(
5680 BinaryNodeType node) {
5681 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5681); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5681; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5682 return false;
5683}
5684
5685template <>
5686inline bool PerHandlerParser<FullParseHandler>::processImport(
5687 BinaryNodeType node) {
5688 return pc_->sc()->asModuleContext()->builder.processImport(node);
5689}
5690
5691template <>
5692inline bool PerHandlerParser<SyntaxParseHandler>::processImport(
5693 BinaryNodeType node) {
5694 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5694); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5694; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5695 return false;
5696}
5697
5698template <class ParseHandler, typename Unit>
5699typename ParseHandler::BinaryNodeResult
5700GeneralParser<ParseHandler, Unit>::exportFrom(uint32_t begin, Node specList) {
5701 if (!abortIfSyntaxParser()) {
5702 return errorResult();
5703 }
5704
5705 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::From))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::From))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::From)))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::From)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5705); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::From)"
")"); do { *((volatile int*)__null) = 5705; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5706
5707 if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
5708 return errorResult();
5709 }
5710
5711 NameNodeType moduleSpec;
5712 MOZ_TRY_VAR(moduleSpec, stringLiteral())do { auto mozTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleSpec) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5713
5714 TokenKind tt;
5715
5716 // The `assert` keyword has a [no LineTerminator here] production before it in
5717 // the grammar -- `with` does not. We need to handle this distinction.
5718 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
5719 return errorResult();
5720 }
5721
5722 // `with` may have an EOL prior, so peek the next token and replace
5723 // EOL if the next token is `with`.
5724 if (tt == TokenKind::Eol) {
5725 // Doing a regular peek won't produce Eol, but the actual next token.
5726 TokenKind peekedToken;
5727 if (!tokenStream.peekToken(&peekedToken, TokenStream::SlashIsRegExp)) {
5728 return errorResult();
5729 }
5730
5731 if (peekedToken == TokenKind::With) {
5732 tt = TokenKind::With;
5733 }
5734 }
5735
5736 uint32_t moduleSpecPos = pos().begin;
5737
5738 ListNodeType importAttributeList;
5739 MOZ_TRY_VAR(importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
5740 handler_.newList(ParseNodeKind::ImportAttributeList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
;
5741 if (tt == TokenKind::With ||
5742 (tt == TokenKind::Assert && options().importAttributesAssertSyntax())) {
5743 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
5744
5745 if (!withClause(importAttributeList)) {
5746 return errorResult();
5747 }
5748 }
5749
5750 if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
5751 return errorResult();
5752 }
5753
5754 BinaryNodeType moduleRequest;
5755 MOZ_TRY_VAR(moduleRequest,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(moduleSpecPos, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (moduleRequest) = mozTryVarTempResult_
.unwrap(); } while (0)
5756 handler_.newModuleRequest(moduleSpec, importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(moduleSpecPos, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (moduleRequest) = mozTryVarTempResult_
.unwrap(); } while (0)
5757 TokenPos(moduleSpecPos, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(moduleSpecPos, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (moduleRequest) = mozTryVarTempResult_
.unwrap(); } while (0)
;
5758
5759 BinaryNodeType node;
5760 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (handler_.newExportFromDeclaration
(begin, specList, moduleRequest)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (node) = mozTryVarTempResult_.unwrap(); } while (0)
5761 node, handler_.newExportFromDeclaration(begin, specList, moduleRequest))do { auto mozTryVarTempResult_ = (handler_.newExportFromDeclaration
(begin, specList, moduleRequest)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (node) = mozTryVarTempResult_.unwrap(); } while (0)
;
5762
5763 if (!processExportFrom(node)) {
5764 return errorResult();
5765 }
5766
5767 return node;
5768}
5769
5770template <class ParseHandler, typename Unit>
5771typename ParseHandler::BinaryNodeResult
5772GeneralParser<ParseHandler, Unit>::exportBatch(uint32_t begin) {
5773 if (!abortIfSyntaxParser()) {
5774 return errorResult();
5775 }
5776
5777 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Mul))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Mul))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Mul)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Mul)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5777); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Mul)"
")"); do { *((volatile int*)__null) = 5777; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5778 uint32_t beginExportSpec = pos().begin;
5779
5780 ListNodeType kid;
5781 MOZ_TRY_VAR(kid, handler_.newList(ParseNodeKind::ExportSpecList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ExportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
5782
5783 bool foundAs;
5784 if (!tokenStream.matchToken(&foundAs, TokenKind::As)) {
5785 return errorResult();
5786 }
5787
5788 if (foundAs) {
5789 TokenKind tt;
5790 if (!tokenStream.getToken(&tt)) {
5791 return errorResult();
5792 }
5793
5794 NameNodeType exportName = null();
5795 if (TokenKindIsPossibleIdentifierName(tt)) {
5796 MOZ_TRY_VAR(exportName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (exportName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5797 } else if (tt == TokenKind::String) {
5798 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5799 } else {
5800 error(JSMSG_NO_EXPORT_NAME);
5801 return errorResult();
5802 }
5803
5804 if (!checkExportedNameForClause(exportName)) {
5805 return errorResult();
5806 }
5807
5808 UnaryNodeType exportSpec;
5809 MOZ_TRY_VAR(exportSpec,do { auto mozTryVarTempResult_ = (handler_.newExportNamespaceSpec
(beginExportSpec, exportName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exportSpec) = mozTryVarTempResult_.unwrap(); } while (0)
5810 handler_.newExportNamespaceSpec(beginExportSpec, exportName))do { auto mozTryVarTempResult_ = (handler_.newExportNamespaceSpec
(beginExportSpec, exportName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exportSpec) = mozTryVarTempResult_.unwrap(); } while (0)
;
5811
5812 handler_.addList(kid, exportSpec);
5813 } else {
5814 // Handle the form |export *| by adding a special export batch
5815 // specifier to the list.
5816 NullaryNodeType exportSpec;
5817 MOZ_TRY_VAR(exportSpec, handler_.newExportBatchSpec(pos()))do { auto mozTryVarTempResult_ = (handler_.newExportBatchSpec
(pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (exportSpec
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5818
5819 handler_.addList(kid, exportSpec);
5820 }
5821
5822 if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_EXPORT_STAR)) {
5823 return errorResult();
5824 }
5825
5826 return exportFrom(begin, kid);
5827}
5828
5829template <typename Unit>
5830bool Parser<FullParseHandler, Unit>::checkLocalExportNames(ListNode* node) {
5831 // ES 2017 draft 15.2.3.1.
5832 for (ParseNode* next : node->contents()) {
5833 ParseNode* name = next->as<BinaryNode>().left();
5834
5835 if (name->isKind(ParseNodeKind::StringExpr)) {
5836 errorAt(name->pn_pos.begin, JSMSG_BAD_LOCAL_STRING_EXPORT);
5837 return false;
5838 }
5839
5840 MOZ_ASSERT(name->isKind(ParseNodeKind::Name))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name->isKind(ParseNodeKind::Name))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(name->isKind(ParseNodeKind
::Name)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("name->isKind(ParseNodeKind::Name)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5840); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name->isKind(ParseNodeKind::Name)"
")"); do { *((volatile int*)__null) = 5840; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5841
5842 TaggedParserAtomIndex ident = name->as<NameNode>().atom();
5843 if (!checkLocalExportName(ident, name->pn_pos.begin)) {
5844 return false;
5845 }
5846 }
5847
5848 return true;
5849}
5850
5851template <typename Unit>
5852bool Parser<SyntaxParseHandler, Unit>::checkLocalExportNames(
5853 ListNodeType node) {
5854 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5854); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5854; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5855 return false;
5856}
5857
5858template <class ParseHandler, typename Unit>
5859inline bool GeneralParser<ParseHandler, Unit>::checkLocalExportNames(
5860 ListNodeType node) {
5861 return asFinalParser()->checkLocalExportNames(node);
5862}
5863
5864template <class ParseHandler, typename Unit>
5865typename ParseHandler::NodeResult
5866GeneralParser<ParseHandler, Unit>::exportClause(uint32_t begin) {
5867 if (!abortIfSyntaxParser()) {
5868 return errorResult();
5869 }
5870
5871 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5871); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 5871; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5872
5873 ListNodeType kid;
5874 MOZ_TRY_VAR(kid, handler_.newList(ParseNodeKind::ExportSpecList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ExportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
5875
5876 TokenKind tt;
5877 while (true) {
5878 // Handle the forms |export {}| and |export { ..., }| (where ... is non
5879 // empty), by escaping the loop early if the next token is }.
5880 if (!tokenStream.getToken(&tt)) {
5881 return errorResult();
5882 }
5883
5884 if (tt == TokenKind::RightCurly) {
5885 break;
5886 }
5887
5888 NameNodeType bindingName = null();
5889 if (TokenKindIsPossibleIdentifierName(tt)) {
5890 MOZ_TRY_VAR(bindingName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (bindingName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5891 } else if (tt == TokenKind::String) {
5892 MOZ_TRY_VAR(bindingName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (bindingName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5893 } else {
5894 error(JSMSG_NO_BINDING_NAME);
5895 return errorResult();
5896 }
5897
5898 bool foundAs;
5899 if (!tokenStream.matchToken(&foundAs, TokenKind::As)) {
5900 return errorResult();
5901 }
5902
5903 NameNodeType exportName = null();
5904 if (foundAs) {
5905 TokenKind tt;
5906 if (!tokenStream.getToken(&tt)) {
5907 return errorResult();
5908 }
5909
5910 if (TokenKindIsPossibleIdentifierName(tt)) {
5911 MOZ_TRY_VAR(exportName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (exportName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5912 } else if (tt == TokenKind::String) {
5913 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5914 } else {
5915 error(JSMSG_NO_EXPORT_NAME);
5916 return errorResult();
5917 }
5918 } else {
5919 if (tt != TokenKind::String) {
5920 MOZ_TRY_VAR(exportName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (exportName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5921 } else {
5922 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5923 }
5924 }
5925
5926 if (!checkExportedNameForClause(exportName)) {
5927 return errorResult();
5928 }
5929
5930 BinaryNodeType exportSpec;
5931 MOZ_TRY_VAR(exportSpec, handler_.newExportSpec(bindingName, exportName))do { auto mozTryVarTempResult_ = (handler_.newExportSpec(bindingName
, exportName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exportSpec) = mozTryVarTempResult_.unwrap(); } while (0)
;
5932
5933 handler_.addList(kid, exportSpec);
5934
5935 TokenKind next;
5936 if (!tokenStream.getToken(&next)) {
5937 return errorResult();
5938 }
5939
5940 if (next == TokenKind::RightCurly) {
5941 break;
5942 }
5943
5944 if (next != TokenKind::Comma) {
5945 error(JSMSG_RC_AFTER_EXPORT_SPEC_LIST);
5946 return errorResult();
5947 }
5948 }
5949
5950 // Careful! If |from| follows, even on a new line, it must start a
5951 // FromClause:
5952 //
5953 // export { x }
5954 // from "foo"; // a single ExportDeclaration
5955 //
5956 // But if it doesn't, we might have an ASI opportunity in SlashIsRegExp
5957 // context:
5958 //
5959 // export { x } // ExportDeclaration, terminated by ASI
5960 // fro\u006D // ExpressionStatement, the name "from"
5961 //
5962 // In that case let matchOrInsertSemicolon sort out ASI or any necessary
5963 // error.
5964 bool matched;
5965 if (!tokenStream.matchToken(&matched, TokenKind::From,
5966 TokenStream::SlashIsRegExp)) {
5967 return errorResult();
5968 }
5969
5970 if (matched) {
5971 return exportFrom(begin, kid);
5972 }
5973
5974 if (!matchOrInsertSemicolon()) {
5975 return errorResult();
5976 }
5977
5978 if (!checkLocalExportNames(kid)) {
5979 return errorResult();
5980 }
5981
5982 UnaryNodeType node;
5983 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
5984 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
5985
5986 if (!processExport(node)) {
5987 return errorResult();
5988 }
5989
5990 return node;
5991}
5992
5993template <class ParseHandler, typename Unit>
5994typename ParseHandler::UnaryNodeResult
5995GeneralParser<ParseHandler, Unit>::exportVariableStatement(uint32_t begin) {
5996 if (!abortIfSyntaxParser()) {
5997 return errorResult();
5998 }
5999
6000 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Var))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Var))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Var)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Var)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6000); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Var)"
")"); do { *((volatile int*)__null) = 6000; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6001
6002 DeclarationListNodeType kid;
6003 MOZ_TRY_VAR(kid, declarationList(YieldIsName, ParseNodeKind::VarStmt))do { auto mozTryVarTempResult_ = (declarationList(YieldIsName
, ParseNodeKind::VarStmt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
6004 if (!matchOrInsertSemicolon()) {
6005 return errorResult();
6006 }
6007 if (!checkExportedNamesForDeclarationList(kid)) {
6008 return errorResult();
6009 }
6010
6011 UnaryNodeType node;
6012 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6013 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6014
6015 if (!processExport(node)) {
6016 return errorResult();
6017 }
6018
6019 return node;
6020}
6021
6022template <class ParseHandler, typename Unit>
6023typename ParseHandler::UnaryNodeResult
6024GeneralParser<ParseHandler, Unit>::exportFunctionDeclaration(
6025 uint32_t begin, uint32_t toStringStart,
6026 FunctionAsyncKind asyncKind /* = SyncFunction */) {
6027 if (!abortIfSyntaxParser()) {
6028 return errorResult();
6029 }
6030
6031 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6031); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 6031; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6032
6033 Node kid;
6034 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, NameRequired, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
6035 kid, functionStmt(toStringStart, YieldIsName, NameRequired, asyncKind))do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, NameRequired, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6036
6037 if (!checkExportedNameForFunction(handler_.asFunctionNode(kid))) {
6038 return errorResult();
6039 }
6040
6041 UnaryNodeType node;
6042 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6043 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6044
6045 if (!processExport(node)) {
6046 return errorResult();
6047 }
6048
6049 return node;
6050}
6051
6052template <class ParseHandler, typename Unit>
6053typename ParseHandler::UnaryNodeResult
6054GeneralParser<ParseHandler, Unit>::exportClassDeclaration(uint32_t begin) {
6055 if (!abortIfSyntaxParser()) {
6056 return errorResult();
6057 }
6058
6059 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Class))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Class)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6059); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 6059; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6060
6061 ClassNodeType kid;
6062 MOZ_TRY_VAR(kid, classDefinition(YieldIsName, ClassStatement, NameRequired))do { auto mozTryVarTempResult_ = (classDefinition(YieldIsName
, ClassStatement, NameRequired)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
6063
6064 if (!checkExportedNameForClass(kid)) {
6065 return errorResult();
6066 }
6067
6068 UnaryNodeType node;
6069 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6070 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6071
6072 if (!processExport(node)) {
6073 return errorResult();
6074 }
6075
6076 return node;
6077}
6078
6079template <class ParseHandler, typename Unit>
6080typename ParseHandler::UnaryNodeResult
6081GeneralParser<ParseHandler, Unit>::exportLexicalDeclaration(
6082 uint32_t begin, DeclarationKind kind) {
6083 if (!abortIfSyntaxParser()) {
6084 return errorResult();
6085 }
6086
6087 MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Let)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == DeclarationKind::Const || kind == DeclarationKind
::Let))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == DeclarationKind::Const || kind == DeclarationKind::Let"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6087); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Let"
")"); do { *((volatile int*)__null) = 6087; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6088 MOZ_ASSERT_IF(kind == DeclarationKind::Const,do { if (kind == DeclarationKind::Const) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(anyChars
.isCurrentTokenType(TokenKind::Const))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Const)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Const)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6089); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Const)"
")"); do { *((volatile int*)__null) = 6089; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6089 anyChars.isCurrentTokenType(TokenKind::Const))do { if (kind == DeclarationKind::Const) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(anyChars
.isCurrentTokenType(TokenKind::Const))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Const)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Const)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6089); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Const)"
")"); do { *((volatile int*)__null) = 6089; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6090 MOZ_ASSERT_IF(kind == DeclarationKind::Let,do { if (kind == DeclarationKind::Let) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Let))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Let)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Let)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6091); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 6091; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6091 anyChars.isCurrentTokenType(TokenKind::Let))do { if (kind == DeclarationKind::Let) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Let))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Let)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Let)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6091); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 6091; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6092
6093 DeclarationListNodeType kid;
6094 MOZ_TRY_VAR(kid, lexicalDeclaration(YieldIsName, kind))do { auto mozTryVarTempResult_ = (lexicalDeclaration(YieldIsName
, kind)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (kid
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6095 if (!checkExportedNamesForDeclarationList(kid)) {
6096 return errorResult();
6097 }
6098
6099 UnaryNodeType node;
6100 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6101 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6102
6103 if (!processExport(node)) {
6104 return errorResult();
6105 }
6106
6107 return node;
6108}
6109
6110template <class ParseHandler, typename Unit>
6111typename ParseHandler::BinaryNodeResult
6112GeneralParser<ParseHandler, Unit>::exportDefaultFunctionDeclaration(
6113 uint32_t begin, uint32_t toStringStart,
6114 FunctionAsyncKind asyncKind /* = SyncFunction */) {
6115 if (!abortIfSyntaxParser()) {
6116 return errorResult();
6117 }
6118
6119 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6119); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 6119; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6120
6121 Node kid;
6122 MOZ_TRY_VAR(kid, functionStmt(toStringStart, YieldIsName, AllowDefaultName,do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, AllowDefaultName, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
6123 asyncKind))do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, AllowDefaultName, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6124
6125 BinaryNodeType node;
6126 MOZ_TRY_VAR(node, handler_.newExportDefaultDeclaration(do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6127 kid, null(), TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6128
6129 if (!processExport(node)) {
6130 return errorResult();
6131 }
6132
6133 return node;
6134}
6135
6136template <class ParseHandler, typename Unit>
6137typename ParseHandler::BinaryNodeResult
6138GeneralParser<ParseHandler, Unit>::exportDefaultClassDeclaration(
6139 uint32_t begin) {
6140 if (!abortIfSyntaxParser()) {
6141 return errorResult();
6142 }
6143
6144 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Class))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Class)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6144); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 6144; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6145
6146 ClassNodeType kid;
6147 MOZ_TRY_VAR(kid,do { auto mozTryVarTempResult_ = (classDefinition(YieldIsName
, ClassStatement, AllowDefaultName)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
6148 classDefinition(YieldIsName, ClassStatement, AllowDefaultName))do { auto mozTryVarTempResult_ = (classDefinition(YieldIsName
, ClassStatement, AllowDefaultName)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6149
6150 BinaryNodeType node;
6151 MOZ_TRY_VAR(node, handler_.newExportDefaultDeclaration(do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6152 kid, null(), TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6153
6154 if (!processExport(node)) {
6155 return errorResult();
6156 }
6157
6158 return node;
6159}
6160
6161template <class ParseHandler, typename Unit>
6162typename ParseHandler::BinaryNodeResult
6163GeneralParser<ParseHandler, Unit>::exportDefaultAssignExpr(uint32_t begin) {
6164 if (!abortIfSyntaxParser()) {
6165 return errorResult();
6166 }
6167
6168 TaggedParserAtomIndex name = TaggedParserAtomIndex::WellKnown::default_();
6169 NameNodeType nameNode;
6170 MOZ_TRY_VAR(nameNode, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nameNode) = mozTryVarTempResult_.unwrap()
; } while (0)
;
6171 if (!noteDeclaredName(name, DeclarationKind::Const, pos())) {
6172 return errorResult();
6173 }
6174
6175 Node kid;
6176 MOZ_TRY_VAR(kid, assignExpr(InAllowed, YieldIsName, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, YieldIsName
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
6177
6178 if (!matchOrInsertSemicolon()) {
6179 return errorResult();
6180 }
6181
6182 BinaryNodeType node;
6183 MOZ_TRY_VAR(node, handler_.newExportDefaultDeclaration(do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, nameNode, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6184 kid, nameNode, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, nameNode, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6185
6186 if (!processExport(node)) {
6187 return errorResult();
6188 }
6189
6190 return node;
6191}
6192
6193template <class ParseHandler, typename Unit>
6194typename ParseHandler::BinaryNodeResult
6195GeneralParser<ParseHandler, Unit>::exportDefault(uint32_t begin) {
6196 if (!abortIfSyntaxParser()) {
6197 return errorResult();
6198 }
6199
6200 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Default))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Default))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Default)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Default)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6200); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Default)"
")"); do { *((volatile int*)__null) = 6200; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6201
6202 TokenKind tt;
6203 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6204 return errorResult();
6205 }
6206
6207 if (!checkExportedName(TaggedParserAtomIndex::WellKnown::default_())) {
6208 return errorResult();
6209 }
6210
6211 switch (tt) {
6212 case TokenKind::Function:
6213 return exportDefaultFunctionDeclaration(begin, pos().begin);
6214
6215 case TokenKind::Async: {
6216 TokenKind nextSameLine = TokenKind::Eof;
6217 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
6218 return errorResult();
6219 }
6220
6221 if (nextSameLine == TokenKind::Function) {
6222 uint32_t toStringStart = pos().begin;
6223 tokenStream.consumeKnownToken(TokenKind::Function);
6224 return exportDefaultFunctionDeclaration(
6225 begin, toStringStart, FunctionAsyncKind::AsyncFunction);
6226 }
6227
6228 anyChars.ungetToken();
6229 return exportDefaultAssignExpr(begin);
6230 }
6231
6232 case TokenKind::Class:
6233 return exportDefaultClassDeclaration(begin);
6234
6235 default:
6236 anyChars.ungetToken();
6237 return exportDefaultAssignExpr(begin);
6238 }
6239}
6240
6241template <class ParseHandler, typename Unit>
6242typename ParseHandler::NodeResult
6243GeneralParser<ParseHandler, Unit>::exportDeclaration() {
6244 if (!abortIfSyntaxParser()) {
6245 return errorResult();
6246 }
6247
6248 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Export))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Export))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Export)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Export)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6248); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Export)"
")"); do { *((volatile int*)__null) = 6248; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6249
6250 if (!pc_->atModuleLevel()) {
6251 error(JSMSG_EXPORT_DECL_AT_TOP_LEVEL);
6252 return errorResult();
6253 }
6254
6255 uint32_t begin = pos().begin;
6256
6257 TokenKind tt;
6258 if (!tokenStream.getToken(&tt)) {
6259 return errorResult();
6260 }
6261 switch (tt) {
6262 case TokenKind::Mul:
6263 return exportBatch(begin);
6264
6265 case TokenKind::LeftCurly:
6266 return exportClause(begin);
6267
6268 case TokenKind::Var:
6269 return exportVariableStatement(begin);
6270
6271 case TokenKind::Function:
6272 return exportFunctionDeclaration(begin, pos().begin);
6273
6274 case TokenKind::Async: {
6275 TokenKind nextSameLine = TokenKind::Eof;
6276 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
6277 return errorResult();
6278 }
6279
6280 if (nextSameLine == TokenKind::Function) {
6281 uint32_t toStringStart = pos().begin;
6282 tokenStream.consumeKnownToken(TokenKind::Function);
6283 return exportFunctionDeclaration(begin, toStringStart,
6284 FunctionAsyncKind::AsyncFunction);
6285 }
6286
6287 error(JSMSG_DECLARATION_AFTER_EXPORT);
6288 return errorResult();
6289 }
6290
6291 case TokenKind::Class:
6292 return exportClassDeclaration(begin);
6293
6294 case TokenKind::Const:
6295 return exportLexicalDeclaration(begin, DeclarationKind::Const);
6296
6297 case TokenKind::Let:
6298 return exportLexicalDeclaration(begin, DeclarationKind::Let);
6299
6300 case TokenKind::Default:
6301 return exportDefault(begin);
6302
6303 default:
6304 error(JSMSG_DECLARATION_AFTER_EXPORT);
6305 return errorResult();
6306 }
6307}
6308
6309template <class ParseHandler, typename Unit>
6310typename ParseHandler::UnaryNodeResult
6311GeneralParser<ParseHandler, Unit>::expressionStatement(
6312 YieldHandling yieldHandling, InvokedPrediction invoked) {
6313 anyChars.ungetToken();
6314 Node pnexpr;
6315 MOZ_TRY_VAR(pnexpr, expr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited, nullptr, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pnexpr) = mozTryVarTempResult_.unwrap(); }
while (0)
6316 /* possibleError = */ nullptr, invoked))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited, nullptr, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pnexpr) = mozTryVarTempResult_.unwrap(); }
while (0)
;
6317 if (!matchOrInsertSemicolon()) {
6318 return errorResult();
6319 }
6320 return handler_.newExprStatement(pnexpr, pos().end);
6321}
6322
6323template <class ParseHandler, typename Unit>
6324typename ParseHandler::NodeResult
6325GeneralParser<ParseHandler, Unit>::consequentOrAlternative(
6326 YieldHandling yieldHandling) {
6327 TokenKind next;
6328 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
6329 return errorResult();
6330 }
6331
6332 // Annex B.3.4 says that unbraced FunctionDeclarations under if/else in
6333 // non-strict code act as if they were braced: |if (x) function f() {}|
6334 // parses as |if (x) { function f() {} }|.
6335 //
6336 // Careful! FunctionDeclaration doesn't include generators or async
6337 // functions.
6338 if (next == TokenKind::Function) {
6339 tokenStream.consumeKnownToken(next, TokenStream::SlashIsRegExp);
6340
6341 // Parser::statement would handle this, but as this function handles
6342 // every other error case, it seems best to handle this.
6343 if (pc_->sc()->strict()) {
6344 error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
6345 return errorResult();
6346 }
6347
6348 TokenKind maybeStar;
6349 if (!tokenStream.peekToken(&maybeStar)) {
6350 return errorResult();
6351 }
6352
6353 if (maybeStar == TokenKind::Mul) {
6354 error(JSMSG_FORBIDDEN_AS_STATEMENT, "generator declarations");
6355 return errorResult();
6356 }
6357
6358 ParseContext::Statement stmt(pc_, StatementKind::Block);
6359 ParseContext::Scope scope(this);
6360 if (!scope.init(pc_)) {
6361 return errorResult();
6362 }
6363
6364 TokenPos funcPos = pos();
6365 Node fun;
6366 MOZ_TRY_VAR(fun, functionStmt(pos().begin, yieldHandling, NameRequired))do { auto mozTryVarTempResult_ = (functionStmt(pos().begin, yieldHandling
, NameRequired)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fun) = mozTryVarTempResult_.unwrap(); } while (0)
;
6367
6368 ListNodeType block;
6369 MOZ_TRY_VAR(block, handler_.newStatementList(funcPos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(funcPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (block) =
mozTryVarTempResult_.unwrap(); } while (0)
;
6370
6371 handler_.addStatementToList(block, fun);
6372 return finishLexicalScope(scope, block);
6373 }
6374
6375 return statement(yieldHandling);
6376}
6377
6378template <class ParseHandler, typename Unit>
6379typename ParseHandler::TernaryNodeResult
6380GeneralParser<ParseHandler, Unit>::ifStatement(YieldHandling yieldHandling) {
6381 Vector<Node, 4> condList(fc_), thenList(fc_);
6382 Vector<uint32_t, 4> posList(fc_);
6383 Node elseBranch;
6384
6385 ParseContext::Statement stmt(pc_, StatementKind::If);
6386
6387 while (true) {
6388 uint32_t begin = pos().begin;
6389
6390 /* An IF node has three kids: condition, then, and optional else. */
6391 Node cond;
6392 MOZ_TRY_VAR(cond, condition(InAllowed, yieldHandling))do { auto mozTryVarTempResult_ = (condition(InAllowed, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (cond) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6393
6394 TokenKind tt;
6395 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6396 return errorResult();
6397 }
6398
6399 Node thenBranch;
6400 MOZ_TRY_VAR(thenBranch, consequentOrAlternative(yieldHandling))do { auto mozTryVarTempResult_ = (consequentOrAlternative(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (thenBranch
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6401
6402 if (!condList.append(cond) || !thenList.append(thenBranch) ||
6403 !posList.append(begin)) {
6404 return errorResult();
6405 }
6406
6407 bool matched;
6408 if (!tokenStream.matchToken(&matched, TokenKind::Else,
6409 TokenStream::SlashIsRegExp)) {
6410 return errorResult();
6411 }
6412 if (matched) {
6413 if (!tokenStream.matchToken(&matched, TokenKind::If,
6414 TokenStream::SlashIsRegExp)) {
6415 return errorResult();
6416 }
6417 if (matched) {
6418 continue;
6419 }
6420 MOZ_TRY_VAR(elseBranch, consequentOrAlternative(yieldHandling))do { auto mozTryVarTempResult_ = (consequentOrAlternative(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (elseBranch
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6421 } else {
6422 elseBranch = null();
6423 }
6424 break;
6425 }
6426
6427 TernaryNodeType ifNode;
6428 for (int i = condList.length() - 1; i >= 0; i--) {
6429 MOZ_TRY_VAR(ifNode, handler_.newIfStatement(posList[i], condList[i],do { auto mozTryVarTempResult_ = (handler_.newIfStatement(posList
[i], condList[i], thenList[i], elseBranch)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ifNode) = mozTryVarTempResult_.unwrap(); }
while (0)
6430 thenList[i], elseBranch))do { auto mozTryVarTempResult_ = (handler_.newIfStatement(posList
[i], condList[i], thenList[i], elseBranch)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ifNode) = mozTryVarTempResult_.unwrap(); }
while (0)
;
6431 elseBranch = ifNode;
6432 }
6433
6434 return ifNode;
6435}
6436
6437template <class ParseHandler, typename Unit>
6438typename ParseHandler::BinaryNodeResult
6439GeneralParser<ParseHandler, Unit>::doWhileStatement(
6440 YieldHandling yieldHandling) {
6441 uint32_t begin = pos().begin;
6442 ParseContext::Statement stmt(pc_, StatementKind::DoLoop);
6443 Node body;
6444 MOZ_TRY_VAR(body, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6445 if (!mustMatchToken(TokenKind::While, JSMSG_WHILE_AFTER_DO)) {
6446 return errorResult();
6447 }
6448 Node cond;
6449 MOZ_TRY_VAR(cond, condition(InAllowed, yieldHandling))do { auto mozTryVarTempResult_ = (condition(InAllowed, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (cond) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6450
6451 // The semicolon after do-while is even more optional than most
6452 // semicolons in JS. Web compat required this by 2004:
6453 // http://bugzilla.mozilla.org/show_bug.cgi?id=238945
6454 // ES3 and ES5 disagreed, but ES6 conforms to Web reality:
6455 // https://bugs.ecmascript.org/show_bug.cgi?id=157
6456 // To parse |do {} while (true) false| correctly, use SlashIsRegExp.
6457 bool ignored;
6458 if (!tokenStream.matchToken(&ignored, TokenKind::Semi,
6459 TokenStream::SlashIsRegExp)) {
6460 return errorResult();
6461 }
6462 return handler_.newDoWhileStatement(body, cond, TokenPos(begin, pos().end));
6463}
6464
6465template <class ParseHandler, typename Unit>
6466typename ParseHandler::BinaryNodeResult
6467GeneralParser<ParseHandler, Unit>::whileStatement(YieldHandling yieldHandling) {
6468 uint32_t begin = pos().begin;
6469 ParseContext::Statement stmt(pc_, StatementKind::WhileLoop);
6470 Node cond;
6471 MOZ_TRY_VAR(cond, condition(InAllowed, yieldHandling))do { auto mozTryVarTempResult_ = (condition(InAllowed, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (cond) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6472 Node body;
6473 MOZ_TRY_VAR(body, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6474 return handler_.newWhileStatement(begin, cond, body);
6475}
6476
6477template <class ParseHandler, typename Unit>
6478bool GeneralParser<ParseHandler, Unit>::matchInOrOf(bool* isForInp,
6479 bool* isForOfp) {
6480 TokenKind tt;
6481 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6482 return false;
6483 }
6484
6485 *isForInp = tt == TokenKind::In;
6486 *isForOfp = tt == TokenKind::Of;
6487 if (!*isForInp && !*isForOfp) {
6488 anyChars.ungetToken();
6489 }
6490
6491 MOZ_ASSERT_IF(*isForInp || *isForOfp, *isForInp != *isForOfp)do { if (*isForInp || *isForOfp) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(*isForInp != *isForOfp
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(*isForInp != *isForOfp))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("*isForInp != *isForOfp", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*isForInp != *isForOfp"
")"); do { *((volatile int*)__null) = 6491; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6492 return true;
6493}
6494
6495template <class ParseHandler, typename Unit>
6496bool GeneralParser<ParseHandler, Unit>::forHeadStart(
6497 YieldHandling yieldHandling, IteratorKind iterKind,
6498 ParseNodeKind* forHeadKind, Node* forInitialPart,
6499 Maybe<ParseContext::Scope>& forLoopLexicalScope,
6500 Node* forInOrOfExpression) {
6501 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftParen))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftParen))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftParen))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftParen)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6501); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftParen)"
")"); do { *((volatile int*)__null) = 6501; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6502
6503 TokenKind tt;
6504 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6505 return false;
6506 }
6507
6508 // Super-duper easy case: |for (;| is a C-style for-loop with no init
6509 // component.
6510 if (tt == TokenKind::Semi) {
6511 *forInitialPart = null();
6512 *forHeadKind = ParseNodeKind::ForHead;
6513 return true;
6514 }
6515
6516 // Parsing after |for (var| is also relatively simple (from this method's
6517 // point of view). No block-related work complicates matters, so delegate
6518 // to Parser::declaration.
6519 if (tt == TokenKind::Var) {
6520 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6521
6522 // Pass null for block object because |var| declarations don't use one.
6523 MOZ_TRY_VAR_OR_RETURN(*forInitialPart,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
6524 declarationList(yieldHandling, ParseNodeKind::VarStmt,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
6525 forHeadKind, forInOrOfExpression),do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
6526 false)do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
;
6527 return true;
6528 }
6529
6530 // Otherwise we have a lexical declaration or an expression.
6531
6532 // For-in loop backwards compatibility requires that |let| starting a
6533 // for-loop that's not a (new to ES6) for-of loop, in non-strict mode code,
6534 // parse as an identifier. (|let| in for-of is always a declaration.)
6535 //
6536 // For-of loops can't start with the token sequence "async of", because that
6537 // leads to a shift-reduce conflict when parsing |for (async of => {};;)| or
6538 // |for (async of [])|.
6539 bool parsingLexicalDeclaration = false;
6540 bool letIsIdentifier = false;
6541 bool startsWithForOf = false;
6542
6543 if (tt == TokenKind::Const) {
6544 parsingLexicalDeclaration = true;
6545 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6546 }
6547#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
6548 else if (tt == TokenKind::Await) {
6549 if (!pc_->isAsync()) {
6550 if (pc_->atModuleTopLevel()) {
6551 if (!options().topLevelAwait) {
6552 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
6553 return false;
6554 }
6555 pc_->sc()->asModuleContext()->setIsAsync();
6556 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6556); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 6556; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6557 }
6558 }
6559 if (pc_->isAsync()) {
6560 // Try finding evidence of a AwaitUsingDeclaration the syntax for which
6561 // would be:
6562 // await [no LineTerminator here] using [no LineTerminator here]
6563 // identifier
6564 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6565
6566 TokenKind nextTok = TokenKind::Eof;
6567 if (!tokenStream.peekTokenSameLine(&nextTok,
6568 TokenStream::SlashIsRegExp)) {
6569 return false;
6570 }
6571
6572 if (nextTok == TokenKind::Using) {
6573 tokenStream.consumeKnownToken(nextTok, TokenStream::SlashIsRegExp);
6574
6575 TokenKind nextTokIdent = TokenKind::Eof;
6576 if (!tokenStream.peekTokenSameLine(&nextTokIdent)) {
6577 return false;
6578 }
6579
6580 if (TokenKindIsPossibleIdentifier(nextTokIdent)) {
6581 parsingLexicalDeclaration = true;
6582 } else {
6583 anyChars.ungetToken(); // put back using token
6584 anyChars.ungetToken(); // put back await token
6585 }
6586 } else {
6587 anyChars.ungetToken(); // put back await token
6588 }
6589 }
6590 } else if (tt == TokenKind::Using) {
6591 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6592
6593 // Look ahead to find either a 'of' token or if not identifier
6594 TokenKind nextTok = TokenKind::Eof;
6595 if (!tokenStream.peekTokenSameLine(&nextTok)) {
6596 return false;
6597 }
6598
6599 if (nextTok == TokenKind::Of || !TokenKindIsPossibleIdentifier(nextTok)) {
6600 anyChars.ungetToken(); // we didnt find a valid case of using decl put
6601 // back the token
6602 } else {
6603 parsingLexicalDeclaration = true;
6604 }
6605 }
6606#endif
6607 else if (tt == TokenKind::Let) {
6608 // We could have a {For,Lexical}Declaration, or we could have a
6609 // LeftHandSideExpression with lookahead restrictions so it's not
6610 // ambiguous with the former. Check for a continuation of the former
6611 // to decide which we have.
6612 tokenStream.consumeKnownToken(TokenKind::Let, TokenStream::SlashIsRegExp);
6613
6614 TokenKind next;
6615 if (!tokenStream.peekToken(&next)) {
6616 return false;
6617 }
6618
6619 parsingLexicalDeclaration = nextTokenContinuesLetDeclaration(next);
6620 if (!parsingLexicalDeclaration) {
6621 // If we end up here, we may have `for (let <reserved word> of/in ...`,
6622 // which is not valid.
6623 if (next != TokenKind::In && next != TokenKind::Of &&
6624 TokenKindIsReservedWord(next)) {
6625 tokenStream.consumeKnownToken(next);
6626 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
6627 return false;
6628 }
6629
6630 anyChars.ungetToken();
6631 letIsIdentifier = true;
6632 }
6633 } else if (tt == TokenKind::Async && iterKind == IteratorKind::Sync) {
6634 tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::SlashIsRegExp);
6635
6636 TokenKind next;
6637 if (!tokenStream.peekToken(&next)) {
6638 return false;
6639 }
6640
6641 if (next == TokenKind::Of) {
6642 startsWithForOf = true;
6643 }
6644 anyChars.ungetToken();
6645 }
6646
6647 if (parsingLexicalDeclaration) {
6648 if (options().selfHostingMode) {
6649 error(JSMSG_SELFHOSTED_LEXICAL);
6650 return false;
6651 }
6652
6653 forLoopLexicalScope.emplace(this);
6654 if (!forLoopLexicalScope->init(pc_)) {
6655 return false;
6656 }
6657
6658 // Push a temporary ForLoopLexicalHead Statement that allows for
6659 // lexical declarations, as they are usually allowed only in braced
6660 // statements.
6661 ParseContext::Statement forHeadStmt(pc_, StatementKind::ForLoopLexicalHead);
6662
6663 ParseNodeKind declKind;
6664 switch (tt) {
6665 case TokenKind::Const:
6666 declKind = ParseNodeKind::ConstDecl;
6667 break;
6668#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
6669 case TokenKind::Using:
6670 declKind = ParseNodeKind::UsingDecl;
6671 break;
6672 case TokenKind::Await:
6673 declKind = ParseNodeKind::AwaitUsingDecl;
6674 break;
6675#endif
6676 case TokenKind::Let:
6677 declKind = ParseNodeKind::LetDecl;
6678 break;
6679 default:
6680 MOZ_CRASH("unexpected node kind")do { do { } while (false); MOZ_ReportCrash("" "unexpected node kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6680); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected node kind"
")"); do { *((volatile int*)__null) = 6680; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6681 }
6682
6683 MOZ_TRY_VAR_OR_RETURN(*forInitialPart,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6684 declarationList(yieldHandling, declKind, forHeadKind,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6685 forInOrOfExpression),do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6686 false)do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
;
6687 return true;
6688 }
6689
6690 uint32_t exprOffset;
6691 if (!tokenStream.peekOffset(&exprOffset, TokenStream::SlashIsRegExp)) {
6692 return false;
6693 }
6694
6695 // Finally, handle for-loops that start with expressions. Pass
6696 // |InProhibited| so that |in| isn't parsed in a RelationalExpression as a
6697 // binary operator. |in| makes it a for-in loop, *not* an |in| expression.
6698 PossibleError possibleError(*this);
6699 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6700 *forInitialPart,do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6701 expr(InProhibited, yieldHandling, TripledotProhibited, &possibleError),do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6702 false)do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
;
6703
6704 bool isForIn, isForOf;
6705 if (!matchInOrOf(&isForIn, &isForOf)) {
6706 return false;
6707 }
6708
6709 // If we don't encounter 'in'/'of', we have a for(;;) loop. We've handled
6710 // the init expression; the caller handles the rest.
6711 if (!isForIn && !isForOf) {
6712 if (!possibleError.checkForExpressionError()) {
6713 return false;
6714 }
6715
6716 *forHeadKind = ParseNodeKind::ForHead;
6717 return true;
6718 }
6719
6720 MOZ_ASSERT(isForIn != isForOf)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isForIn != isForOf)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isForIn != isForOf))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("isForIn != isForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6720); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isForIn != isForOf"
")"); do { *((volatile int*)__null) = 6720; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6721
6722 // In a for-of loop, 'let' that starts the loop head is a |let| keyword,
6723 // per the [lookahead ≠ let] restriction on the LeftHandSideExpression
6724 // variant of such loops. Expressions that start with |let| can't be used
6725 // here.
6726 //
6727 // var let = {};
6728 // for (let.prop of [1]) // BAD
6729 // break;
6730 //
6731 // See ES6 13.7.
6732 if (isForOf && letIsIdentifier) {
6733 errorAt(exprOffset, JSMSG_BAD_STARTING_FOROF_LHS, "let");
6734 return false;
6735 }
6736
6737 // In a for-of loop, the LeftHandSideExpression isn't allowed to be an
6738 // identifier named "async" per the [lookahead ≠ async of] restriction.
6739 if (isForOf && startsWithForOf) {
6740 errorAt(exprOffset, JSMSG_BAD_STARTING_FOROF_LHS, "async of");
6741 return false;
6742 }
6743
6744 *forHeadKind = isForIn ? ParseNodeKind::ForIn : ParseNodeKind::ForOf;
6745
6746 // Verify the left-hand side expression doesn't have a forbidden form.
6747 if (handler_.isUnparenthesizedDestructuringPattern(*forInitialPart)) {
6748 if (!possibleError.checkForDestructuringErrorOrWarning()) {
6749 return false;
6750 }
6751 } else if (handler_.isName(*forInitialPart)) {
6752 if (const char* chars = nameIsArgumentsOrEval(*forInitialPart)) {
6753 // |chars| is "arguments" or "eval" here.
6754 if (!strictModeErrorAt(exprOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) {
6755 return false;
6756 }
6757 }
6758 } else if (handler_.isArgumentsLength(*forInitialPart)) {
6759 pc_->sc()->setIneligibleForArgumentsLength();
6760 } else if (handler_.isPropertyOrPrivateMemberAccess(*forInitialPart)) {
6761 // Permitted: no additional testing/fixup needed.
6762 } else if (handler_.isFunctionCall(*forInitialPart)) {
6763 if (!strictModeErrorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE)) {
6764 return false;
6765 }
6766 } else {
6767 errorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE);
6768 return false;
6769 }
6770
6771 if (!possibleError.checkForExpressionError()) {
6772 return false;
6773 }
6774
6775 // Finally, parse the iterated expression, making the for-loop's closing
6776 // ')' the next token.
6777 MOZ_TRY_VAR_OR_RETURN(*forInOrOfExpression,do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
6778 expressionAfterForInOrOf(*forHeadKind, yieldHandling),do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
6779 false)do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
;
6780 return true;
6781}
6782
6783template <class ParseHandler, typename Unit>
6784typename ParseHandler::NodeResult
6785GeneralParser<ParseHandler, Unit>::forStatement(YieldHandling yieldHandling) {
6786 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::For))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::For))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::For)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::For)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6786); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::For)"
")"); do { *((volatile int*)__null) = 6786; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6787
6788 uint32_t begin = pos().begin;
6789
6790 ParseContext::Statement stmt(pc_, StatementKind::ForLoop);
6791
6792 IteratorKind iterKind = IteratorKind::Sync;
6793 unsigned iflags = 0;
6794
6795 if (pc_->isAsync() || pc_->sc()->isModuleContext()) {
6796 bool matched;
6797 if (!tokenStream.matchToken(&matched, TokenKind::Await)) {
6798 return errorResult();
6799 }
6800
6801 // If we come across a top level await here, mark the module as async.
6802 if (matched && pc_->sc()->isModuleContext() && !pc_->isAsync()) {
6803 if (!options().topLevelAwait) {
6804 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
6805 return errorResult();
6806 }
6807 pc_->sc()->asModuleContext()->setIsAsync();
6808 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6808); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 6808; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6809 }
6810
6811 if (matched) {
6812 iflags |= JSITER_FORAWAITOF0x80;
6813 iterKind = IteratorKind::Async;
6814 }
6815 }
6816
6817 if (!mustMatchToken(TokenKind::LeftParen, [this](TokenKind actual) {
6818 this->error((actual == TokenKind::Await && !this->pc_->isAsync())
6819 ? JSMSG_FOR_AWAIT_OUTSIDE_ASYNC
6820 : JSMSG_PAREN_AFTER_FOR);
6821 })) {
6822 return errorResult();
6823 }
6824
6825 // ParseNodeKind::ForHead, ParseNodeKind::ForIn, or
6826 // ParseNodeKind::ForOf depending on the loop type.
6827 ParseNodeKind headKind;
6828
6829 // |x| in either |for (x; ...; ...)| or |for (x in/of ...)|.
6830 Node startNode;
6831
6832 // The next two variables are used to implement `for (let/const ...)`.
6833 //
6834 // We generate an implicit block, wrapping the whole loop, to store loop
6835 // variables declared this way. Note that if the loop uses `for (var...)`
6836 // instead, those variables go on some existing enclosing scope, so no
6837 // implicit block scope is created.
6838 //
6839 // Both variables remain null/none if the loop is any other form.
6840
6841 // The static block scope for the implicit block scope.
6842 Maybe<ParseContext::Scope> forLoopLexicalScope;
6843
6844 // The expression being iterated over, for for-in/of loops only. Unused
6845 // for for(;;) loops.
6846 Node iteratedExpr;
6847
6848 // Parse the entirety of the loop-head for a for-in/of loop (so the next
6849 // token is the closing ')'):
6850 //
6851 // for (... in/of ...) ...
6852 // ^next token
6853 //
6854 // ...OR, parse up to the first ';' in a C-style for-loop:
6855 //
6856 // for (...; ...; ...) ...
6857 // ^next token
6858 //
6859 // In either case the subsequent token can be consistently accessed using
6860 // TokenStream::SlashIsDiv semantics.
6861 if (!forHeadStart(yieldHandling, iterKind, &headKind, &startNode,
6862 forLoopLexicalScope, &iteratedExpr)) {
6863 return errorResult();
6864 }
6865
6866 MOZ_ASSERT(headKind == ParseNodeKind::ForIn ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf || headKind == ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(headKind == ParseNodeKind::ForIn
|| headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6867 headKind == ParseNodeKind::ForOf ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf || headKind == ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(headKind == ParseNodeKind::ForIn
|| headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6868 headKind == ParseNodeKind::ForHead)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf || headKind == ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(headKind == ParseNodeKind::ForIn
|| headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6869
6870 if (iterKind == IteratorKind::Async && headKind != ParseNodeKind::ForOf) {
6871 errorAt(begin, JSMSG_FOR_AWAIT_NOT_OF);
6872 return errorResult();
6873 }
6874
6875 TernaryNodeType forHead;
6876 if (headKind == ParseNodeKind::ForHead) {
6877 Node init = startNode;
6878
6879 // Look for an operand: |for (;| means we might have already examined
6880 // this semicolon with that modifier.
6881 if (!mustMatchToken(TokenKind::Semi, JSMSG_SEMI_AFTER_FOR_INIT)) {
6882 return errorResult();
6883 }
6884
6885 TokenKind tt;
6886 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6887 return errorResult();
6888 }
6889
6890 Node test;
6891 if (tt == TokenKind::Semi) {
6892 test = null();
6893 } else {
6894 MOZ_TRY_VAR(test, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (test) = mozTryVarTempResult_.unwrap(); } while (0)
;
6895 }
6896
6897 if (!mustMatchToken(TokenKind::Semi, JSMSG_SEMI_AFTER_FOR_COND)) {
6898 return errorResult();
6899 }
6900
6901 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6902 return errorResult();
6903 }
6904
6905 Node update;
6906 if (tt == TokenKind::RightParen) {
6907 update = null();
6908 } else {
6909 MOZ_TRY_VAR(update, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (update) = mozTryVarTempResult_.unwrap(); } while (0)
;
6910 }
6911
6912 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_FOR_CTRL)) {
6913 return errorResult();
6914 }
6915
6916 TokenPos headPos(begin, pos().end);
6917 MOZ_TRY_VAR(forHead, handler_.newForHead(init, test, update, headPos))do { auto mozTryVarTempResult_ = (handler_.newForHead(init, test
, update, headPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forHead) = mozTryVarTempResult_.unwrap(); } while (0)
;
6918 } else {
6919 MOZ_ASSERT(headKind == ParseNodeKind::ForIn ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6920); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 6920; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6920 headKind == ParseNodeKind::ForOf)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6920); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 6920; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6921
6922 // |target| is the LeftHandSideExpression or declaration to which the
6923 // per-iteration value (an arbitrary value exposed by the iteration
6924 // protocol, or a string naming a property) is assigned.
6925 Node target = startNode;
6926
6927 // Parse the rest of the for-in/of head.
6928 if (headKind == ParseNodeKind::ForIn) {
6929 stmt.refineForKind(StatementKind::ForInLoop);
6930 } else {
6931 stmt.refineForKind(StatementKind::ForOfLoop);
6932 }
6933
6934 // Parser::declaration consumed everything up to the closing ')'. That
6935 // token follows an {Assignment,}Expression and so must be interpreted
6936 // as an operand to be consistent with normal expression tokenizing.
6937 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_FOR_CTRL)) {
6938 return errorResult();
6939 }
6940
6941 TokenPos headPos(begin, pos().end);
6942 MOZ_TRY_VAR(forHead, handler_.newForInOrOfHead(headKind, target,do { auto mozTryVarTempResult_ = (handler_.newForInOrOfHead(headKind
, target, iteratedExpr, headPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forHead) = mozTryVarTempResult_.unwrap(); } while (0)
6943 iteratedExpr, headPos))do { auto mozTryVarTempResult_ = (handler_.newForInOrOfHead(headKind
, target, iteratedExpr, headPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forHead) = mozTryVarTempResult_.unwrap(); } while (0)
;
6944 }
6945
6946 Node body;
6947 MOZ_TRY_VAR(body, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6948
6949 ForNodeType forLoop;
6950 MOZ_TRY_VAR(forLoop, handler_.newForStatement(begin, forHead, body, iflags))do { auto mozTryVarTempResult_ = (handler_.newForStatement(begin
, forHead, body, iflags)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forLoop) = mozTryVarTempResult_.unwrap(); } while (0)
;
6951
6952 if (forLoopLexicalScope) {
6953 return finishLexicalScope(*forLoopLexicalScope, forLoop);
6954 }
6955
6956 return forLoop;
6957}
6958
6959template <class ParseHandler, typename Unit>
6960typename ParseHandler::SwitchStatementResult
6961GeneralParser<ParseHandler, Unit>::switchStatement(
6962 YieldHandling yieldHandling) {
6963 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Switch))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Switch))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Switch)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Switch)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Switch)"
")"); do { *((volatile int*)__null) = 6963; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6964 uint32_t begin = pos().begin;
6965
6966 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_SWITCH)) {
6967 return errorResult();
6968 }
6969
6970 Node discriminant;
6971 MOZ_TRY_VAR(discriminant,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (discriminant) = mozTryVarTempResult_.unwrap(); } while (0
)
6972 exprInParens(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (discriminant) = mozTryVarTempResult_.unwrap(); } while (0
)
;
6973
6974 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_SWITCH)) {
6975 return errorResult();
6976 }
6977 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_SWITCH)) {
6978 return errorResult();
6979 }
6980
6981 ParseContext::Statement stmt(pc_, StatementKind::Switch);
6982 ParseContext::Scope scope(this);
6983 if (!scope.init(pc_)) {
6984 return errorResult();
6985 }
6986
6987 ListNodeType caseList;
6988 MOZ_TRY_VAR(caseList, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (caseList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6989
6990 bool seenDefault = false;
6991 TokenKind tt;
6992 while (true) {
6993 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6994 return errorResult();
6995 }
6996 if (tt == TokenKind::RightCurly) {
6997 break;
6998 }
6999 uint32_t caseBegin = pos().begin;
7000
7001 Node caseExpr;
7002 switch (tt) {
7003 case TokenKind::Default:
7004 if (seenDefault) {
7005 error(JSMSG_TOO_MANY_DEFAULTS);
7006 return errorResult();
7007 }
7008 seenDefault = true;
7009 caseExpr = null(); // The default case has pn_left == nullptr.
7010 break;
7011
7012 case TokenKind::Case:
7013 MOZ_TRY_VAR(caseExpr,do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
7014 expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
7015 break;
7016
7017 default:
7018 error(JSMSG_BAD_SWITCH);
7019 return errorResult();
7020 }
7021
7022 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_CASE)) {
7023 return errorResult();
7024 }
7025
7026 ListNodeType body;
7027 MOZ_TRY_VAR(body, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (body) =
mozTryVarTempResult_.unwrap(); } while (0)
;
7028
7029 bool afterReturn = false;
7030 bool warnedAboutStatementsAfterReturn = false;
7031 uint32_t statementBegin = 0;
7032 while (true) {
7033 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
7034 return errorResult();
7035 }
7036 if (tt == TokenKind::RightCurly || tt == TokenKind::Case ||
7037 tt == TokenKind::Default) {
7038 break;
7039 }
7040 if (afterReturn) {
7041 if (!tokenStream.peekOffset(&statementBegin,
7042 TokenStream::SlashIsRegExp)) {
7043 return errorResult();
7044 }
7045 }
7046 Node stmt;
7047 MOZ_TRY_VAR(stmt, statementListItem(yieldHandling))do { auto mozTryVarTempResult_ = (statementListItem(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (stmt) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7048 if (!warnedAboutStatementsAfterReturn) {
7049 if (afterReturn) {
7050 if (!handler_.isStatementPermittedAfterReturnStatement(stmt)) {
7051 if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
7052 return errorResult();
7053 }
7054
7055 warnedAboutStatementsAfterReturn = true;
7056 }
7057 } else if (handler_.isReturnStatement(stmt)) {
7058 afterReturn = true;
7059 }
7060 }
7061 handler_.addStatementToList(body, stmt);
7062 }
7063
7064 CaseClauseType caseClause;
7065 MOZ_TRY_VAR(caseClause,do { auto mozTryVarTempResult_ = (handler_.newCaseOrDefault(caseBegin
, caseExpr, body)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseClause) = mozTryVarTempResult_.unwrap(); } while (0)
7066 handler_.newCaseOrDefault(caseBegin, caseExpr, body))do { auto mozTryVarTempResult_ = (handler_.newCaseOrDefault(caseBegin
, caseExpr, body)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseClause) = mozTryVarTempResult_.unwrap(); } while (0)
;
7067 handler_.addCaseStatementToList(caseList, caseClause);
7068 }
7069
7070 LexicalScopeNodeType lexicalForCaseList;
7071 MOZ_TRY_VAR(lexicalForCaseList, finishLexicalScope(scope, caseList))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, caseList
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (lexicalForCaseList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7072
7073 handler_.setEndPosition(lexicalForCaseList, pos().end);
7074
7075 return handler_.newSwitchStatement(begin, discriminant, lexicalForCaseList,
7076 seenDefault);
7077}
7078
7079template <class ParseHandler, typename Unit>
7080typename ParseHandler::ContinueStatementResult
7081GeneralParser<ParseHandler, Unit>::continueStatement(
7082 YieldHandling yieldHandling) {
7083 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Continue))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Continue))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Continue)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Continue)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7083); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Continue)"
")"); do { *((volatile int*)__null) = 7083; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7084 uint32_t begin = pos().begin;
7085
7086 TaggedParserAtomIndex label;
7087 if (!matchLabel(yieldHandling, &label)) {
7088 return errorResult();
7089 }
7090
7091 auto validity = pc_->checkContinueStatement(label);
7092 if (validity.isErr()) {
7093 switch (validity.unwrapErr()) {
7094 case ParseContext::ContinueStatementError::NotInALoop:
7095 errorAt(begin, JSMSG_BAD_CONTINUE);
7096 break;
7097 case ParseContext::ContinueStatementError::LabelNotFound:
7098 error(JSMSG_LABEL_NOT_FOUND);
7099 break;
7100 }
7101 return errorResult();
7102 }
7103
7104 if (!matchOrInsertSemicolon()) {
7105 return errorResult();
7106 }
7107
7108 return handler_.newContinueStatement(label, TokenPos(begin, pos().end));
7109}
7110
7111template <class ParseHandler, typename Unit>
7112typename ParseHandler::BreakStatementResult
7113GeneralParser<ParseHandler, Unit>::breakStatement(YieldHandling yieldHandling) {
7114 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Break))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Break))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Break)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Break)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7114); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Break)"
")"); do { *((volatile int*)__null) = 7114; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7115 uint32_t begin = pos().begin;
7116
7117 TaggedParserAtomIndex label;
7118 if (!matchLabel(yieldHandling, &label)) {
7119 return errorResult();
7120 }
7121
7122 auto validity = pc_->checkBreakStatement(label);
7123 if (validity.isErr()) {
7124 switch (validity.unwrapErr()) {
7125 case ParseContext::BreakStatementError::ToughBreak:
7126 errorAt(begin, JSMSG_TOUGH_BREAK);
7127 return errorResult();
7128 case ParseContext::BreakStatementError::LabelNotFound:
7129 error(JSMSG_LABEL_NOT_FOUND);
7130 return errorResult();
7131 }
7132 }
7133
7134 if (!matchOrInsertSemicolon()) {
7135 return errorResult();
7136 }
7137
7138 return handler_.newBreakStatement(label, TokenPos(begin, pos().end));
7139}
7140
7141template <class ParseHandler, typename Unit>
7142typename ParseHandler::UnaryNodeResult
7143GeneralParser<ParseHandler, Unit>::returnStatement(
7144 YieldHandling yieldHandling) {
7145 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Return))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Return))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Return)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Return)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7145); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Return)"
")"); do { *((volatile int*)__null) = 7145; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7146 uint32_t begin = pos().begin;
7147
7148 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7148); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 7148; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7149
7150 // Parse an optional operand.
7151 //
7152 // This is ugly, but we don't want to require a semicolon.
7153 Node exprNode;
7154 TokenKind tt = TokenKind::Eof;
7155 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7156 return errorResult();
7157 }
7158 switch (tt) {
7159 case TokenKind::Eol:
7160 case TokenKind::Eof:
7161 case TokenKind::Semi:
7162 case TokenKind::RightCurly:
7163 exprNode = null();
7164 break;
7165 default: {
7166 MOZ_TRY_VAR(exprNode,do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
7167 expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
7168 }
7169 }
7170
7171 if (!matchOrInsertSemicolon()) {
7172 return errorResult();
7173 }
7174
7175 return handler_.newReturnStatement(exprNode, TokenPos(begin, pos().end));
7176}
7177
7178template <class ParseHandler, typename Unit>
7179typename ParseHandler::UnaryNodeResult
7180GeneralParser<ParseHandler, Unit>::yieldExpression(InHandling inHandling) {
7181 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Yield))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Yield))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Yield)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Yield)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7181); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Yield)"
")"); do { *((volatile int*)__null) = 7181; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7182 uint32_t begin = pos().begin;
7183
7184 MOZ_ASSERT(pc_->isGenerator())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isGenerator())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isGenerator()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isGenerator()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7184); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isGenerator()"
")"); do { *((volatile int*)__null) = 7184; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7185 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7185); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 7185; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7186
7187 pc_->lastYieldOffset = begin;
7188
7189 Node exprNode;
7190 ParseNodeKind kind = ParseNodeKind::YieldExpr;
7191 TokenKind tt = TokenKind::Eof;
7192 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7193 return errorResult();
7194 }
7195 switch (tt) {
7196 // TokenKind::Eol is special; it implements the [no LineTerminator here]
7197 // quirk in the grammar.
7198 case TokenKind::Eol:
7199 // The rest of these make up the complete set of tokens that can
7200 // appear after any of the places where AssignmentExpression is used
7201 // throughout the grammar. Conveniently, none of them can also be the
7202 // start an expression.
7203 case TokenKind::Eof:
7204 case TokenKind::Semi:
7205 case TokenKind::RightCurly:
7206 case TokenKind::RightBracket:
7207 case TokenKind::RightParen:
7208 case TokenKind::Colon:
7209 case TokenKind::Comma:
7210 case TokenKind::In: // Annex B.3.6 `for (x = yield in y) ;`
7211 // No value.
7212 exprNode = null();
7213 break;
7214 case TokenKind::Mul:
7215 kind = ParseNodeKind::YieldStarExpr;
7216 tokenStream.consumeKnownToken(TokenKind::Mul, TokenStream::SlashIsRegExp);
7217 [[fallthrough]];
7218 default:
7219 MOZ_TRY_VAR(exprNode,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, YieldIsKeyword
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
7220 assignExpr(inHandling, YieldIsKeyword, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, YieldIsKeyword
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
7221 }
7222 if (kind == ParseNodeKind::YieldStarExpr) {
7223 return handler_.newYieldStarExpression(begin, exprNode);
7224 }
7225 return handler_.newYieldExpression(begin, exprNode);
7226}
7227
7228template <class ParseHandler, typename Unit>
7229typename ParseHandler::BinaryNodeResult
7230GeneralParser<ParseHandler, Unit>::withStatement(YieldHandling yieldHandling) {
7231 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::With))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::With))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::With)))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::With)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7231); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 7231; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7232 uint32_t begin = pos().begin;
7233
7234 if (pc_->sc()->strict()) {
7235 if (!strictModeError(JSMSG_STRICT_CODE_WITH)) {
7236 return errorResult();
7237 }
7238 }
7239
7240 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_WITH)) {
7241 return errorResult();
7242 }
7243
7244 Node objectExpr;
7245 MOZ_TRY_VAR(objectExpr,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (objectExpr) = mozTryVarTempResult_.unwrap(); } while (0)
7246 exprInParens(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (objectExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
7247
7248 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_WITH)) {
7249 return errorResult();
7250 }
7251
7252 Node innerBlock;
7253 {
7254 ParseContext::Statement stmt(pc_, StatementKind::With);
7255 MOZ_TRY_VAR(innerBlock, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (innerBlock) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7256 }
7257
7258 pc_->sc()->setBindingsAccessedDynamically();
7259
7260 return handler_.newWithStatement(begin, objectExpr, innerBlock);
7261}
7262
7263template <class ParseHandler, typename Unit>
7264typename ParseHandler::NodeResult
7265GeneralParser<ParseHandler, Unit>::labeledItem(YieldHandling yieldHandling) {
7266 TokenKind tt;
7267 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
7268 return errorResult();
7269 }
7270
7271 if (tt == TokenKind::Function) {
7272 TokenKind next;
7273 if (!tokenStream.peekToken(&next)) {
7274 return errorResult();
7275 }
7276
7277 // GeneratorDeclaration is only matched by HoistableDeclaration in
7278 // StatementListItem, so generators can't be inside labels.
7279 if (next == TokenKind::Mul) {
7280 error(JSMSG_GENERATOR_LABEL);
7281 return errorResult();
7282 }
7283
7284 // Per 13.13.1 it's a syntax error if LabelledItem: FunctionDeclaration
7285 // is ever matched. Per Annex B.3.2 that modifies this text, this
7286 // applies only to strict mode code.
7287 if (pc_->sc()->strict()) {
7288 error(JSMSG_FUNCTION_LABEL);
7289 return errorResult();
7290 }
7291
7292 return functionStmt(pos().begin, yieldHandling, NameRequired);
7293 }
7294
7295 anyChars.ungetToken();
7296 return statement(yieldHandling);
7297}
7298
7299template <class ParseHandler, typename Unit>
7300typename ParseHandler::LabeledStatementResult
7301GeneralParser<ParseHandler, Unit>::labeledStatement(
7302 YieldHandling yieldHandling) {
7303 TaggedParserAtomIndex label = labelIdentifier(yieldHandling);
7304 if (!label) {
7305 return errorResult();
7306 }
7307
7308 auto hasSameLabel = [&label](ParseContext::LabelStatement* stmt) {
7309 return stmt->label() == label;
7310 };
7311
7312 uint32_t begin = pos().begin;
7313
7314 if (pc_->template findInnermostStatement<ParseContext::LabelStatement>(
7315 hasSameLabel)) {
7316 errorAt(begin, JSMSG_DUPLICATE_LABEL);
7317 return errorResult();
7318 }
7319
7320 tokenStream.consumeKnownToken(TokenKind::Colon);
7321
7322 /* Push a label struct and parse the statement. */
7323 ParseContext::LabelStatement stmt(pc_, label);
7324 Node pn;
7325 MOZ_TRY_VAR(pn, labeledItem(yieldHandling))do { auto mozTryVarTempResult_ = (labeledItem(yieldHandling))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7326
7327 return handler_.newLabeledStatement(label, pn, begin);
7328}
7329
7330template <class ParseHandler, typename Unit>
7331typename ParseHandler::UnaryNodeResult
7332GeneralParser<ParseHandler, Unit>::throwStatement(YieldHandling yieldHandling) {
7333 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Throw))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Throw))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Throw)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Throw)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7333); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Throw)"
")"); do { *((volatile int*)__null) = 7333; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7334 uint32_t begin = pos().begin;
7335
7336 /* ECMA-262 Edition 3 says 'throw [no LineTerminator here] Expr'. */
7337 TokenKind tt = TokenKind::Eof;
7338 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7339 return errorResult();
7340 }
7341 if (tt == TokenKind::Eof || tt == TokenKind::Semi ||
7342 tt == TokenKind::RightCurly) {
7343 error(JSMSG_MISSING_EXPR_AFTER_THROW);
7344 return errorResult();
7345 }
7346 if (tt == TokenKind::Eol) {
7347 error(JSMSG_LINE_BREAK_AFTER_THROW);
7348 return errorResult();
7349 }
7350
7351 Node throwExpr;
7352 MOZ_TRY_VAR(throwExpr, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (throwExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
7353
7354 if (!matchOrInsertSemicolon()) {
7355 return errorResult();
7356 }
7357
7358 return handler_.newThrowStatement(throwExpr, TokenPos(begin, pos().end));
7359}
7360
7361template <class ParseHandler, typename Unit>
7362typename ParseHandler::TernaryNodeResult
7363GeneralParser<ParseHandler, Unit>::tryStatement(YieldHandling yieldHandling) {
7364 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Try))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Try))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Try)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Try)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7364); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Try)"
")"); do { *((volatile int*)__null) = 7364; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7365 uint32_t begin = pos().begin;
7366
7367 /*
7368 * try nodes are ternary.
7369 * kid1 is the try statement
7370 * kid2 is the catch node list or null
7371 * kid3 is the finally statement
7372 *
7373 * catch nodes are binary.
7374 * left is the catch-name/pattern or null
7375 * right is the catch block
7376 *
7377 * catch lvalue nodes are either:
7378 * a single identifier
7379 * TokenKind::RightBracket for a destructuring left-hand side
7380 * TokenKind::RightCurly for a destructuring left-hand side
7381 *
7382 * finally nodes are TokenKind::LeftCurly statement lists.
7383 */
7384
7385 Node innerBlock;
7386 {
7387 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_TRY)) {
7388 return errorResult();
7389 }
7390
7391 uint32_t openedPos = pos().begin;
7392
7393 ParseContext::Statement stmt(pc_, StatementKind::Try);
7394 ParseContext::Scope scope(this);
7395 if (!scope.init(pc_)) {
7396 return errorResult();
7397 }
7398
7399 MOZ_TRY_VAR(innerBlock, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7400
7401 MOZ_TRY_VAR(innerBlock, finishLexicalScope(scope, innerBlock))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, innerBlock
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7402
7403 if (!mustMatchToken(
7404 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7405 this->reportMissingClosing(JSMSG_CURLY_AFTER_TRY,
7406 JSMSG_CURLY_OPENED, openedPos);
7407 })) {
7408 return errorResult();
7409 }
7410 }
7411
7412 LexicalScopeNodeType catchScope = null();
7413 TokenKind tt;
7414 if (!tokenStream.getToken(&tt)) {
7415 return errorResult();
7416 }
7417 if (tt == TokenKind::Catch) {
7418 /*
7419 * Create a lexical scope node around the whole catch clause,
7420 * including the head.
7421 */
7422 ParseContext::Statement stmt(pc_, StatementKind::Catch);
7423 ParseContext::Scope scope(this);
7424 if (!scope.init(pc_)) {
7425 return errorResult();
7426 }
7427
7428 /*
7429 * Legal catch forms are:
7430 * catch (lhs) {
7431 * catch {
7432 * where lhs is a name or a destructuring left-hand side.
7433 */
7434 bool omittedBinding;
7435 if (!tokenStream.matchToken(&omittedBinding, TokenKind::LeftCurly)) {
7436 return errorResult();
7437 }
7438
7439 Node catchName;
7440 if (omittedBinding) {
7441 catchName = null();
7442 } else {
7443 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_CATCH)) {
7444 return errorResult();
7445 }
7446
7447 if (!tokenStream.getToken(&tt)) {
7448 return errorResult();
7449 }
7450 switch (tt) {
7451 case TokenKind::LeftBracket:
7452 case TokenKind::LeftCurly:
7453 MOZ_TRY_VAR(catchName,do { auto mozTryVarTempResult_ = (destructuringDeclaration(DeclarationKind
::CatchParameter, yieldHandling, tt)); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7454 destructuringDeclaration(DeclarationKind::CatchParameter,do { auto mozTryVarTempResult_ = (destructuringDeclaration(DeclarationKind
::CatchParameter, yieldHandling, tt)); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7455 yieldHandling, tt))do { auto mozTryVarTempResult_ = (destructuringDeclaration(DeclarationKind
::CatchParameter, yieldHandling, tt)); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
;
7456 break;
7457
7458 default: {
7459 if (!TokenKindIsPossibleIdentifierName(tt)) {
7460 error(JSMSG_CATCH_IDENTIFIER);
7461 return errorResult();
7462 }
7463
7464 MOZ_TRY_VAR(catchName,do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7465 bindingIdentifier(DeclarationKind::SimpleCatchParameter,do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7466 yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
;
7467 break;
7468 }
7469 }
7470
7471 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_CATCH)) {
7472 return errorResult();
7473 }
7474
7475 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_CATCH)) {
7476 return errorResult();
7477 }
7478 }
7479
7480 LexicalScopeNodeType catchBody;
7481 MOZ_TRY_VAR(catchBody, catchBlockStatement(yieldHandling, scope))do { auto mozTryVarTempResult_ = (catchBlockStatement(yieldHandling
, scope)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (catchBody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7482
7483 MOZ_TRY_VAR(catchScope, finishLexicalScope(scope, catchBody))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, catchBody
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (catchScope
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7484
7485 if (!handler_.setupCatchScope(catchScope, catchName, catchBody)) {
7486 return errorResult();
7487 }
7488 handler_.setEndPosition(catchScope, pos().end);
7489
7490 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
7491 return errorResult();
7492 }
7493 }
7494
7495 Node finallyBlock = null();
7496
7497 if (tt == TokenKind::Finally) {
7498 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_FINALLY)) {
7499 return errorResult();
7500 }
7501
7502 uint32_t openedPos = pos().begin;
7503
7504 ParseContext::Statement stmt(pc_, StatementKind::Finally);
7505 ParseContext::Scope scope(this);
7506 if (!scope.init(pc_)) {
7507 return errorResult();
7508 }
7509
7510 MOZ_TRY_VAR(finallyBlock, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (finallyBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7511
7512 MOZ_TRY_VAR(finallyBlock, finishLexicalScope(scope, finallyBlock))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, finallyBlock
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (finallyBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7513
7514 if (!mustMatchToken(
7515 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7516 this->reportMissingClosing(JSMSG_CURLY_AFTER_FINALLY,
7517 JSMSG_CURLY_OPENED, openedPos);
7518 })) {
7519 return errorResult();
7520 }
7521 } else {
7522 anyChars.ungetToken();
7523 }
7524 if (!catchScope && !finallyBlock) {
7525 error(JSMSG_CATCH_OR_FINALLY);
7526 return errorResult();
7527 }
7528
7529 return handler_.newTryStatement(begin, innerBlock, catchScope, finallyBlock);
7530}
7531
7532template <class ParseHandler, typename Unit>
7533typename ParseHandler::LexicalScopeNodeResult
7534GeneralParser<ParseHandler, Unit>::catchBlockStatement(
7535 YieldHandling yieldHandling, ParseContext::Scope& catchParamScope) {
7536 uint32_t openedPos = pos().begin;
7537
7538 ParseContext::Statement stmt(pc_, StatementKind::Block);
7539
7540 // ES 13.15.7 CatchClauseEvaluation
7541 //
7542 // Step 8 means that the body of a catch block always has an additional
7543 // lexical scope.
7544 ParseContext::Scope scope(this);
7545 if (!scope.init(pc_)) {
7546 return errorResult();
7547 }
7548
7549 // The catch parameter names cannot be redeclared inside the catch
7550 // block, so declare the name in the inner scope.
7551 if (!scope.addCatchParameters(pc_, catchParamScope)) {
7552 return errorResult();
7553 }
7554
7555 ListNodeType list;
7556 MOZ_TRY_VAR(list, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (list) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7557
7558 if (!mustMatchToken(
7559 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7560 this->reportMissingClosing(JSMSG_CURLY_AFTER_CATCH,
7561 JSMSG_CURLY_OPENED, openedPos);
7562 })) {
7563 return errorResult();
7564 }
7565
7566 // The catch parameter names are not bound in the body scope, so remove
7567 // them before generating bindings.
7568 scope.removeCatchParameters(pc_, catchParamScope);
7569 return finishLexicalScope(scope, list);
7570}
7571
7572template <class ParseHandler, typename Unit>
7573typename ParseHandler::DebuggerStatementResult
7574GeneralParser<ParseHandler, Unit>::debuggerStatement() {
7575 TokenPos p;
7576 p.begin = pos().begin;
7577 if (!matchOrInsertSemicolon()) {
7578 return errorResult();
7579 }
7580 p.end = pos().end;
7581
7582 return handler_.newDebuggerStatement(p);
7583}
7584
7585static AccessorType ToAccessorType(PropertyType propType) {
7586 switch (propType) {
7587 case PropertyType::Getter:
7588 return AccessorType::Getter;
7589 case PropertyType::Setter:
7590 return AccessorType::Setter;
7591 case PropertyType::Normal:
7592 case PropertyType::Method:
7593 case PropertyType::GeneratorMethod:
7594 case PropertyType::AsyncMethod:
7595 case PropertyType::AsyncGeneratorMethod:
7596 case PropertyType::Constructor:
7597 case PropertyType::DerivedConstructor:
7598 return AccessorType::None;
7599 default:
7600 MOZ_CRASH("unexpected property type")do { do { } while (false); MOZ_ReportCrash("" "unexpected property type"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7600); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected property type"
")"); do { *((volatile int*)__null) = 7600; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
7601 }
7602}
7603
7604#ifdef ENABLE_DECORATORS
7605template <class ParseHandler, typename Unit>
7606typename ParseHandler::ListNodeResult
7607GeneralParser<ParseHandler, Unit>::decoratorList(YieldHandling yieldHandling) {
7608 ListNodeType decorators;
7609 MOZ_TRY_VAR(decorators,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::DecoratorList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decorators) = mozTryVarTempResult_.unwrap(); } while (0)
7610 handler_.newList(ParseNodeKind::DecoratorList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::DecoratorList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decorators) = mozTryVarTempResult_.unwrap(); } while (0)
;
7611
7612 // Build a decorator list element. At each entry point to this loop we have
7613 // already consumed the |@| token
7614 TokenKind tt;
7615 for (;;) {
7616 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
7617 return errorResult();
7618 }
7619
7620 Node decorator;
7621 MOZ_TRY_VAR(decorator, decoratorExpr(yieldHandling, tt))do { auto mozTryVarTempResult_ = (decoratorExpr(yieldHandling
, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()
), 0))) { return mozTryVarTempResult_.propagateErr(); } (decorator
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7622
7623 handler_.addList(decorators, decorator);
7624
7625 if (!tokenStream.getToken(&tt)) {
7626 return errorResult();
7627 }
7628 if (tt != TokenKind::At) {
7629 anyChars.ungetToken();
7630 break;
7631 }
7632 }
7633 return decorators;
7634}
7635#endif
7636
7637template <class ParseHandler, typename Unit>
7638bool GeneralParser<ParseHandler, Unit>::classMember(
7639 YieldHandling yieldHandling, const ParseContext::ClassStatement& classStmt,
7640 TaggedParserAtomIndex className, uint32_t classStartOffset,
7641 HasHeritage hasHeritage, ClassInitializedMembers& classInitializedMembers,
7642 ListNodeType& classMembers, bool* done) {
7643 *done = false;
7644
7645 TokenKind tt;
7646 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
7647 return false;
7648 }
7649 if (tt == TokenKind::RightCurly) {
7650 *done = true;
7651 return true;
7652 }
7653
7654 if (tt == TokenKind::Semi) {
7655 return true;
7656 }
7657
7658#ifdef ENABLE_DECORATORS
7659 ListNodeType decorators = null();
7660 if (tt == TokenKind::At) {
7661 MOZ_TRY_VAR_OR_RETURN(decorators, decoratorList(yieldHandling), false)do { auto parserTryVarTempResult_ = (decoratorList(yieldHandling
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (decorators) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7662
7663 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
7664 return false;
7665 }
7666 }
7667#endif
7668
7669 bool isStatic = false;
7670 if (tt == TokenKind::Static) {
7671 if (!tokenStream.peekToken(&tt)) {
7672 return false;
7673 }
7674
7675 if (tt == TokenKind::LeftCurly) {
7676 /* Parsing static class block: static { ... } */
7677 FunctionNodeType staticBlockBody;
7678 MOZ_TRY_VAR_OR_RETURN(staticBlockBody,do { auto parserTryVarTempResult_ = (staticClassBlock(classInitializedMembers
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (staticBlockBody) = parserTryVarTempResult_
.unwrap(); } while (0)
7679 staticClassBlock(classInitializedMembers), false)do { auto parserTryVarTempResult_ = (staticClassBlock(classInitializedMembers
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (staticBlockBody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7680
7681 StaticClassBlockType classBlock;
7682 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newStaticClassBlock
(staticBlockBody)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (classBlock) = parserTryVarTempResult_
.unwrap(); } while (0)
7683 classBlock, handler_.newStaticClassBlock(staticBlockBody), false)do { auto parserTryVarTempResult_ = (handler_.newStaticClassBlock
(staticBlockBody)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (classBlock) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7684
7685 return handler_.addClassMemberDefinition(classMembers, classBlock);
7686 }
7687
7688 if (tt != TokenKind::LeftParen && tt != TokenKind::Assign &&
7689 tt != TokenKind::Semi && tt != TokenKind::RightCurly) {
7690 isStatic = true;
7691 } else {
7692 anyChars.ungetToken();
7693 }
7694 } else {
7695 anyChars.ungetToken();
7696 }
7697
7698 uint32_t propNameOffset;
7699 if (!tokenStream.peekOffset(&propNameOffset, TokenStream::SlashIsInvalid)) {
7700 return false;
7701 }
7702
7703 TaggedParserAtomIndex propAtom;
7704 PropertyType propType;
7705 Node propName;
7706 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7707 propName,do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7708 propertyOrMethodName(yieldHandling, PropertyNameInClass,do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7709 /* maybeDecl = */ Nothing(), classMembers, &propType,do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7710 &propAtom),do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7711 false)do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7712
7713 if (propType == PropertyType::Field ||
7714 propType == PropertyType::FieldWithAccessor) {
7715 if (isStatic) {
7716 if (propAtom == TaggedParserAtomIndex::WellKnown::prototype()) {
7717 errorAt(propNameOffset, JSMSG_CLASS_STATIC_PROTO);
7718 return false;
7719 }
7720 }
7721
7722 if (propAtom == TaggedParserAtomIndex::WellKnown::constructor()) {
7723 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7724 return false;
7725 }
7726
7727 if (handler_.isPrivateName(propName)) {
7728 if (propAtom == TaggedParserAtomIndex::WellKnown::hash_constructor_()) {
7729 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7730 return false;
7731 }
7732
7733 auto privateName = propAtom;
7734 if (!noteDeclaredPrivateName(
7735 propName, privateName, propType,
7736 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7737 pos())) {
7738 return false;
7739 }
7740 }
7741
7742#ifdef ENABLE_DECORATORS
7743 ClassMethodType accessorGetterNode = null();
7744 ClassMethodType accessorSetterNode = null();
7745 if (propType == PropertyType::FieldWithAccessor) {
7746 // Decorators Proposal
7747 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-runtime-semantics-classfielddefinitionevaluation
7748 //
7749 // FieldDefinition : accessor ClassElementName Initializeropt
7750 //
7751 // Step 1. Let name be the result of evaluating ClassElementName.
7752 // ...
7753 // Step 3. Let privateStateDesc be the string-concatenation of name
7754 // and " accessor storage".
7755 StringBuffer privateStateDesc(fc_);
7756 if (!privateStateDesc.append(this->parserAtoms(), propAtom)) {
7757 return false;
7758 }
7759 if (!privateStateDesc.append(" accessor storage")) {
7760 return false;
7761 }
7762 // Step 4. Let privateStateName be a new Private Name whose
7763 // [[Description]] value is privateStateDesc.
7764 TokenPos propNamePos(propNameOffset, pos().end);
7765 auto privateStateName =
7766 privateStateDesc.finishParserAtom(this->parserAtoms(), fc_);
7767 if (!noteDeclaredPrivateName(
7768 propName, privateStateName, propType,
7769 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7770 propNamePos)) {
7771 return false;
7772 }
7773
7774 // Step 5. Let getter be MakeAutoAccessorGetter(homeObject, name,
7775 // privateStateName).
7776 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7777 accessorGetterNode,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7778 synthesizeAccessor(propName, propNamePos, propAtom, privateStateName,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7779 isStatic, FunctionSyntaxKind::Getter,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7780 classInitializedMembers),do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7781 false)do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
;
7782
7783 // If the accessor is not decorated or is a non-static private field,
7784 // add it to the class here. Otherwise, we'll handle this when the
7785 // decorators are called. We don't need to keep a reference to the node
7786 // after this except for non-static private accessors. Please see the
7787 // comment in the definition of ClassField for details.
7788 bool addAccessorImmediately =
7789 !decorators || (!isStatic && handler_.isPrivateName(propName));
7790 if (addAccessorImmediately) {
7791 if (!handler_.addClassMemberDefinition(classMembers,
7792 accessorGetterNode)) {
7793 return false;
7794 }
7795 if (!handler_.isPrivateName(propName)) {
7796 accessorGetterNode = null();
7797 }
7798 }
7799
7800 // Step 6. Let setter be MakeAutoAccessorSetter(homeObject, name,
7801 // privateStateName).
7802 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7803 accessorSetterNode,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7804 synthesizeAccessor(propName, propNamePos, propAtom, privateStateName,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7805 isStatic, FunctionSyntaxKind::Setter,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7806 classInitializedMembers),do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7807 false)do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
;
7808
7809 if (addAccessorImmediately) {
7810 if (!handler_.addClassMemberDefinition(classMembers,
7811 accessorSetterNode)) {
7812 return false;
7813 }
7814 if (!handler_.isPrivateName(propName)) {
7815 accessorSetterNode = null();
7816 }
7817 }
7818
7819 // Step 10. Return ClassElementDefinition Record { [[Key]]: name,
7820 // [[Kind]]: accessor, [[Get]]: getter, [[Set]]: setter,
7821 // [[BackingStorageKey]]: privateStateName, [[Initializers]]:
7822 // initializers, [[Decorators]]: empty }.
7823 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newPrivateName(
privateStateName, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7824 propName, handler_.newPrivateName(privateStateName, pos()), false)do { auto parserTryVarTempResult_ = (handler_.newPrivateName(
privateStateName, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7825 propAtom = privateStateName;
7826 // We maintain `decorators` here to perform this step at the same time:
7827 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-static-semantics-classelementevaluation
7828 // 4. Set fieldDefinition.[[Decorators]] to decorators.
7829 }
7830#endif
7831 if (isStatic) {
7832 classInitializedMembers.staticFields++;
7833 } else {
7834 classInitializedMembers.instanceFields++;
7835#ifdef ENABLE_DECORATORS
7836 if (decorators) {
7837 classInitializedMembers.hasInstanceDecorators = true;
7838 }
7839#endif
7840 }
7841
7842 TokenPos propNamePos(propNameOffset, pos().end);
7843 FunctionNodeType initializer;
7844 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7845 initializer,do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7846 fieldInitializerOpt(propNamePos, propName, propAtom,do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7847 classInitializedMembers, isStatic, hasHeritage),do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7848 false)do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7849
7850 if (!matchOrInsertSemicolon(TokenStream::SlashIsInvalid)) {
7851 return false;
7852 }
7853
7854 ClassFieldType field;
7855 MOZ_TRY_VAR_OR_RETURN(field,do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7856 handler_.newClassFieldDefinition(do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7857 propName, initializer, isStaticdo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7858#ifdef ENABLE_DECORATORSdo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7859 ,do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7860 decorators, accessorGetterNode, accessorSetterNodedo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7861#endifdo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7862 ),do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7863 false)do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
;
7864
7865 return handler_.addClassMemberDefinition(classMembers, field);
7866 }
7867
7868 if (propType != PropertyType::Getter && propType != PropertyType::Setter &&
7869 propType != PropertyType::Method &&
7870 propType != PropertyType::GeneratorMethod &&
7871 propType != PropertyType::AsyncMethod &&
7872 propType != PropertyType::AsyncGeneratorMethod) {
7873 errorAt(propNameOffset, JSMSG_BAD_CLASS_MEMBER_DEF);
7874 return false;
7875 }
7876
7877 bool isConstructor =
7878 !isStatic && propAtom == TaggedParserAtomIndex::WellKnown::constructor();
7879 if (isConstructor) {
7880 if (propType != PropertyType::Method) {
7881 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7882 return false;
7883 }
7884 if (classStmt.constructorBox) {
7885 errorAt(propNameOffset, JSMSG_DUPLICATE_CONSTRUCTOR);
7886 return false;
7887 }
7888 propType = hasHeritage == HasHeritage::Yes
7889 ? PropertyType::DerivedConstructor
7890 : PropertyType::Constructor;
7891 } else if (isStatic &&
7892 propAtom == TaggedParserAtomIndex::WellKnown::prototype()) {
7893 errorAt(propNameOffset, JSMSG_CLASS_STATIC_PROTO);
7894 return false;
7895 }
7896
7897 TaggedParserAtomIndex funName;
7898 switch (propType) {
7899 case PropertyType::Getter:
7900 case PropertyType::Setter: {
7901 bool hasStaticName =
7902 !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom;
7903 if (hasStaticName) {
7904 funName = prefixAccessorName(propType, propAtom);
7905 if (!funName) {
7906 return false;
7907 }
7908 }
7909 break;
7910 }
7911 case PropertyType::Constructor:
7912 case PropertyType::DerivedConstructor:
7913 funName = className;
7914 break;
7915 default:
7916 if (!anyChars.isCurrentTokenType(TokenKind::RightBracket)) {
7917 funName = propAtom;
7918 }
7919 }
7920
7921 // When |super()| is invoked, we search for the nearest scope containing
7922 // |.initializers| to initialize the class fields. This set-up precludes
7923 // declaring |.initializers| in the class scope, because in some syntactic
7924 // contexts |super()| can appear nested in a class, while actually belonging
7925 // to an outer class definition.
7926 //
7927 // Example:
7928 // class Outer extends Base {
7929 // field = 1;
7930 // constructor() {
7931 // class Inner {
7932 // field = 2;
7933 //
7934 // // The super() call in the computed property name mustn't access
7935 // // Inner's |.initializers| array, but instead Outer's.
7936 // [super()]() {}
7937 // }
7938 // }
7939 // }
7940 Maybe<ParseContext::Scope> dotInitializersScope;
7941 if (isConstructor && !options().selfHostingMode) {
7942 dotInitializersScope.emplace(this);
7943 if (!dotInitializersScope->init(pc_)) {
7944 return false;
7945 }
7946
7947 if (!noteDeclaredName(TaggedParserAtomIndex::WellKnown::dot_initializers_(),
7948 DeclarationKind::Let, pos())) {
7949 return false;
7950 }
7951
7952#ifdef ENABLE_DECORATORS
7953 if (!noteDeclaredName(
7954 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
7955 DeclarationKind::Let, pos())) {
7956 return false;
7957 }
7958#endif
7959 }
7960
7961 // Calling toString on constructors need to return the source text for
7962 // the entire class. The end offset is unknown at this point in
7963 // parsing and will be amended when class parsing finishes below.
7964 FunctionNodeType funNode;
7965 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7966 funNode,do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7967 methodDefinition(isConstructor ? classStartOffset : propNameOffset,do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7968 propType, funName),do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7969 false)do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
;
7970
7971 AccessorType atype = ToAccessorType(propType);
7972
7973 Maybe<FunctionNodeType> initializerIfPrivate = Nothing();
7974 if (handler_.isPrivateName(propName)) {
7975 if (propAtom == TaggedParserAtomIndex::WellKnown::hash_constructor_()) {
7976 // #constructor is an invalid private name.
7977 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7978 return false;
7979 }
7980
7981 TaggedParserAtomIndex privateName = propAtom;
7982 if (!noteDeclaredPrivateName(
7983 propName, privateName, propType,
7984 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7985 pos())) {
7986 return false;
7987 }
7988
7989 // Private non-static methods are stored in the class body environment.
7990 // Private non-static accessors are stamped onto every instance using
7991 // initializers. Private static methods are stamped onto the constructor
7992 // during class evaluation; see BytecodeEmitter::emitPropertyList.
7993 if (!isStatic) {
7994 if (atype == AccessorType::Getter || atype == AccessorType::Setter) {
7995 classInitializedMembers.privateAccessors++;
7996 TokenPos propNamePos(propNameOffset, pos().end);
7997 FunctionNodeType initializerNode;
7998 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
7999 initializerNode,do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8000 synthesizePrivateMethodInitializer(propAtom, atype, propNamePos),do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8001 false)do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8002 initializerIfPrivate = Some(initializerNode);
8003 } else {
8004 MOZ_ASSERT(atype == AccessorType::None)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(atype == AccessorType::None)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(atype == AccessorType::None)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("atype == AccessorType::None"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8004); AnnotateMozCrashReason("MOZ_ASSERT" "(" "atype == AccessorType::None"
")"); do { *((volatile int*)__null) = 8004; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8005 classInitializedMembers.privateMethods++;
8006 }
8007 }
8008 }
8009
8010#ifdef ENABLE_DECORATORS
8011 if (decorators) {
8012 classInitializedMembers.hasInstanceDecorators = true;
8013 }
8014#endif
8015
8016 Node method;
8017 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8018 method,do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8019 handler_.newClassMethodDefinition(propName, funNode, atype, isStatic,do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8020 initializerIfPrivatedo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8021#ifdef ENABLE_DECORATORSdo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8022 ,do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8023 decoratorsdo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8024#endifdo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8025 ),do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8026 false)do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
;
8027
8028 if (dotInitializersScope.isSome()) {
8029 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(*dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (method) = parserTryVarTempResult_
.unwrap(); } while (0)
8030 method, finishLexicalScope(*dotInitializersScope, method), false)do { auto parserTryVarTempResult_ = (finishLexicalScope(*dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (method) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8031 dotInitializersScope.reset();
8032 }
8033
8034 return handler_.addClassMemberDefinition(classMembers, method);
8035}
8036
8037template <class ParseHandler, typename Unit>
8038bool GeneralParser<ParseHandler, Unit>::finishClassConstructor(
8039 const ParseContext::ClassStatement& classStmt,
8040 TaggedParserAtomIndex className, HasHeritage hasHeritage,
8041 uint32_t classStartOffset, uint32_t classEndOffset,
8042 const ClassInitializedMembers& classInitializedMembers,
8043 ListNodeType& classMembers) {
8044 if (classStmt.constructorBox == nullptr) {
8045 MOZ_ASSERT(!options().selfHostingMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!options().selfHostingMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!options().selfHostingMode))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!options().selfHostingMode"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8045); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 8045; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8046 // Unconditionally create the scope here, because it's always the
8047 // constructor.
8048 ParseContext::Scope dotInitializersScope(this);
8049 if (!dotInitializersScope.init(pc_)) {
8050 return false;
8051 }
8052
8053 if (!noteDeclaredName(TaggedParserAtomIndex::WellKnown::dot_initializers_(),
8054 DeclarationKind::Let, pos())) {
8055 return false;
8056 }
8057
8058#ifdef ENABLE_DECORATORS
8059 if (!noteDeclaredName(
8060 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
8061 DeclarationKind::Let, pos(), ClosedOver::Yes)) {
8062 return false;
8063 }
8064#endif
8065
8066 // synthesizeConstructor assigns to classStmt.constructorBox
8067 TokenPos synthesizedBodyPos(classStartOffset, classEndOffset);
8068 FunctionNodeType synthesizedCtor;
8069 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8070 synthesizedCtor,do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8071 synthesizeConstructor(className, synthesizedBodyPos, hasHeritage),do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8072 false)do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
;
8073
8074 // Note: the *function* has the name of the class, but the *property*
8075 // containing the function has the name "constructor"
8076 Node constructorNameNode;
8077 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8078 constructorNameNode,do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8079 handler_.newObjectLiteralPropertyName(do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8080 TaggedParserAtomIndex::WellKnown::constructor(), pos()),do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8081 false)do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8082 ClassMethodType method;
8083 MOZ_TRY_VAR_OR_RETURN(method,do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8084 handler_.newDefaultClassConstructor(do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8085 constructorNameNode, synthesizedCtor),do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8086 false)do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
;
8087 LexicalScopeNodeType scope;
8088 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (scope) = parserTryVarTempResult_
.unwrap(); } while (0)
8089 scope, finishLexicalScope(dotInitializersScope, method), false)do { auto parserTryVarTempResult_ = (finishLexicalScope(dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (scope) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8090 if (!handler_.addClassMemberDefinition(classMembers, scope)) {
8091 return false;
8092 }
8093 }
8094
8095 MOZ_ASSERT(classStmt.constructorBox)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(classStmt.constructorBox)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(classStmt.constructorBox))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("classStmt.constructorBox"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8095); AnnotateMozCrashReason("MOZ_ASSERT" "(" "classStmt.constructorBox"
")"); do { *((volatile int*)__null) = 8095; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8096 FunctionBox* ctorbox = classStmt.constructorBox;
8097
8098 // Amend the toStringEnd offset for the constructor now that we've
8099 // finished parsing the class.
8100 ctorbox->setCtorToStringEnd(classEndOffset);
8101
8102 size_t numMemberInitializers = classInitializedMembers.privateAccessors +
8103 classInitializedMembers.instanceFields;
8104 bool hasPrivateBrand = classInitializedMembers.hasPrivateBrand();
8105 if (hasPrivateBrand || numMemberInitializers > 0) {
8106 // Now that we have full set of initializers, update the constructor.
8107 MemberInitializers initializers(
8108 hasPrivateBrand,
8109#ifdef ENABLE_DECORATORS
8110 classInitializedMembers.hasInstanceDecorators,
8111#endif
8112 numMemberInitializers);
8113 ctorbox->setMemberInitializers(initializers);
8114
8115 // Field initialization need access to `this`.
8116 ctorbox->setCtorFunctionHasThisBinding();
8117 }
8118
8119 return true;
8120}
8121
8122template <class ParseHandler, typename Unit>
8123typename ParseHandler::ClassNodeResult
8124GeneralParser<ParseHandler, Unit>::classDefinition(
8125 YieldHandling yieldHandling, ClassContext classContext,
8126 DefaultHandling defaultHandling) {
8127#ifdef ENABLE_DECORATORS
8128 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::At) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::At) || anyChars
.isCurrentTokenType(TokenKind::Class))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
8129 anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::At) || anyChars
.isCurrentTokenType(TokenKind::Class))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8130
8131 ListNodeType decorators = null();
8132 FunctionNodeType addInitializerFunction = null();
8133 if (anyChars.isCurrentTokenType(TokenKind::At)) {
8134 MOZ_TRY_VAR(decorators, decoratorList(yieldHandling))do { auto mozTryVarTempResult_ = (decoratorList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (decorators
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8135 TokenKind next;
8136 if (!tokenStream.getToken(&next)) {
8137 return errorResult();
8138 }
8139 if (next != TokenKind::Class) {
8140 error(JSMSG_CLASS_EXPECTED);
8141 return errorResult();
8142 }
8143 }
8144#else
8145 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Class))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Class)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8145); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8145; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8146#endif
8147
8148 uint32_t classStartOffset = pos().begin;
8149 bool savedStrictness = setLocalStrictMode(true);
8150
8151 // Classes are quite broken in self-hosted code.
8152 if (options().selfHostingMode) {
8153 error(JSMSG_SELFHOSTED_CLASS);
8154 return errorResult();
8155 }
8156
8157 TokenKind tt;
8158 if (!tokenStream.getToken(&tt)) {
8159 return errorResult();
8160 }
8161
8162 TaggedParserAtomIndex className;
8163 if (TokenKindIsPossibleIdentifier(tt)) {
8164 className = bindingIdentifier(yieldHandling);
8165 if (!className) {
8166 return errorResult();
8167 }
8168 } else if (classContext == ClassStatement) {
8169 if (defaultHandling == AllowDefaultName) {
8170 className = TaggedParserAtomIndex::WellKnown::default_();
8171 anyChars.ungetToken();
8172 } else {
8173 // Class statements must have a bound name
8174 error(JSMSG_UNNAMED_CLASS_STMT);
8175 return errorResult();
8176 }
8177 } else {
8178 // Make sure to put it back, whatever it was
8179 anyChars.ungetToken();
8180 }
8181
8182 // Because the binding definitions keep track of their blockId, we need to
8183 // create at least the inner binding later. Keep track of the name's
8184 // position in order to provide it for the nodes created later.
8185 TokenPos namePos = pos();
8186
8187 auto isClass = [](ParseContext::Statement* stmt) {
8188 return stmt->kind() == StatementKind::Class;
8189 };
8190
8191 bool isInClass = pc_->sc()->inClass() || pc_->findInnermostStatement(isClass);
8192
8193 // Push a ParseContext::ClassStatement to keep track of the constructor
8194 // funbox.
8195 ParseContext::ClassStatement classStmt(pc_);
8196
8197 NameNodeType innerName;
8198 Node nameNode = null();
8199 Node classHeritage = null();
8200 LexicalScopeNodeType classBlock = null();
8201 ClassBodyScopeNodeType classBodyBlock = null();
8202 uint32_t classEndOffset;
8203 {
8204 // A named class creates a new lexical scope with a const binding of the
8205 // class name for the "inner name".
8206 ParseContext::Statement innerScopeStmt(pc_, StatementKind::Block);
8207 ParseContext::Scope innerScope(this);
8208 if (!innerScope.init(pc_)) {
8209 return errorResult();
8210 }
8211
8212 bool hasHeritageBool;
8213 if (!tokenStream.matchToken(&hasHeritageBool, TokenKind::Extends)) {
8214 return errorResult();
8215 }
8216 HasHeritage hasHeritage =
8217 hasHeritageBool ? HasHeritage::Yes : HasHeritage::No;
8218 if (hasHeritage == HasHeritage::Yes) {
8219 if (!tokenStream.getToken(&tt)) {
8220 return errorResult();
8221 }
8222 MOZ_TRY_VAR(classHeritage,do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classHeritage) = mozTryVarTempResult_.unwrap(); } while (
0)
8223 optionalExpr(yieldHandling, TripledotProhibited, tt))do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classHeritage) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8224 }
8225
8226 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_CLASS)) {
8227 return errorResult();
8228 }
8229
8230 {
8231 ParseContext::Statement bodyScopeStmt(pc_, StatementKind::Block);
8232 ParseContext::Scope bodyScope(this);
8233 if (!bodyScope.init(pc_)) {
8234 return errorResult();
8235 }
8236
8237 ListNodeType classMembers;
8238 MOZ_TRY_VAR(classMembers, handler_.newClassMemberList(pos().begin))do { auto mozTryVarTempResult_ = (handler_.newClassMemberList
(pos().begin)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classMembers) = mozTryVarTempResult_.unwrap(); } while (0
)
;
8239
8240 ClassInitializedMembers classInitializedMembers{};
8241 for (;;) {
8242 bool done;
8243 if (!classMember(yieldHandling, classStmt, className, classStartOffset,
8244 hasHeritage, classInitializedMembers, classMembers,
8245 &done)) {
8246 return errorResult();
8247 }
8248 if (done) {
8249 break;
8250 }
8251 }
8252#ifdef ENABLE_DECORATORS
8253 if (classInitializedMembers.hasInstanceDecorators) {
8254 MOZ_TRY_VAR(addInitializerFunction,do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8255 synthesizeAddInitializerFunction(do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8256 TaggedParserAtomIndex::WellKnown::do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8257 dot_instanceExtraInitializers_(),do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8258 yieldHandling))do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
;
8259 }
8260#endif
8261
8262 if (classInitializedMembers.privateMethods +
8263 classInitializedMembers.privateAccessors >
8264 0) {
8265 // We declare `.privateBrand` as ClosedOver because the constructor
8266 // always uses it, even a default constructor. We could equivalently
8267 // `noteUsedName` when parsing the constructor, except that at that
8268 // time, we don't necessarily know if the class has a private brand.
8269 if (!noteDeclaredName(
8270 TaggedParserAtomIndex::WellKnown::dot_privateBrand_(),
8271 DeclarationKind::Synthetic, namePos, ClosedOver::Yes)) {
8272 return errorResult();
8273 }
8274 }
8275
8276 if (classInitializedMembers.instanceFieldKeys > 0) {
8277 if (!noteDeclaredName(
8278 TaggedParserAtomIndex::WellKnown::dot_fieldKeys_(),
8279 DeclarationKind::Synthetic, namePos)) {
8280 return errorResult();
8281 }
8282 }
8283
8284 if (classInitializedMembers.staticFields > 0) {
8285 if (!noteDeclaredName(
8286 TaggedParserAtomIndex::WellKnown::dot_staticInitializers_(),
8287 DeclarationKind::Synthetic, namePos)) {
8288 return errorResult();
8289 }
8290 }
8291
8292 if (classInitializedMembers.staticFieldKeys > 0) {
8293 if (!noteDeclaredName(
8294 TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_(),
8295 DeclarationKind::Synthetic, namePos)) {
8296 return errorResult();
8297 }
8298 }
8299
8300 classEndOffset = pos().end;
8301 if (!finishClassConstructor(classStmt, className, hasHeritage,
8302 classStartOffset, classEndOffset,
8303 classInitializedMembers, classMembers)) {
8304 return errorResult();
8305 }
8306
8307 MOZ_TRY_VAR(classBodyBlock,do { auto mozTryVarTempResult_ = (finishClassBodyScope(bodyScope
, classMembers)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBodyBlock) = mozTryVarTempResult_.unwrap(); } while (
0)
8308 finishClassBodyScope(bodyScope, classMembers))do { auto mozTryVarTempResult_ = (finishClassBodyScope(bodyScope
, classMembers)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBodyBlock) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8309
8310 // Pop the class body scope
8311 }
8312
8313 if (className) {
8314 // The inner name is immutable.
8315 if (!noteDeclaredName(className, DeclarationKind::Const, namePos)) {
8316 return errorResult();
8317 }
8318
8319 MOZ_TRY_VAR(innerName, newName(className, namePos))do { auto mozTryVarTempResult_ = (newName(className, namePos)
); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)
)) { return mozTryVarTempResult_.propagateErr(); } (innerName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8320 }
8321
8322 MOZ_TRY_VAR(classBlock, finishLexicalScope(innerScope, classBodyBlock))do { auto mozTryVarTempResult_ = (finishLexicalScope(innerScope
, classBodyBlock)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBlock) = mozTryVarTempResult_.unwrap(); } while (0)
;
8323
8324 // Pop the inner scope.
8325 }
8326
8327 if (className) {
8328 NameNodeType outerName = null();
8329 if (classContext == ClassStatement) {
8330 // The outer name is mutable.
8331 if (!noteDeclaredName(className, DeclarationKind::Class, namePos)) {
8332 return errorResult();
8333 }
8334
8335 MOZ_TRY_VAR(outerName, newName(className, namePos))do { auto mozTryVarTempResult_ = (newName(className, namePos)
); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)
)) { return mozTryVarTempResult_.propagateErr(); } (outerName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8336 }
8337
8338 MOZ_TRY_VAR(nameNode,do { auto mozTryVarTempResult_ = (handler_.newClassNames(outerName
, innerName, namePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nameNode) = mozTryVarTempResult_.unwrap(); } while (0)
8339 handler_.newClassNames(outerName, innerName, namePos))do { auto mozTryVarTempResult_ = (handler_.newClassNames(outerName
, innerName, namePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nameNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8340 }
8341 MOZ_ALWAYS_TRUE(setLocalStrictMode(savedStrictness))do { if ((__builtin_expect(!!(setLocalStrictMode(savedStrictness
)), 1))) { } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "setLocalStrictMode(savedStrictness)"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8341); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "setLocalStrictMode(savedStrictness)" ")"); do { *((volatile
int*)__null) = 8341; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false); } } while (false)
;
8342 // We're leaving a class definition that was not itself nested within a class
8343 if (!isInClass) {
8344 mozilla::Maybe<UnboundPrivateName> maybeUnboundName;
8345 if (!usedNames_.hasUnboundPrivateNames(fc_, maybeUnboundName)) {
8346 return errorResult();
8347 }
8348 if (maybeUnboundName) {
8349 UniqueChars str =
8350 this->parserAtoms().toPrintableString(maybeUnboundName->atom);
8351 if (!str) {
8352 ReportOutOfMemory(this->fc_);
8353 return errorResult();
8354 }
8355
8356 errorAt(maybeUnboundName->position.begin, JSMSG_MISSING_PRIVATE_DECL,
8357 str.get());
8358 return errorResult();
8359 }
8360 }
8361
8362 return handler_.newClass(nameNode, classHeritage, classBlock,
8363#ifdef ENABLE_DECORATORS
8364 decorators, addInitializerFunction,
8365#endif
8366 TokenPos(classStartOffset, classEndOffset));
8367}
8368
8369template <class ParseHandler, typename Unit>
8370typename ParseHandler::FunctionNodeResult
8371GeneralParser<ParseHandler, Unit>::synthesizeConstructor(
8372 TaggedParserAtomIndex className, TokenPos synthesizedBodyPos,
8373 HasHeritage hasHeritage) {
8374 FunctionSyntaxKind functionSyntaxKind =
8375 hasHeritage == HasHeritage::Yes
8376 ? FunctionSyntaxKind::DerivedClassConstructor
8377 : FunctionSyntaxKind::ClassConstructor;
8378
8379 bool isSelfHosting = options().selfHostingMode;
8380 FunctionFlags flags =
8381 InitialFunctionFlags(functionSyntaxKind, GeneratorKind::NotGenerator,
8382 FunctionAsyncKind::SyncFunction, isSelfHosting);
8383
8384 // Create the top-level field initializer node.
8385 FunctionNodeType funNode;
8386 MOZ_TRY_VAR(funNode,do { auto mozTryVarTempResult_ = (handler_.newFunction(functionSyntaxKind
, synthesizedBodyPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
8387 handler_.newFunction(functionSyntaxKind, synthesizedBodyPos))do { auto mozTryVarTempResult_ = (handler_.newFunction(functionSyntaxKind
, synthesizedBodyPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8388
8389 // If we see any inner function, note it on our current context. The bytecode
8390 // emitter may eliminate the function later, but we use a conservative
8391 // definition for consistency between lazy and full parsing.
8392 pc_->sc()->setHasInnerFunctions();
8393
8394 // When fully parsing a lazy script, we do not fully reparse its inner
8395 // functions, which are also lazy. Instead, their free variables and source
8396 // extents are recorded and may be skipped.
8397 if (handler_.reuseLazyInnerFunctions()) {
8398 if (!skipLazyInnerFunction(funNode, synthesizedBodyPos.begin,
8399 /* tryAnnexB = */ false)) {
8400 return errorResult();
8401 }
8402
8403 return funNode;
8404 }
8405
8406 // Create the FunctionBox and link it to the function object.
8407 Directives directives(true);
8408 FunctionBox* funbox = newFunctionBox(
8409 funNode, className, flags, synthesizedBodyPos.begin, directives,
8410 GeneratorKind::NotGenerator, FunctionAsyncKind::SyncFunction);
8411 if (!funbox) {
8412 return errorResult();
8413 }
8414 funbox->initWithEnclosingParseContext(pc_, functionSyntaxKind);
8415 setFunctionEndFromCurrentToken(funbox);
8416
8417 // Mark this function as being synthesized by the parser. This means special
8418 // handling in delazification will be used since we don't have typical
8419 // function syntax.
8420 funbox->setSyntheticFunction();
8421
8422 // Push a SourceParseContext on to the stack.
8423 ParseContext* outerpc = pc_;
8424 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8425 if (!funpc.init()) {
8426 return errorResult();
8427 }
8428
8429 if (!synthesizeConstructorBody(synthesizedBodyPos, hasHeritage, funNode,
8430 funbox)) {
8431 return errorResult();
8432 }
8433
8434 if (!leaveInnerFunction(outerpc)) {
8435 return errorResult();
8436 }
8437
8438 return funNode;
8439}
8440
8441template <class ParseHandler, typename Unit>
8442bool GeneralParser<ParseHandler, Unit>::synthesizeConstructorBody(
8443 TokenPos synthesizedBodyPos, HasHeritage hasHeritage,
8444 FunctionNodeType funNode, FunctionBox* funbox) {
8445 MOZ_ASSERT(funbox->isClassConstructor())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isClassConstructor())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isClassConstructor
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isClassConstructor()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8445); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isClassConstructor()"
")"); do { *((volatile int*)__null) = 8445; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8446
8447 // Create a ParamsBodyNode for the parameters + body (there are no
8448 // parameters).
8449 ParamsBodyNodeType argsbody;
8450 MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(synthesizedBodyPos),do { auto parserTryVarTempResult_ = (handler_.newParamsBody(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
8451 false)do { auto parserTryVarTempResult_ = (handler_.newParamsBody(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8452 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8453 setFunctionStartAtPosition(funbox, synthesizedBodyPos);
8454
8455 if (hasHeritage == HasHeritage::Yes) {
8456 // Synthesize the equivalent to `function f(...args)`
8457 funbox->setHasRest();
8458 if (!notePositionalFormalParameter(
8459 funNode, TaggedParserAtomIndex::WellKnown::dot_args_(),
8460 synthesizedBodyPos.begin,
8461 /* disallowDuplicateParams = */ false,
8462 /* duplicatedParam = */ nullptr)) {
8463 return false;
8464 }
8465 funbox->setArgCount(1);
8466 } else {
8467 funbox->setArgCount(0);
8468 }
8469
8470 pc_->functionScope().useAsVarScope(pc_);
8471
8472 ListNodeType stmtList;
8473 MOZ_TRY_VAR_OR_RETURN(stmtList, handler_.newStatementList(synthesizedBodyPos),do { auto parserTryVarTempResult_ = (handler_.newStatementList
(synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (stmtList) = parserTryVarTempResult_
.unwrap(); } while (0)
8474 false)do { auto parserTryVarTempResult_ = (handler_.newStatementList
(synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (stmtList) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8475
8476 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_this_())) {
8477 return false;
8478 }
8479
8480 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
8481 return false;
8482 }
8483
8484#ifdef ENABLE_DECORATORS
8485 if (!noteUsedName(
8486 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_())) {
8487 return false;
8488 }
8489#endif
8490
8491 if (hasHeritage == HasHeritage::Yes) {
8492 // |super()| implicitly reads |new.target|.
8493 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
8494 return false;
8495 }
8496
8497 NameNodeType thisName;
8498 MOZ_TRY_VAR_OR_RETURN(thisName, newThisName(), false)do { auto parserTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(thisName) = parserTryVarTempResult_.unwrap(); } while (0)
;
8499
8500 UnaryNodeType superBase;
8501 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newSuperBase(thisName
, synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superBase) = parserTryVarTempResult_
.unwrap(); } while (0)
8502 superBase, handler_.newSuperBase(thisName, synthesizedBodyPos), false)do { auto parserTryVarTempResult_ = (handler_.newSuperBase(thisName
, synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superBase) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8503
8504 ListNodeType arguments;
8505 MOZ_TRY_VAR_OR_RETURN(arguments, handler_.newArguments(synthesizedBodyPos),do { auto parserTryVarTempResult_ = (handler_.newArguments(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (arguments) = parserTryVarTempResult_
.unwrap(); } while (0)
8506 false)do { auto parserTryVarTempResult_ = (handler_.newArguments(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (arguments) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8507
8508 NameNodeType argsNameNode;
8509 MOZ_TRY_VAR_OR_RETURN(argsNameNode,do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
8510 newName(TaggedParserAtomIndex::WellKnown::dot_args_(),do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
8511 synthesizedBodyPos),do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
8512 false)do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
;
8513 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_args_())) {
8514 return false;
8515 }
8516
8517 UnaryNodeType spreadArgs;
8518 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newSpread(synthesizedBodyPos
.begin, argsNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (spreadArgs) = parserTryVarTempResult_
.unwrap(); } while (0)
8519 spreadArgs, handler_.newSpread(synthesizedBodyPos.begin, argsNameNode),do { auto parserTryVarTempResult_ = (handler_.newSpread(synthesizedBodyPos
.begin, argsNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (spreadArgs) = parserTryVarTempResult_
.unwrap(); } while (0)
8520 false)do { auto parserTryVarTempResult_ = (handler_.newSpread(synthesizedBodyPos
.begin, argsNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (spreadArgs) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8521 handler_.addList(arguments, spreadArgs);
8522
8523 CallNodeType superCall;
8524 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
8525 superCall,do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
8526 handler_.newSuperCall(superBase, arguments, /* isSpread = */ true),do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
8527 false)do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8528
8529 BinaryNodeType setThis;
8530 MOZ_TRY_VAR_OR_RETURN(setThis, handler_.newSetThis(thisName, superCall),do { auto parserTryVarTempResult_ = (handler_.newSetThis(thisName
, superCall)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (setThis) = parserTryVarTempResult_
.unwrap(); } while (0)
8531 false)do { auto parserTryVarTempResult_ = (handler_.newSetThis(thisName
, superCall)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (setThis) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8532
8533 UnaryNodeType exprStatement;
8534 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newExprStatement
(setThis, synthesizedBodyPos.end)); if ((__builtin_expect(!!(
parserTryVarTempResult_.isErr()), 0))) { return (false); } (exprStatement
) = parserTryVarTempResult_.unwrap(); } while (0)
8535 exprStatement,do { auto parserTryVarTempResult_ = (handler_.newExprStatement
(setThis, synthesizedBodyPos.end)); if ((__builtin_expect(!!(
parserTryVarTempResult_.isErr()), 0))) { return (false); } (exprStatement
) = parserTryVarTempResult_.unwrap(); } while (0)
8536 handler_.newExprStatement(setThis, synthesizedBodyPos.end), false)do { auto parserTryVarTempResult_ = (handler_.newExprStatement
(setThis, synthesizedBodyPos.end)); if ((__builtin_expect(!!(
parserTryVarTempResult_.isErr()), 0))) { return (false); } (exprStatement
) = parserTryVarTempResult_.unwrap(); } while (0)
;
8537
8538 handler_.addStatementToList(stmtList, exprStatement);
8539 }
8540
8541 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8542 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8543 return false;
8544 }
8545 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8546 return false;
8547 }
8548
8549 LexicalScopeNodeType initializerBody;
8550 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
8551 initializerBody,do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
8552 finishLexicalScope(pc_->varScope(), stmtList, ScopeKind::FunctionLexical),do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
8553 false)do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
;
8554 handler_.setBeginPosition(initializerBody, stmtList);
8555 handler_.setEndPosition(initializerBody, stmtList);
8556
8557 handler_.setFunctionBody(funNode, initializerBody);
8558
8559 return finishFunction();
8560}
8561
8562template <class ParseHandler, typename Unit>
8563typename ParseHandler::FunctionNodeResult
8564GeneralParser<ParseHandler, Unit>::privateMethodInitializer(
8565 TokenPos propNamePos, TaggedParserAtomIndex propAtom,
8566 TaggedParserAtomIndex storedMethodAtom) {
8567 if (!abortIfSyntaxParser()) {
8568 return errorResult();
8569 }
8570
8571 // Synthesize an initializer function that the constructor can use to stamp a
8572 // private method onto an instance object.
8573 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer;
8574 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8575 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8576 bool isSelfHosting = options().selfHostingMode;
8577 FunctionFlags flags =
8578 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8579
8580 FunctionNodeType funNode;
8581 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8582
8583 Directives directives(true);
8584 FunctionBox* funbox =
8585 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
8586 propNamePos.begin, directives, generatorKind, asyncKind);
8587 if (!funbox) {
8588 return errorResult();
8589 }
8590 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8591
8592 // Push a SourceParseContext on to the stack.
8593 ParseContext* outerpc = pc_;
8594 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8595 if (!funpc.init()) {
8596 return errorResult();
8597 }
8598 pc_->functionScope().useAsVarScope(pc_);
8599
8600 // Add empty parameter list.
8601 ParamsBodyNodeType argsbody;
8602 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8603 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8604 setFunctionStartAtCurrentToken(funbox);
8605 funbox->setArgCount(0);
8606
8607 // Note both the stored private method body and it's private name as being
8608 // used in the initializer. They will be emitted into the method body in the
8609 // BCE.
8610 if (!noteUsedName(storedMethodAtom)) {
8611 return errorResult();
8612 }
8613 MOZ_TRY(privateNameReference(propAtom))do { auto mozTryTempResult_ = ::mozilla::ToResult(privateNameReference
(propAtom)); if ((__builtin_expect(!!(mozTryTempResult_.isErr
()), 0))) { return mozTryTempResult_.propagateErr(); } } while
(0)
;
8614
8615 // Unlike field initializers, private method initializers are not created with
8616 // a body of synthesized AST nodes. Instead, the body is left empty and the
8617 // initializer is synthesized at the bytecode level.
8618 // See BytecodeEmitter::emitPrivateMethodInitializer.
8619 ListNodeType stmtList;
8620 MOZ_TRY_VAR(stmtList, handler_.newStatementList(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8621
8622 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8623 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8624 return errorResult();
8625 }
8626 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8627 return errorResult();
8628 }
8629
8630 LexicalScopeNodeType initializerBody;
8631 MOZ_TRY_VAR(initializerBody, finishLexicalScope(pc_->varScope(), stmtList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerBody) = mozTryVarTempResult_.unwrap
(); } while (0)
8632 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerBody) = mozTryVarTempResult_.unwrap
(); } while (0)
;
8633 handler_.setBeginPosition(initializerBody, stmtList);
8634 handler_.setEndPosition(initializerBody, stmtList);
8635 handler_.setFunctionBody(funNode, initializerBody);
8636
8637 // Set field-initializer lambda boundary to start at property name and end
8638 // after method body.
8639 setFunctionStartAtPosition(funbox, propNamePos);
8640 setFunctionEndFromCurrentToken(funbox);
8641
8642 if (!finishFunction()) {
8643 return errorResult();
8644 }
8645
8646 if (!leaveInnerFunction(outerpc)) {
8647 return errorResult();
8648 }
8649
8650 return funNode;
8651}
8652
8653template <class ParseHandler, typename Unit>
8654typename ParseHandler::FunctionNodeResult
8655GeneralParser<ParseHandler, Unit>::staticClassBlock(
8656 ClassInitializedMembers& classInitializedMembers) {
8657 // Both for getting-this-done, and because this will invariably be executed,
8658 // syntax parsing should be aborted.
8659 if (!abortIfSyntaxParser()) {
8660 return errorResult();
8661 }
8662
8663 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::StaticClassBlock;
8664 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8665 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8666 bool isSelfHosting = options().selfHostingMode;
8667 FunctionFlags flags =
8668 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8669
8670 AutoAwaitIsKeyword awaitIsKeyword(this, AwaitHandling::AwaitIsDisallowed);
8671
8672 // Create the function node for the static class body.
8673 FunctionNodeType funNode;
8674 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8675
8676 // Create the FunctionBox and link it to the function object.
8677 Directives directives(true);
8678 FunctionBox* funbox =
8679 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags, pos().begin,
8680 directives, generatorKind, asyncKind);
8681 if (!funbox) {
8682 return errorResult();
8683 }
8684 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8685 MOZ_ASSERT(funbox->isSyntheticFunction())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isSyntheticFunction())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isSyntheticFunction
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isSyntheticFunction()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8685); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isSyntheticFunction()"
")"); do { *((volatile int*)__null) = 8685; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8686 MOZ_ASSERT(!funbox->allowSuperCall())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!funbox->allowSuperCall())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!funbox->allowSuperCall()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!funbox->allowSuperCall()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8686); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowSuperCall()"
")"); do { *((volatile int*)__null) = 8686; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8687 MOZ_ASSERT(!funbox->allowArguments())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!funbox->allowArguments())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!funbox->allowArguments()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!funbox->allowArguments()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8687); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowArguments()"
")"); do { *((volatile int*)__null) = 8687; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8688 MOZ_ASSERT(!funbox->allowReturn())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!funbox->allowReturn())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!funbox->allowReturn())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("!funbox->allowReturn()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8688); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowReturn()"
")"); do { *((volatile int*)__null) = 8688; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8689
8690 // Set start at `static` token.
8691 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Static))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Static))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Static)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Static)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8691); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Static)"
")"); do { *((volatile int*)__null) = 8691; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8692 setFunctionStartAtCurrentToken(funbox);
8693
8694 // Push a SourceParseContext on to the stack.
8695 ParseContext* outerpc = pc_;
8696 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8697 if (!funpc.init()) {
8698 return errorResult();
8699 }
8700
8701 pc_->functionScope().useAsVarScope(pc_);
8702
8703 uint32_t start = pos().begin;
8704
8705 tokenStream.consumeKnownToken(TokenKind::LeftCurly);
8706
8707 // Static class blocks are code-generated as if they were static field
8708 // initializers, so we bump the staticFields count here, which ensures
8709 // .staticInitializers is noted as used.
8710 classInitializedMembers.staticFields++;
8711
8712 LexicalScopeNodeType body;
8713 MOZ_TRY_VAR(body,do { auto mozTryVarTempResult_ = (functionBody(InHandling::InAllowed
, YieldHandling::YieldIsKeyword, syntaxKind, FunctionBodyType
::StatementListBody)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (body) = mozTryVarTempResult_.unwrap(); } while (0)
8714 functionBody(InHandling::InAllowed, YieldHandling::YieldIsKeyword,do { auto mozTryVarTempResult_ = (functionBody(InHandling::InAllowed
, YieldHandling::YieldIsKeyword, syntaxKind, FunctionBodyType
::StatementListBody)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (body) = mozTryVarTempResult_.unwrap(); } while (0)
8715 syntaxKind, FunctionBodyType::StatementListBody))do { auto mozTryVarTempResult_ = (functionBody(InHandling::InAllowed
, YieldHandling::YieldIsKeyword, syntaxKind, FunctionBodyType
::StatementListBody)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (body) = mozTryVarTempResult_.unwrap(); } while (0)
;
8716
8717 if (anyChars.isEOF()) {
8718 error(JSMSG_UNTERMINATED_STATIC_CLASS_BLOCK);
8719 return errorResult();
8720 }
8721
8722 tokenStream.consumeKnownToken(TokenKind::RightCurly,
8723 TokenStream::Modifier::SlashIsRegExp);
8724
8725 TokenPos wholeBodyPos(start, pos().end);
8726
8727 handler_.setEndPosition(funNode, wholeBodyPos.end);
8728 setFunctionEndFromCurrentToken(funbox);
8729
8730 // Create a ParamsBodyNode for the parameters + body (there are no
8731 // parameters).
8732 ParamsBodyNodeType argsbody;
8733 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(wholeBodyPos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(wholeBodyPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8734
8735 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8736 funbox->setArgCount(0);
8737
8738 if (pc_->superScopeNeedsHomeObject()) {
8739 funbox->setNeedsHomeObject();
8740 }
8741
8742 handler_.setEndPosition(body, pos().begin);
8743 handler_.setEndPosition(funNode, pos().end);
8744 handler_.setFunctionBody(funNode, body);
8745
8746 if (!finishFunction()) {
8747 return errorResult();
8748 }
8749
8750 if (!leaveInnerFunction(outerpc)) {
8751 return errorResult();
8752 }
8753
8754 return funNode;
8755}
8756
8757template <class ParseHandler, typename Unit>
8758typename ParseHandler::FunctionNodeResult
8759GeneralParser<ParseHandler, Unit>::fieldInitializerOpt(
8760 TokenPos propNamePos, Node propName, TaggedParserAtomIndex propAtom,
8761 ClassInitializedMembers& classInitializedMembers, bool isStatic,
8762 HasHeritage hasHeritage) {
8763 if (!abortIfSyntaxParser()) {
8764 return errorResult();
8765 }
8766
8767 bool hasInitializer = false;
8768 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
8769 TokenStream::SlashIsDiv)) {
8770 return errorResult();
8771 }
8772
8773 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer;
8774 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8775 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8776 bool isSelfHosting = options().selfHostingMode;
8777 FunctionFlags flags =
8778 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8779
8780 // Create the top-level field initializer node.
8781 FunctionNodeType funNode;
8782 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8783
8784 // Create the FunctionBox and link it to the function object.
8785 Directives directives(true);
8786 FunctionBox* funbox =
8787 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
8788 propNamePos.begin, directives, generatorKind, asyncKind);
8789 if (!funbox) {
8790 return errorResult();
8791 }
8792 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8793 MOZ_ASSERT(funbox->isSyntheticFunction())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isSyntheticFunction())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isSyntheticFunction
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isSyntheticFunction()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8793); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isSyntheticFunction()"
")"); do { *((volatile int*)__null) = 8793; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8794
8795 // We can't use setFunctionStartAtCurrentToken because that uses pos().begin,
8796 // which is incorrect for fields without initializers (pos() points to the
8797 // field identifier)
8798 setFunctionStartAtPosition(funbox, propNamePos);
8799
8800 // Push a SourceParseContext on to the stack.
8801 ParseContext* outerpc = pc_;
8802 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8803 if (!funpc.init()) {
8804 return errorResult();
8805 }
8806
8807 pc_->functionScope().useAsVarScope(pc_);
8808
8809 Node initializerExpr;
8810 if (hasInitializer) {
8811 // Parse the expression for the field initializer.
8812 {
8813 AutoAwaitIsKeyword awaitHandling(this, AwaitIsName);
8814 MOZ_TRY_VAR(initializerExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, YieldIsName
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerExpr) = mozTryVarTempResult_.unwrap(); } while
(0)
8815 assignExpr(InAllowed, YieldIsName, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, YieldIsName
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerExpr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
8816 }
8817
8818 handler_.checkAndSetIsDirectRHSAnonFunction(initializerExpr);
8819 } else {
8820 MOZ_TRY_VAR(initializerExpr, handler_.newRawUndefinedLiteral(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newRawUndefinedLiteral
(propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerExpr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
8821 }
8822
8823 TokenPos wholeInitializerPos(propNamePos.begin, pos().end);
8824
8825 // Update the end position of the parse node.
8826 handler_.setEndPosition(funNode, wholeInitializerPos.end);
8827 setFunctionEndFromCurrentToken(funbox);
8828
8829 // Create a ParamsBodyNode for the parameters + body (there are no
8830 // parameters).
8831 ParamsBodyNodeType argsbody;
8832 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(wholeInitializerPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8833 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8834 funbox->setArgCount(0);
8835
8836 NameNodeType thisName;
8837 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
8838
8839 // Build `this.field` expression.
8840 ThisLiteralType propAssignThis;
8841 MOZ_TRY_VAR(propAssignThis,do { auto mozTryVarTempResult_ = (handler_.newThisLiteral(wholeInitializerPos
, thisName)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propAssignThis
) = mozTryVarTempResult_.unwrap(); } while (0)
8842 handler_.newThisLiteral(wholeInitializerPos, thisName))do { auto mozTryVarTempResult_ = (handler_.newThisLiteral(wholeInitializerPos
, thisName)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propAssignThis
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8843
8844 Node propAssignFieldAccess;
8845 uint32_t indexValue;
8846 if (!propAtom) {
8847 // See BytecodeEmitter::emitCreateFieldKeys for an explanation of what
8848 // .fieldKeys means and its purpose.
8849 NameNodeType fieldKeysName;
8850 if (isStatic) {
8851 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8852 fieldKeysName,do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8853 newInternalDotName(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8854 TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_()))do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
8855 } else {
8856 MOZ_TRY_VAR(fieldKeysName,do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_fieldKeys_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fieldKeysName) = mozTryVarTempResult_.unwrap(); } while (
0)
8857 newInternalDotName(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_fieldKeys_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fieldKeysName) = mozTryVarTempResult_.unwrap(); } while (
0)
8858 TaggedParserAtomIndex::WellKnown::dot_fieldKeys_()))do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_fieldKeys_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fieldKeysName) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8859 }
8860 if (!fieldKeysName) {
8861 return errorResult();
8862 }
8863
8864 double fieldKeyIndex;
8865 if (isStatic) {
8866 fieldKeyIndex = classInitializedMembers.staticFieldKeys++;
8867 } else {
8868 fieldKeyIndex = classInitializedMembers.instanceFieldKeys++;
8869 }
8870 Node fieldKeyIndexNode;
8871 MOZ_TRY_VAR(fieldKeyIndexNode,do { auto mozTryVarTempResult_ = (handler_.newNumber(fieldKeyIndex
, DecimalPoint::NoDecimal, wholeInitializerPos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeyIndexNode) = mozTryVarTempResult_
.unwrap(); } while (0)
8872 handler_.newNumber(fieldKeyIndex, DecimalPoint::NoDecimal,do { auto mozTryVarTempResult_ = (handler_.newNumber(fieldKeyIndex
, DecimalPoint::NoDecimal, wholeInitializerPos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeyIndexNode) = mozTryVarTempResult_
.unwrap(); } while (0)
8873 wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newNumber(fieldKeyIndex
, DecimalPoint::NoDecimal, wholeInitializerPos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeyIndexNode) = mozTryVarTempResult_
.unwrap(); } while (0)
;
8874
8875 Node fieldKeyValue;
8876 MOZ_TRY_VAR(fieldKeyValue,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(fieldKeysName, fieldKeyIndexNode, wholeInitializerPos.end));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (fieldKeyValue
) = mozTryVarTempResult_.unwrap(); } while (0)
8877 handler_.newPropertyByValue(fieldKeysName, fieldKeyIndexNode,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(fieldKeysName, fieldKeyIndexNode, wholeInitializerPos.end));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (fieldKeyValue
) = mozTryVarTempResult_.unwrap(); } while (0)
8878 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(fieldKeysName, fieldKeyIndexNode, wholeInitializerPos.end));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (fieldKeyValue
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8879
8880 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, fieldKeyValue, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8881 handler_.newPropertyByValue(propAssignThis, fieldKeyValue,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, fieldKeyValue, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8882 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, fieldKeyValue, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8883 } else if (handler_.isPrivateName(propName)) {
8884 // It would be nice if we could tweak this here such that only if
8885 // HasHeritage::Yes we end up emitting CheckPrivateField, but otherwise we
8886 // emit InitElem -- this is an optimization to minimize HasOwn checks
8887 // in InitElem for classes without heritage.
8888 //
8889 // Further tweaking would be to ultimately only do CheckPrivateField for the
8890 // -first- field in a derived class, which would suffice to match the
8891 // semantic check.
8892
8893 NameNodeType privateNameNode;
8894 MOZ_TRY_VAR(privateNameNode, privateNameReference(propAtom))do { auto mozTryVarTempResult_ = (privateNameReference(propAtom
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (privateNameNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8895
8896 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
(propAssignThis, privateNameNode, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8897 handler_.newPrivateMemberAccess(propAssignThis, privateNameNode,do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
(propAssignThis, privateNameNode, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8898 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
(propAssignThis, privateNameNode, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8899 } else if (this->parserAtoms().isIndex(propAtom, &indexValue)) {
8900 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, propName, wholeInitializerPos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propAssignFieldAccess) = mozTryVarTempResult_
.unwrap(); } while (0)
8901 handler_.newPropertyByValue(propAssignThis, propName,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, propName, wholeInitializerPos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propAssignFieldAccess) = mozTryVarTempResult_
.unwrap(); } while (0)
8902 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, propName, wholeInitializerPos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propAssignFieldAccess) = mozTryVarTempResult_
.unwrap(); } while (0)
;
8903 } else {
8904 NameNodeType propAssignName;
8905 MOZ_TRY_VAR(propAssignName,do { auto mozTryVarTempResult_ = (handler_.newPropertyName(propAtom
, wholeInitializerPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignName) = mozTryVarTempResult_.unwrap(); } while (
0)
8906 handler_.newPropertyName(propAtom, wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newPropertyName(propAtom
, wholeInitializerPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignName) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8907
8908 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPropertyAccess(
propAssignThis, propAssignName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignFieldAccess) = mozTryVarTempResult_.unwrap(); }
while (0)
8909 handler_.newPropertyAccess(propAssignThis, propAssignName))do { auto mozTryVarTempResult_ = (handler_.newPropertyAccess(
propAssignThis, propAssignName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignFieldAccess) = mozTryVarTempResult_.unwrap(); }
while (0)
;
8910 }
8911
8912 // Synthesize an property init.
8913 BinaryNodeType initializerPropInit;
8914 MOZ_TRY_VAR(initializerPropInit,do { auto mozTryVarTempResult_ = (handler_.newInitExpr(propAssignFieldAccess
, initializerExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerPropInit) = mozTryVarTempResult_.unwrap(); } while
(0)
8915 handler_.newInitExpr(propAssignFieldAccess, initializerExpr))do { auto mozTryVarTempResult_ = (handler_.newInitExpr(propAssignFieldAccess
, initializerExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerPropInit) = mozTryVarTempResult_.unwrap(); } while
(0)
;
8916
8917 UnaryNodeType exprStatement;
8918 MOZ_TRY_VAR(exprStatement, handler_.newExprStatement(do { auto mozTryVarTempResult_ = (handler_.newExprStatement( initializerPropInit
, wholeInitializerPos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprStatement) = mozTryVarTempResult_.unwrap(); } while (
0)
8919 initializerPropInit, wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newExprStatement( initializerPropInit
, wholeInitializerPos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprStatement) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8920
8921 ListNodeType statementList;
8922 MOZ_TRY_VAR(statementList, handler_.newStatementList(wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(wholeInitializerPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (statementList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8923 handler_.addStatementToList(statementList, exprStatement);
8924
8925 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8926 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8927 return errorResult();
8928 }
8929 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8930 return errorResult();
8931 }
8932
8933 // Set the function's body to the field assignment.
8934 LexicalScopeNodeType initializerBody;
8935 MOZ_TRY_VAR(initializerBody,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
8936 finishLexicalScope(pc_->varScope(), statementList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
8937 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
;
8938
8939 handler_.setFunctionBody(funNode, initializerBody);
8940
8941 if (pc_->superScopeNeedsHomeObject()) {
8942 funbox->setNeedsHomeObject();
8943 }
8944
8945 if (!finishFunction()) {
8946 return errorResult();
8947 }
8948
8949 if (!leaveInnerFunction(outerpc)) {
8950 return errorResult();
8951 }
8952
8953 return funNode;
8954}
8955
8956template <class ParseHandler, typename Unit>
8957typename ParseHandler::FunctionNodeResult
8958GeneralParser<ParseHandler, Unit>::synthesizePrivateMethodInitializer(
8959 TaggedParserAtomIndex propAtom, AccessorType accessorType,
8960 TokenPos propNamePos) {
8961 if (!abortIfSyntaxParser()) {
8962 return errorResult();
8963 }
8964
8965 // Synthesize a name for the lexical variable that will store the
8966 // accessor body.
8967 StringBuffer storedMethodName(fc_);
8968 if (!storedMethodName.append(this->parserAtoms(), propAtom)) {
8969 return errorResult();
8970 }
8971 if (!storedMethodName.append(
8972 accessorType == AccessorType::Getter ? ".getter" : ".setter")) {
8973 return errorResult();
8974 }
8975 auto storedMethodProp =
8976 storedMethodName.finishParserAtom(this->parserAtoms(), fc_);
8977 if (!storedMethodProp) {
8978 return errorResult();
8979 }
8980 if (!noteDeclaredName(storedMethodProp, DeclarationKind::Synthetic, pos())) {
8981 return errorResult();
8982 }
8983
8984 return privateMethodInitializer(propNamePos, propAtom, storedMethodProp);
8985}
8986
8987#ifdef ENABLE_DECORATORS
8988template <class ParseHandler, typename Unit>
8989typename ParseHandler::FunctionNodeResult
8990GeneralParser<ParseHandler, Unit>::synthesizeAddInitializerFunction(
8991 TaggedParserAtomIndex initializers, YieldHandling yieldHandling) {
8992 if (!abortIfSyntaxParser()) {
8993 return errorResult();
8994 }
8995
8996 // TODO: Add support for static and class extra initializers, see bug 1868220
8997 // and bug 1868221.
8998 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9000); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9000; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
8999 initializers ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9000); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9000; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9000 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9000); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9000; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9001
9002 TokenPos propNamePos = pos();
9003
9004 // Synthesize an addInitializer function that can be used to append to
9005 // .initializers
9006 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
9007 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
9008 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
9009 bool isSelfHosting = options().selfHostingMode;
9010 FunctionFlags flags =
9011 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
9012
9013 FunctionNodeType funNode;
9014 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
9015
9016 Directives directives(true);
9017 FunctionBox* funbox =
9018 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
9019 propNamePos.begin, directives, generatorKind, asyncKind);
9020 if (!funbox) {
9021 return errorResult();
9022 }
9023 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
9024
9025 ParseContext* outerpc = pc_;
9026 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
9027 if (!funpc.init()) {
9028 return errorResult();
9029 }
9030 pc_->functionScope().useAsVarScope(pc_);
9031
9032 // Takes a single parameter, `initializer`.
9033 ParamsBodyNodeType params;
9034 MOZ_TRY_VAR(params, handler_.newParamsBody(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (params) =
mozTryVarTempResult_.unwrap(); } while (0)
;
9035
9036 handler_.setFunctionFormalParametersAndBody(funNode, params);
9037
9038 constexpr bool disallowDuplicateParams = true;
9039 bool duplicatedParam = false;
9040 if (!notePositionalFormalParameter(
9041 funNode, TaggedParserAtomIndex::WellKnown::initializer(), pos().begin,
9042 disallowDuplicateParams, &duplicatedParam)) {
9043 return null();
9044 }
9045 MOZ_ASSERT(!duplicatedParam)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!duplicatedParam)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!duplicatedParam))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!duplicatedParam"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9045); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!duplicatedParam"
")"); do { *((volatile int*)__null) = 9045; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9046 MOZ_ASSERT(pc_->positionalFormalParameterNames().length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->positionalFormalParameterNames().length() ==
1)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->positionalFormalParameterNames().length() ==
1))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->positionalFormalParameterNames().length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9046); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->positionalFormalParameterNames().length() == 1"
")"); do { *((volatile int*)__null) = 9046; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9047
9048 funbox->setLength(1);
9049 funbox->setArgCount(1);
9050 setFunctionStartAtCurrentToken(funbox);
9051
9052 // Like private method initializers, the addInitializer method is not created
9053 // with a body of synthesized AST nodes. Instead, the body is left empty and
9054 // the initializer is synthesized at the bytecode level. See
9055 // DecoratorEmitter::emitCreateAddInitializerFunction.
9056 ListNodeType stmtList;
9057 MOZ_TRY_VAR(stmtList, handler_.newStatementList(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9058
9059 if (!noteUsedName(initializers)) {
9060 return null();
9061 }
9062
9063 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
9064 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
9065 return null();
9066 }
9067 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
9068 return null();
9069 }
9070
9071 LexicalScopeNodeType addInitializerBody;
9072 MOZ_TRY_VAR(addInitializerBody,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (addInitializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9073 finishLexicalScope(pc_->varScope(), stmtList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (addInitializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9074 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (addInitializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
;
9075 handler_.setBeginPosition(addInitializerBody, stmtList);
9076 handler_.setEndPosition(addInitializerBody, stmtList);
9077 handler_.setFunctionBody(funNode, addInitializerBody);
9078
9079 // Set field-initializer lambda boundary to start at property name and end
9080 // after method body.
9081 setFunctionStartAtPosition(funbox, propNamePos);
9082 setFunctionEndFromCurrentToken(funbox);
9083
9084 if (!finishFunction()) {
9085 return errorResult();
9086 }
9087
9088 if (!leaveInnerFunction(outerpc)) {
9089 return errorResult();
9090 }
9091
9092 return funNode;
9093}
9094
9095template <class ParseHandler, typename Unit>
9096typename ParseHandler::ClassMethodResult
9097GeneralParser<ParseHandler, Unit>::synthesizeAccessor(
9098 Node propName, TokenPos propNamePos, TaggedParserAtomIndex propAtom,
9099 TaggedParserAtomIndex privateStateNameAtom, bool isStatic,
9100 FunctionSyntaxKind syntaxKind,
9101 ClassInitializedMembers& classInitializedMembers) {
9102 // Decorators Proposal
9103 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9104 // The abstract operation MakeAutoAccessorGetter takes arguments homeObject
9105 // (an Object), name (a property key or Private Name), and privateStateName (a
9106 // Private Name) and returns a function object.
9107 //
9108 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9109 // The abstract operation MakeAutoAccessorSetter takes arguments homeObject
9110 // (an Object), name (a property key or Private Name), and privateStateName (a
9111 // Private Name) and returns a function object.
9112 if (!abortIfSyntaxParser()) {
9113 return errorResult();
9114 }
9115
9116 AccessorType accessorType = syntaxKind == FunctionSyntaxKind::Getter
9117 ? AccessorType::Getter
9118 : AccessorType::Setter;
9119
9120 mozilla::Maybe<FunctionNodeType> initializerIfPrivate = Nothing();
9121 if (!isStatic && handler_.isPrivateName(propName)) {
9122 classInitializedMembers.privateAccessors++;
9123 FunctionNodeType initializerNode;
9124 MOZ_TRY_VAR(initializerNode, synthesizePrivateMethodInitializer(do { auto mozTryVarTempResult_ = (synthesizePrivateMethodInitializer
( propAtom, accessorType, propNamePos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerNode) = mozTryVarTempResult_.unwrap
(); } while (0)
9125 propAtom, accessorType, propNamePos))do { auto mozTryVarTempResult_ = (synthesizePrivateMethodInitializer
( propAtom, accessorType, propNamePos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerNode) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9126 initializerIfPrivate = Some(initializerNode);
9127 handler_.setPrivateNameKind(propName, PrivateNameKind::GetterSetter);
9128 }
9129
9130 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9131 // 2. Let getter be CreateBuiltinFunction(getterClosure, 0, "get", « »).
9132 //
9133 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9134 // 2. Let setter be CreateBuiltinFunction(setterClosure, 1, "set", « »).
9135 StringBuffer storedMethodName(fc_);
9136 if (!storedMethodName.append(accessorType == AccessorType::Getter ? "get"
9137 : "set")) {
9138 return errorResult();
9139 }
9140 TaggedParserAtomIndex funNameAtom =
9141 storedMethodName.finishParserAtom(this->parserAtoms(), fc_);
9142
9143 FunctionNodeType funNode;
9144 MOZ_TRY_VAR(funNode,do { auto mozTryVarTempResult_ = (synthesizeAccessorBody(funNameAtom
, propNamePos, privateStateNameAtom, syntaxKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (funNode) = mozTryVarTempResult_.unwrap();
} while (0)
9145 synthesizeAccessorBody(funNameAtom, propNamePos,do { auto mozTryVarTempResult_ = (synthesizeAccessorBody(funNameAtom
, propNamePos, privateStateNameAtom, syntaxKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (funNode) = mozTryVarTempResult_.unwrap();
} while (0)
9146 privateStateNameAtom, syntaxKind))do { auto mozTryVarTempResult_ = (synthesizeAccessorBody(funNameAtom
, propNamePos, privateStateNameAtom, syntaxKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (funNode) = mozTryVarTempResult_.unwrap();
} while (0)
;
9147
9148 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9149 // 3. Perform MakeMethod(getter, homeObject).
9150 // 4. Return getter.
9151 //
9152 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9153 // 3. Perform MakeMethod(setter, homeObject).
9154 // 4. Return setter.
9155 return handler_.newClassMethodDefinition(
9156 propName, funNode, accessorType, isStatic, initializerIfPrivate, null());
9157}
9158
9159template <class ParseHandler, typename Unit>
9160typename ParseHandler::FunctionNodeResult
9161GeneralParser<ParseHandler, Unit>::synthesizeAccessorBody(
9162 TaggedParserAtomIndex funNameAtom, TokenPos propNamePos,
9163 TaggedParserAtomIndex propNameAtom, FunctionSyntaxKind syntaxKind) {
9164 if (!abortIfSyntaxParser()) {
9165 return errorResult();
9166 }
9167
9168 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
9169 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
9170 bool isSelfHosting = options().selfHostingMode;
9171 FunctionFlags flags =
9172 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
9173
9174 // Create the top-level function node.
9175 FunctionNodeType funNode;
9176 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
9177
9178 // Create the FunctionBox and link it to the function object.
9179 Directives directives(true);
9180 FunctionBox* funbox =
9181 newFunctionBox(funNode, funNameAtom, flags, propNamePos.begin, directives,
9182 generatorKind, asyncKind);
9183 if (!funbox) {
9184 return errorResult();
9185 }
9186 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
9187 funbox->setSyntheticFunction();
9188
9189 // Push a SourceParseContext on to the stack.
9190 ParseContext* outerpc = pc_;
9191 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
9192 if (!funpc.init()) {
9193 return errorResult();
9194 }
9195
9196 pc_->functionScope().useAsVarScope(pc_);
9197
9198 // The function we synthesize is located at the field with the
9199 // accessor.
9200 setFunctionStartAtCurrentToken(funbox);
9201 setFunctionEndFromCurrentToken(funbox);
9202
9203 // Create a ListNode for the parameters + body
9204 ParamsBodyNodeType paramsbody;
9205 MOZ_TRY_VAR(paramsbody, handler_.newParamsBody(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (paramsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9206 handler_.setFunctionFormalParametersAndBody(funNode, paramsbody);
9207
9208 if (syntaxKind == FunctionSyntaxKind::Getter) {
9209 funbox->setArgCount(0);
9210 } else {
9211 funbox->setArgCount(1);
9212 }
9213
9214 // Build `this` expression to access the privateStateName for use in the
9215 // operations to create the getter and setter below.
9216 NameNodeType thisName;
9217 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
9218
9219 ThisLiteralType propThis;
9220 MOZ_TRY_VAR(propThis, handler_.newThisLiteral(propNamePos, thisName))do { auto mozTryVarTempResult_ = (handler_.newThisLiteral(propNamePos
, thisName)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propThis
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9221
9222 NameNodeType privateNameNode;
9223 MOZ_TRY_VAR(privateNameNode, privateNameReference(propNameAtom))do { auto mozTryVarTempResult_ = (privateNameReference(propNameAtom
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (privateNameNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9224
9225 Node propFieldAccess;
9226 MOZ_TRY_VAR(propFieldAccess, handler_.newPrivateMemberAccess(do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
( propThis, privateNameNode, propNamePos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propFieldAccess) = mozTryVarTempResult_.unwrap
(); } while (0)
9227 propThis, privateNameNode, propNamePos.end))do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
( propThis, privateNameNode, propNamePos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propFieldAccess) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9228
9229 Node accessorBody;
9230 if (syntaxKind == FunctionSyntaxKind::Getter) {
9231 // Decorators Proposal
9232 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9233 // 1. Let getterClosure be a new Abstract Closure with no parameters that
9234 // captures privateStateName and performs the following steps when called:
9235 // 1.a. Let o be the this value.
9236 // 1.b. Return ? PrivateGet(privateStateName, o).
9237 MOZ_TRY_VAR(accessorBody,do { auto mozTryVarTempResult_ = (handler_.newReturnStatement
(propFieldAccess, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
9238 handler_.newReturnStatement(propFieldAccess, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newReturnStatement
(propFieldAccess, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
;
9239 } else {
9240 // Decorators Proposal
9241 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9242 // The abstract operation MakeAutoAccessorSetter takes arguments homeObject
9243 // (an Object), name (a property key or Private Name), and privateStateName
9244 // (a Private Name) and returns a function object.
9245 // 1. Let setterClosure be a new Abstract Closure with parameters (value)
9246 // that captures privateStateName and performs the following steps when
9247 // called:
9248 // 1.a. Let o be the this value.
9249 notePositionalFormalParameter(funNode,
9250 TaggedParserAtomIndex::WellKnown::value(),
9251 /* pos = */ 0, false,
9252 /* duplicatedParam = */ nullptr);
9253
9254 Node initializerExpr;
9255 MOZ_TRY_VAR(initializerExpr,do { auto mozTryVarTempResult_ = (handler_.newName(TaggedParserAtomIndex
::WellKnown::value(), propNamePos)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerExpr) = mozTryVarTempResult_.unwrap
(); } while (0)
9256 handler_.newName(TaggedParserAtomIndex::WellKnown::value(),do { auto mozTryVarTempResult_ = (handler_.newName(TaggedParserAtomIndex
::WellKnown::value(), propNamePos)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerExpr) = mozTryVarTempResult_.unwrap
(); } while (0)
9257 propNamePos))do { auto mozTryVarTempResult_ = (handler_.newName(TaggedParserAtomIndex
::WellKnown::value(), propNamePos)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerExpr) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9258
9259 // 1.b. Perform ? PrivateSet(privateStateName, o, value).
9260 Node assignment;
9261 MOZ_TRY_VAR(assignment,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, propFieldAccess, initializerExpr)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (assignment) = mozTryVarTempResult_.unwrap
(); } while (0)
9262 handler_.newAssignment(ParseNodeKind::AssignExpr,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, propFieldAccess, initializerExpr)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (assignment) = mozTryVarTempResult_.unwrap
(); } while (0)
9263 propFieldAccess, initializerExpr))do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, propFieldAccess, initializerExpr)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (assignment) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9264
9265 MOZ_TRY_VAR(accessorBody,do { auto mozTryVarTempResult_ = (handler_.newExprStatement(assignment
, propNamePos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
9266 handler_.newExprStatement(assignment, propNamePos.end))do { auto mozTryVarTempResult_ = (handler_.newExprStatement(assignment
, propNamePos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
;
9267
9268 // 1.c. Return undefined.
9269 }
9270
9271 ListNodeType statementList;
9272 MOZ_TRY_VAR(statementList, handler_.newStatementList(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (statementList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9273 handler_.addStatementToList(statementList, accessorBody);
9274
9275 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
9276 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
9277 return errorResult();
9278 }
9279 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
9280 return errorResult();
9281 }
9282
9283 LexicalScopeNodeType initializerBody;
9284 MOZ_TRY_VAR(initializerBody,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9285 finishLexicalScope(pc_->varScope(), statementList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9286 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
;
9287
9288 handler_.setFunctionBody(funNode, initializerBody);
9289
9290 if (pc_->superScopeNeedsHomeObject()) {
9291 funbox->setNeedsHomeObject();
9292 }
9293
9294 if (!finishFunction()) {
9295 return errorResult();
9296 }
9297
9298 if (!leaveInnerFunction(outerpc)) {
9299 return errorResult();
9300 }
9301
9302 return funNode;
9303}
9304
9305#endif
9306
9307bool ParserBase::nextTokenContinuesLetDeclaration(TokenKind next) {
9308 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Let))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Let))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Let)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Let)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9308); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 9308; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9309 MOZ_ASSERT(anyChars.nextToken().type == next)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.nextToken().type == next)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.nextToken().type ==
next))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.nextToken().type == next", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9309); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.nextToken().type == next"
")"); do { *((volatile int*)__null) = 9309; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9310
9311 TokenStreamShared::verifyConsistentModifier(TokenStreamShared::SlashIsDiv,
9312 anyChars.nextToken());
9313
9314 // Destructuring continues a let declaration.
9315 if (next == TokenKind::LeftBracket || next == TokenKind::LeftCurly) {
9316 return true;
9317 }
9318
9319 // A "let" edge case deserves special comment. Consider this:
9320 //
9321 // let // not an ASI opportunity
9322 // let;
9323 //
9324 // Static semantics in §13.3.1.1 turn a LexicalDeclaration that binds
9325 // "let" into an early error. Does this retroactively permit ASI so
9326 // that we should parse this as two ExpressionStatements? No. ASI
9327 // resolves during parsing. Static semantics only apply to the full
9328 // parse tree with ASI applied. No backsies!
9329
9330 // Otherwise a let declaration must have a name.
9331 return TokenKindIsPossibleIdentifier(next);
9332}
9333
9334template <class ParseHandler, typename Unit>
9335typename ParseHandler::DeclarationListNodeResult
9336GeneralParser<ParseHandler, Unit>::variableStatement(
9337 YieldHandling yieldHandling) {
9338 DeclarationListNodeType vars;
9339 MOZ_TRY_VAR(vars, declarationList(yieldHandling, ParseNodeKind::VarStmt))do { auto mozTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (vars) = mozTryVarTempResult_.unwrap(); } while (0)
;
9340 if (!matchOrInsertSemicolon()) {
9341 return errorResult();
9342 }
9343 return vars;
9344}
9345
9346template <class ParseHandler, typename Unit>
9347typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::statement(
9348 YieldHandling yieldHandling) {
9349 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 9349; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9350
9351 AutoCheckRecursionLimit recursion(this->fc_);
9352 if (!recursion.check(this->fc_)) {
9353 return errorResult();
9354 }
9355
9356 TokenKind tt;
9357 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
9358 return errorResult();
9359 }
9360
9361 switch (tt) {
9362 // BlockStatement[?Yield, ?Return]
9363 case TokenKind::LeftCurly:
9364 return blockStatement(yieldHandling);
9365
9366 // VariableStatement[?Yield]
9367 case TokenKind::Var:
9368 return variableStatement(yieldHandling);
9369
9370 // EmptyStatement
9371 case TokenKind::Semi:
9372 return handler_.newEmptyStatement(pos());
9373
9374 // ExpressionStatement[?Yield].
9375
9376 case TokenKind::Yield: {
9377 // Don't use a ternary operator here due to obscure linker issues
9378 // around using static consts in the arms of a ternary.
9379 Modifier modifier;
9380 if (yieldExpressionsSupported()) {
9381 modifier = TokenStream::SlashIsRegExp;
9382 } else {
9383 modifier = TokenStream::SlashIsDiv;
9384 }
9385
9386 TokenKind next;
9387 if (!tokenStream.peekToken(&next, modifier)) {
9388 return errorResult();
9389 }
9390
9391 if (next == TokenKind::Colon) {
9392 return labeledStatement(yieldHandling);
9393 }
9394
9395 return expressionStatement(yieldHandling);
9396 }
9397
9398 default: {
9399 // If we encounter an await in a module, and the module is not marked
9400 // as async, mark the module as async.
9401 if (tt == TokenKind::Await && !pc_->isAsync()) {
9402 if (pc_->atModuleTopLevel()) {
9403 if (!options().topLevelAwait) {
9404 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
9405 return errorResult();
9406 }
9407 pc_->sc()->asModuleContext()->setIsAsync();
9408 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9408); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 9408; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9409 }
9410 }
9411
9412 // Avoid getting next token with SlashIsDiv.
9413 if (tt == TokenKind::Await && pc_->isAsync()) {
9414 return expressionStatement(yieldHandling);
9415 }
9416
9417 if (!TokenKindIsPossibleIdentifier(tt)) {
9418 return expressionStatement(yieldHandling);
9419 }
9420
9421 TokenKind next;
9422 if (!tokenStream.peekToken(&next)) {
9423 return errorResult();
9424 }
9425
9426 // |let| here can only be an Identifier, not a declaration. Give nicer
9427 // errors for declaration-looking typos.
9428 if (tt == TokenKind::Let) {
9429 bool forbiddenLetDeclaration = false;
9430
9431 if (next == TokenKind::LeftBracket) {
9432 // Enforce ExpressionStatement's 'let [' lookahead restriction.
9433 forbiddenLetDeclaration = true;
9434 } else if (next == TokenKind::LeftCurly ||
9435 TokenKindIsPossibleIdentifier(next)) {
9436 // 'let {' and 'let foo' aren't completely forbidden, if ASI
9437 // causes 'let' to be the entire Statement. But if they're
9438 // same-line, we can aggressively give a better error message.
9439 //
9440 // Note that this ignores 'yield' as TokenKind::Yield: we'll handle it
9441 // correctly but with a worse error message.
9442 TokenKind nextSameLine;
9443 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
9444 return errorResult();
9445 }
9446
9447 MOZ_ASSERT(TokenKindIsPossibleIdentifier(nextSameLine) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9449); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9449; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9448 nextSameLine == TokenKind::LeftCurly ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9449); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9449; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9449 nextSameLine == TokenKind::Eol)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9449); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9449; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9450
9451 forbiddenLetDeclaration = nextSameLine != TokenKind::Eol;
9452 }
9453
9454 if (forbiddenLetDeclaration) {
9455 error(JSMSG_FORBIDDEN_AS_STATEMENT, "lexical declarations");
9456 return errorResult();
9457 }
9458 } else if (tt == TokenKind::Async) {
9459 // Peek only on the same line: ExpressionStatement's lookahead
9460 // restriction is phrased as
9461 //
9462 // [lookahead ∉ { '{',
9463 // function,
9464 // async [no LineTerminator here] function,
9465 // class,
9466 // let '[' }]
9467 //
9468 // meaning that code like this is valid:
9469 //
9470 // if (true)
9471 // async // ASI opportunity
9472 // function clownshoes() {}
9473 TokenKind maybeFunction;
9474 if (!tokenStream.peekTokenSameLine(&maybeFunction)) {
9475 return errorResult();
9476 }
9477
9478 if (maybeFunction == TokenKind::Function) {
9479 error(JSMSG_FORBIDDEN_AS_STATEMENT, "async function declarations");
9480 return errorResult();
9481 }
9482
9483 // Otherwise this |async| begins an ExpressionStatement or is a
9484 // label name.
9485 }
9486
9487 // NOTE: It's unfortunately allowed to have a label named 'let' in
9488 // non-strict code. 💯
9489 if (next == TokenKind::Colon) {
9490 return labeledStatement(yieldHandling);
9491 }
9492
9493 return expressionStatement(yieldHandling);
9494 }
9495
9496 case TokenKind::New:
9497 return expressionStatement(yieldHandling, PredictInvoked);
9498
9499 // IfStatement[?Yield, ?Return]
9500 case TokenKind::If:
9501 return ifStatement(yieldHandling);
9502
9503 // BreakableStatement[?Yield, ?Return]
9504 //
9505 // BreakableStatement[Yield, Return]:
9506 // IterationStatement[?Yield, ?Return]
9507 // SwitchStatement[?Yield, ?Return]
9508 case TokenKind::Do:
9509 return doWhileStatement(yieldHandling);
9510
9511 case TokenKind::While:
9512 return whileStatement(yieldHandling);
9513
9514 case TokenKind::For:
9515 return forStatement(yieldHandling);
9516
9517 case TokenKind::Switch:
9518 return switchStatement(yieldHandling);
9519
9520 // ContinueStatement[?Yield]
9521 case TokenKind::Continue:
9522 return continueStatement(yieldHandling);
9523
9524 // BreakStatement[?Yield]
9525 case TokenKind::Break:
9526 return breakStatement(yieldHandling);
9527
9528 // [+Return] ReturnStatement[?Yield]
9529 case TokenKind::Return:
9530 // The Return parameter is only used here, and the effect is easily
9531 // detected this way, so don't bother passing around an extra parameter
9532 // everywhere.
9533 if (!pc_->allowReturn()) {
9534 error(JSMSG_BAD_RETURN_OR_YIELD, "return");
9535 return errorResult();
9536 }
9537 return returnStatement(yieldHandling);
9538
9539 // WithStatement[?Yield, ?Return]
9540 case TokenKind::With:
9541 return withStatement(yieldHandling);
9542
9543 // LabelledStatement[?Yield, ?Return]
9544 // This is really handled by default and TokenKind::Yield cases above.
9545
9546 // ThrowStatement[?Yield]
9547 case TokenKind::Throw:
9548 return throwStatement(yieldHandling);
9549
9550 // TryStatement[?Yield, ?Return]
9551 case TokenKind::Try:
9552 return tryStatement(yieldHandling);
9553
9554 // DebuggerStatement
9555 case TokenKind::Debugger:
9556 return debuggerStatement();
9557
9558 // |function| is forbidden by lookahead restriction (unless as child
9559 // statement of |if| or |else|, but Parser::consequentOrAlternative
9560 // handles that).
9561 case TokenKind::Function:
9562 error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
9563 return errorResult();
9564
9565 // |class| is also forbidden by lookahead restriction.
9566 case TokenKind::Class:
9567 error(JSMSG_FORBIDDEN_AS_STATEMENT, "classes");
9568 return errorResult();
9569
9570 // ImportDeclaration (only inside modules)
9571 case TokenKind::Import:
9572 return importDeclarationOrImportExpr(yieldHandling);
9573
9574 // ExportDeclaration (only inside modules)
9575 case TokenKind::Export:
9576 return exportDeclaration();
9577
9578 // Miscellaneous error cases arguably better caught here than elsewhere.
9579
9580 case TokenKind::Catch:
9581 error(JSMSG_CATCH_WITHOUT_TRY);
9582 return errorResult();
9583
9584 case TokenKind::Finally:
9585 error(JSMSG_FINALLY_WITHOUT_TRY);
9586 return errorResult();
9587
9588 // NOTE: default case handled in the ExpressionStatement section.
9589 }
9590}
9591
9592template <class ParseHandler, typename Unit>
9593typename ParseHandler::NodeResult
9594GeneralParser<ParseHandler, Unit>::statementListItem(
9595 YieldHandling yieldHandling, bool canHaveDirectives /* = false */) {
9596 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 9596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9597
9598 AutoCheckRecursionLimit recursion(this->fc_);
9599 if (!recursion.check(this->fc_)) {
9600 return errorResult();
9601 }
9602
9603 TokenKind tt;
9604 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
9605 return errorResult();
9606 }
9607
9608 switch (tt) {
9609 // BlockStatement[?Yield, ?Return]
9610 case TokenKind::LeftCurly:
9611 return blockStatement(yieldHandling);
9612
9613 // VariableStatement[?Yield]
9614 case TokenKind::Var:
9615 return variableStatement(yieldHandling);
9616
9617 // EmptyStatement
9618 case TokenKind::Semi:
9619 return handler_.newEmptyStatement(pos());
9620
9621 // ExpressionStatement[?Yield].
9622 //
9623 // These should probably be handled by a single ExpressionStatement
9624 // function in a default, not split up this way.
9625 case TokenKind::String:
9626 if (!canHaveDirectives &&
9627 anyChars.currentToken().atom() ==
9628 TaggedParserAtomIndex::WellKnown::use_asm_()) {
9629 if (!warning(JSMSG_USE_ASM_DIRECTIVE_FAIL)) {
9630 return errorResult();
9631 }
9632 }
9633 return expressionStatement(yieldHandling);
9634
9635 case TokenKind::Yield: {
9636 // Don't use a ternary operator here due to obscure linker issues
9637 // around using static consts in the arms of a ternary.
9638 Modifier modifier;
9639 if (yieldExpressionsSupported()) {
9640 modifier = TokenStream::SlashIsRegExp;
9641 } else {
9642 modifier = TokenStream::SlashIsDiv;
9643 }
9644
9645 TokenKind next;
9646 if (!tokenStream.peekToken(&next, modifier)) {
9647 return errorResult();
9648 }
9649
9650 if (next == TokenKind::Colon) {
9651 return labeledStatement(yieldHandling);
9652 }
9653
9654 return expressionStatement(yieldHandling);
9655 }
9656
9657 default: {
9658 // If we encounter an await in a module, and the module is not marked
9659 // as async, mark the module as async.
9660 if (tt == TokenKind::Await && !pc_->isAsync()) {
9661 if (pc_->atModuleTopLevel()) {
9662 if (!options().topLevelAwait) {
9663 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
9664 return errorResult();
9665 }
9666 pc_->sc()->asModuleContext()->setIsAsync();
9667 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9667); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 9667; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9668 }
9669 }
9670
9671 if (tt == TokenKind::Await && pc_->isAsync()) {
9672#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
9673 // Try finding evidence of a AwaitUsingDeclaration the syntax for which
9674 // would be:
9675 // await [no LineTerminator here] using [no LineTerminator here]
9676 // identifier
9677
9678 TokenKind nextTokUsing = TokenKind::Eof;
9679 // Scan with regex modifier because when its await expression, `/`
9680 // should be treated as a regexp.
9681 if (!tokenStream.peekTokenSameLine(&nextTokUsing,
9682 TokenStream::SlashIsRegExp)) {
9683 return errorResult();
9684 }
9685
9686 if (nextTokUsing == TokenKind::Using &&
9687 this->pc_->isUsingSyntaxAllowed()) {
9688 tokenStream.consumeKnownToken(nextTokUsing,
9689 TokenStream::SlashIsRegExp);
9690 TokenKind nextTokIdentifier = TokenKind::Eof;
9691 // Here we can use the Div modifier because if the next token is using
9692 // then a `/` as the next token can only be considered a division.
9693 if (!tokenStream.peekTokenSameLine(&nextTokIdentifier)) {
9694 return errorResult();
9695 }
9696 if (TokenKindIsPossibleIdentifier(nextTokIdentifier)) {
9697 return lexicalDeclaration(yieldHandling,
9698 DeclarationKind::AwaitUsing);
9699 }
9700 anyChars.ungetToken(); // put back using.
9701 }
9702#endif
9703 return expressionStatement(yieldHandling);
9704 }
9705
9706 if (!TokenKindIsPossibleIdentifier(tt)) {
9707 return expressionStatement(yieldHandling);
9708 }
9709
9710 TokenKind next;
9711 if (!tokenStream.peekToken(&next)) {
9712 return errorResult();
9713 }
9714
9715 if (tt == TokenKind::Let && nextTokenContinuesLetDeclaration(next)) {
9716 return lexicalDeclaration(yieldHandling, DeclarationKind::Let);
9717 }
9718
9719 if (tt == TokenKind::Async) {
9720 TokenKind nextSameLine = TokenKind::Eof;
9721 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
9722 return errorResult();
9723 }
9724 if (nextSameLine == TokenKind::Function) {
9725 uint32_t toStringStart = pos().begin;
9726 tokenStream.consumeKnownToken(TokenKind::Function);
9727 return functionStmt(toStringStart, yieldHandling, NameRequired,
9728 FunctionAsyncKind::AsyncFunction);
9729 }
9730 }
9731
9732 if (next == TokenKind::Colon) {
9733 return labeledStatement(yieldHandling);
9734 }
9735
9736 return expressionStatement(yieldHandling);
9737 }
9738
9739 case TokenKind::New:
9740 return expressionStatement(yieldHandling, PredictInvoked);
9741
9742 // IfStatement[?Yield, ?Return]
9743 case TokenKind::If:
9744 return ifStatement(yieldHandling);
9745
9746 // BreakableStatement[?Yield, ?Return]
9747 //
9748 // BreakableStatement[Yield, Return]:
9749 // IterationStatement[?Yield, ?Return]
9750 // SwitchStatement[?Yield, ?Return]
9751 case TokenKind::Do:
9752 return doWhileStatement(yieldHandling);
9753
9754 case TokenKind::While:
9755 return whileStatement(yieldHandling);
9756
9757 case TokenKind::For:
9758 return forStatement(yieldHandling);
9759
9760 case TokenKind::Switch:
9761 return switchStatement(yieldHandling);
9762
9763 // ContinueStatement[?Yield]
9764 case TokenKind::Continue:
9765 return continueStatement(yieldHandling);
9766
9767 // BreakStatement[?Yield]
9768 case TokenKind::Break:
9769 return breakStatement(yieldHandling);
9770
9771 // [+Return] ReturnStatement[?Yield]
9772 case TokenKind::Return:
9773 // The Return parameter is only used here, and the effect is easily
9774 // detected this way, so don't bother passing around an extra parameter
9775 // everywhere.
9776 if (!pc_->allowReturn()) {
9777 error(JSMSG_BAD_RETURN_OR_YIELD, "return");
9778 return errorResult();
9779 }
9780 return returnStatement(yieldHandling);
9781
9782 // WithStatement[?Yield, ?Return]
9783 case TokenKind::With:
9784 return withStatement(yieldHandling);
9785
9786 // LabelledStatement[?Yield, ?Return]
9787 // This is really handled by default and TokenKind::Yield cases above.
9788
9789 // ThrowStatement[?Yield]
9790 case TokenKind::Throw:
9791 return throwStatement(yieldHandling);
9792
9793 // TryStatement[?Yield, ?Return]
9794 case TokenKind::Try:
9795 return tryStatement(yieldHandling);
9796
9797 // DebuggerStatement
9798 case TokenKind::Debugger:
9799 return debuggerStatement();
9800
9801 // Declaration[Yield]:
9802
9803 // HoistableDeclaration[?Yield, ~Default]
9804 case TokenKind::Function:
9805 return functionStmt(pos().begin, yieldHandling, NameRequired);
9806
9807 // DecoratorList[?Yield, ?Await] opt ClassDeclaration[?Yield, ~Default]
9808#ifdef ENABLE_DECORATORS
9809 case TokenKind::At:
9810 return classDefinition(yieldHandling, ClassStatement, NameRequired);
9811#endif
9812
9813 case TokenKind::Class:
9814 return classDefinition(yieldHandling, ClassStatement, NameRequired);
9815
9816 // LexicalDeclaration[In, ?Yield]
9817 // LetOrConst BindingList[?In, ?Yield]
9818 case TokenKind::Const:
9819 // [In] is the default behavior, because for-loops specially parse
9820 // their heads to handle |in| in this situation.
9821 return lexicalDeclaration(yieldHandling, DeclarationKind::Const);
9822
9823#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
9824 case TokenKind::Using: {
9825 TokenKind nextTok = TokenKind::Eol;
9826 if (!tokenStream.peekTokenSameLine(&nextTok)) {
9827 return errorResult();
9828 }
9829 if (!TokenKindIsPossibleIdentifier(nextTok) ||
9830 !this->pc_->isUsingSyntaxAllowed()) {
9831 if (!tokenStream.peekToken(&nextTok)) {
9832 return errorResult();
9833 }
9834 // labelled statement could be like using\n:\nexpr
9835 if (nextTok == TokenKind::Colon) {
9836 return labeledStatement(yieldHandling);
9837 }
9838 return expressionStatement(yieldHandling);
9839 }
9840 return lexicalDeclaration(yieldHandling, DeclarationKind::Using);
9841 }
9842#endif
9843
9844 // ImportDeclaration (only inside modules)
9845 case TokenKind::Import:
9846 return importDeclarationOrImportExpr(yieldHandling);
9847
9848 // ExportDeclaration (only inside modules)
9849 case TokenKind::Export:
9850 return exportDeclaration();
9851
9852 // Miscellaneous error cases arguably better caught here than elsewhere.
9853
9854 case TokenKind::Catch:
9855 error(JSMSG_CATCH_WITHOUT_TRY);
9856 return errorResult();
9857
9858 case TokenKind::Finally:
9859 error(JSMSG_FINALLY_WITHOUT_TRY);
9860 return errorResult();
9861
9862 // NOTE: default case handled in the ExpressionStatement section.
9863 }
9864}
9865
9866template <class ParseHandler, typename Unit>
9867typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::expr(
9868 InHandling inHandling, YieldHandling yieldHandling,
9869 TripledotHandling tripledotHandling,
9870 PossibleError* possibleError /* = nullptr */,
9871 InvokedPrediction invoked /* = PredictUninvoked */) {
9872 Node pn;
9873 MOZ_TRY_VAR(pn, assignExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
9874 possibleError, invoked))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
;
9875
9876 bool matched;
9877 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
9878 TokenStream::SlashIsRegExp)) {
9879 return errorResult();
9880 }
9881 if (!matched) {
9882 return pn;
9883 }
9884
9885 ListNodeType seq;
9886 MOZ_TRY_VAR(seq, handler_.newCommaExpressionList(pn))do { auto mozTryVarTempResult_ = (handler_.newCommaExpressionList
(pn)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr())
, 0))) { return mozTryVarTempResult_.propagateErr(); } (seq) =
mozTryVarTempResult_.unwrap(); } while (0)
;
9887 while (true) {
9888 // Trailing comma before the closing parenthesis is valid in an arrow
9889 // function parameters list: `(a, b, ) => body`. Check if we are
9890 // directly under CoverParenthesizedExpressionAndArrowParameterList,
9891 // and the next two tokens are closing parenthesis and arrow. If all
9892 // are present allow the trailing comma.
9893 if (tripledotHandling == TripledotAllowed) {
9894 TokenKind tt;
9895 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
9896 return errorResult();
9897 }
9898
9899 if (tt == TokenKind::RightParen) {
9900 tokenStream.consumeKnownToken(TokenKind::RightParen,
9901 TokenStream::SlashIsRegExp);
9902
9903 if (!tokenStream.peekToken(&tt)) {
9904 return errorResult();
9905 }
9906 if (tt != TokenKind::Arrow) {
9907 error(JSMSG_UNEXPECTED_TOKEN, "expression",
9908 TokenKindToDesc(TokenKind::RightParen));
9909 return errorResult();
9910 }
9911
9912 anyChars.ungetToken(); // put back right paren
9913 break;
9914 }
9915 }
9916
9917 // Additional calls to assignExpr should not reuse the possibleError
9918 // which had been passed into the function. Otherwise we would lose
9919 // information needed to determine whether or not we're dealing with
9920 // a non-recoverable situation.
9921 PossibleError possibleErrorInner(*this);
9922 MOZ_TRY_VAR(pn, assignExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
9923 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
;
9924
9925 if (!possibleError) {
9926 // Report any pending expression error.
9927 if (!possibleErrorInner.checkForExpressionError()) {
9928 return errorResult();
9929 }
9930 } else {
9931 possibleErrorInner.transferErrorsTo(possibleError);
9932 }
9933
9934 handler_.addList(seq, pn);
9935
9936 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
9937 TokenStream::SlashIsRegExp)) {
9938 return errorResult();
9939 }
9940 if (!matched) {
9941 break;
9942 }
9943 }
9944 return seq;
9945}
9946
9947static ParseNodeKind BinaryOpTokenKindToParseNodeKind(TokenKind tok) {
9948 MOZ_ASSERT(TokenKindIsBinaryOp(tok))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsBinaryOp(tok))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(TokenKindIsBinaryOp(tok)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsBinaryOp(tok)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9948); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsBinaryOp(tok)"
")"); do { *((volatile int*)__null) = 9948; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9949 return ParseNodeKind(size_t(ParseNodeKind::BinOpFirst) +
9950 (size_t(tok) - size_t(TokenKind::BinOpFirst)));
9951}
9952
9953// This list must be kept in the same order in several places:
9954// - The binary operators in ParseNode.h ,
9955// - the binary operators in TokenKind.h
9956// - the JSOp code list in BytecodeEmitter.cpp
9957static const int PrecedenceTable[] = {
9958 1, /* ParseNodeKind::Coalesce */
9959 2, /* ParseNodeKind::Or */
9960 3, /* ParseNodeKind::And */
9961 4, /* ParseNodeKind::BitOr */
9962 5, /* ParseNodeKind::BitXor */
9963 6, /* ParseNodeKind::BitAnd */
9964 7, /* ParseNodeKind::StrictEq */
9965 7, /* ParseNodeKind::Eq */
9966 7, /* ParseNodeKind::StrictNe */
9967 7, /* ParseNodeKind::Ne */
9968 8, /* ParseNodeKind::Lt */
9969 8, /* ParseNodeKind::Le */
9970 8, /* ParseNodeKind::Gt */
9971 8, /* ParseNodeKind::Ge */
9972 8, /* ParseNodeKind::InstanceOf */
9973 8, /* ParseNodeKind::In */
9974 8, /* ParseNodeKind::PrivateIn */
9975 9, /* ParseNodeKind::Lsh */
9976 9, /* ParseNodeKind::Rsh */
9977 9, /* ParseNodeKind::Ursh */
9978 10, /* ParseNodeKind::Add */
9979 10, /* ParseNodeKind::Sub */
9980 11, /* ParseNodeKind::Star */
9981 11, /* ParseNodeKind::Div */
9982 11, /* ParseNodeKind::Mod */
9983 12 /* ParseNodeKind::Pow */
9984};
9985
9986static const int PRECEDENCE_CLASSES = 12;
9987
9988static int Precedence(ParseNodeKind pnk) {
9989 // Everything binds tighter than ParseNodeKind::Limit, because we want
9990 // to reduce all nodes to a single node when we reach a token that is not
9991 // another binary operator.
9992 if (pnk == ParseNodeKind::Limit) {
9993 return 0;
9994 }
9995
9996 MOZ_ASSERT(pnk >= ParseNodeKind::BinOpFirst)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pnk >= ParseNodeKind::BinOpFirst)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pnk >= ParseNodeKind::BinOpFirst
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"pnk >= ParseNodeKind::BinOpFirst", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9996); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pnk >= ParseNodeKind::BinOpFirst"
")"); do { *((volatile int*)__null) = 9996; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9997 MOZ_ASSERT(pnk <= ParseNodeKind::BinOpLast)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pnk <= ParseNodeKind::BinOpLast)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pnk <= ParseNodeKind::BinOpLast
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"pnk <= ParseNodeKind::BinOpLast", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9997); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pnk <= ParseNodeKind::BinOpLast"
")"); do { *((volatile int*)__null) = 9997; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9998 return PrecedenceTable[size_t(pnk) - size_t(ParseNodeKind::BinOpFirst)];
9999}
10000
10001enum class EnforcedParentheses : uint8_t { CoalesceExpr, AndOrExpr, None };
10002
10003template <class ParseHandler, typename Unit>
10004MOZ_ALWAYS_INLINEinline typename ParseHandler::NodeResult
10005GeneralParser<ParseHandler, Unit>::orExpr(InHandling inHandling,
10006 YieldHandling yieldHandling,
10007 TripledotHandling tripledotHandling,
10008 PossibleError* possibleError,
10009 InvokedPrediction invoked) {
10010 // Shift-reduce parser for the binary operator part of the JS expression
10011 // syntax.
10012
10013 // Conceptually there's just one stack, a stack of pairs (lhs, op).
10014 // It's implemented using two separate arrays, though.
10015 Node nodeStack[PRECEDENCE_CLASSES];
10016 ParseNodeKind kindStack[PRECEDENCE_CLASSES];
10017 int depth = 0;
10018 Node pn;
10019 EnforcedParentheses unparenthesizedExpression = EnforcedParentheses::None;
10020 for (;;) {
10021 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked, PrivateNameHandling::PrivateNameAllowed
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
10022 pn, unaryExpr(yieldHandling, tripledotHandling, possibleError, invoked,do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked, PrivateNameHandling::PrivateNameAllowed
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
10023 PrivateNameHandling::PrivateNameAllowed))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked, PrivateNameHandling::PrivateNameAllowed
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10024
10025 // If a binary operator follows, consume it and compute the
10026 // corresponding operator.
10027 TokenKind tok;
10028 if (!tokenStream.getToken(&tok)) {
10029 return errorResult();
10030 }
10031
10032 // Ensure that if we have a private name lhs we are legally constructing a
10033 // `#x in obj` expessions:
10034 if (handler_.isPrivateName(pn)) {
10035 if (tok != TokenKind::In || inHandling != InAllowed) {
10036 error(JSMSG_ILLEGAL_PRIVATE_NAME);
10037 return errorResult();
10038 }
10039 }
10040
10041 ParseNodeKind pnk;
10042 if (tok == TokenKind::In ? inHandling == InAllowed
10043 : TokenKindIsBinaryOp(tok)) {
10044 // We're definitely not in a destructuring context, so report any
10045 // pending expression error now.
10046 if (possibleError && !possibleError->checkForExpressionError()) {
10047 return errorResult();
10048 }
10049
10050 bool isErgonomicBrandCheck = false;
10051 switch (tok) {
10052 // Report an error for unary expressions on the LHS of **.
10053 case TokenKind::Pow:
10054 if (handler_.isUnparenthesizedUnaryExpression(pn)) {
10055 error(JSMSG_BAD_POW_LEFTSIDE);
10056 return errorResult();
10057 }
10058 break;
10059
10060 case TokenKind::Or:
10061 case TokenKind::And:
10062 // In the case that the `??` is on the left hand side of the
10063 // expression: Disallow Mixing of ?? and other logical operators (||
10064 // and &&) unless one expression is parenthesized
10065 if (unparenthesizedExpression == EnforcedParentheses::CoalesceExpr) {
10066 error(JSMSG_BAD_COALESCE_MIXING);
10067 return errorResult();
10068 }
10069 // If we have not detected a mixing error at this point, record that
10070 // we have an unparenthesized expression, in case we have one later.
10071 unparenthesizedExpression = EnforcedParentheses::AndOrExpr;
10072 break;
10073
10074 case TokenKind::Coalesce:
10075 if (unparenthesizedExpression == EnforcedParentheses::AndOrExpr) {
10076 error(JSMSG_BAD_COALESCE_MIXING);
10077 return errorResult();
10078 }
10079 // If we have not detected a mixing error at this point, record that
10080 // we have an unparenthesized expression, in case we have one later.
10081 unparenthesizedExpression = EnforcedParentheses::CoalesceExpr;
10082 break;
10083
10084 case TokenKind::In:
10085 // if the LHS is a private name, and the operator is In,
10086 // ensure we're construcing an ergonomic brand check of
10087 // '#x in y', rather than having a higher precedence operator
10088 // like + cause a different reduction, such as
10089 // 1 + #x in y.
10090 if (handler_.isPrivateName(pn)) {
10091 if (depth > 0 && Precedence(kindStack[depth - 1]) >=
10092 Precedence(ParseNodeKind::InExpr)) {
10093 error(JSMSG_INVALID_PRIVATE_NAME_PRECEDENCE);
10094 return errorResult();
10095 }
10096
10097 isErgonomicBrandCheck = true;
10098 }
10099 break;
10100
10101 default:
10102 // do nothing in other cases
10103 break;
10104 }
10105
10106 if (isErgonomicBrandCheck) {
10107 pnk = ParseNodeKind::PrivateInExpr;
10108 } else {
10109 pnk = BinaryOpTokenKindToParseNodeKind(tok);
10110 }
10111
10112 } else {
10113 tok = TokenKind::Eof;
10114 pnk = ParseNodeKind::Limit;
10115 }
10116
10117 // From this point on, destructuring defaults are definitely an error.
10118 possibleError = nullptr;
10119
10120 // If pnk has precedence less than or equal to another operator on the
10121 // stack, reduce. This combines nodes on the stack until we form the
10122 // actual lhs of pnk.
10123 //
10124 // The >= in this condition works because it is appendOrCreateList's
10125 // job to decide if the operator in question is left- or
10126 // right-associative, and build the corresponding tree.
10127 while (depth > 0 && Precedence(kindStack[depth - 1]) >= Precedence(pnk)) {
10128 depth--;
10129 ParseNodeKind combiningPnk = kindStack[depth];
10130 MOZ_TRY_VAR(pn, handler_.appendOrCreateList(combiningPnk,do { auto mozTryVarTempResult_ = (handler_.appendOrCreateList
(combiningPnk, nodeStack[depth], pn, pc_)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
10131 nodeStack[depth], pn, pc_))do { auto mozTryVarTempResult_ = (handler_.appendOrCreateList
(combiningPnk, nodeStack[depth], pn, pc_)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
;
10132 }
10133
10134 if (pnk == ParseNodeKind::Limit) {
10135 break;
10136 }
10137
10138 nodeStack[depth] = pn;
10139 kindStack[depth] = pnk;
10140 depth++;
10141 MOZ_ASSERT(depth <= PRECEDENCE_CLASSES)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(depth <= PRECEDENCE_CLASSES)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(depth <= PRECEDENCE_CLASSES
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"depth <= PRECEDENCE_CLASSES", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10141); AnnotateMozCrashReason("MOZ_ASSERT" "(" "depth <= PRECEDENCE_CLASSES"
")"); do { *((volatile int*)__null) = 10141; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10142 }
10143
10144 anyChars.ungetToken();
10145
10146 // Had the next token been a Div, we would have consumed it. So there's no
10147 // ambiguity if we later (after ASI) re-get this token with SlashIsRegExp.
10148 anyChars.allowGettingNextTokenWithSlashIsRegExp();
10149
10150 MOZ_ASSERT(depth == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(depth == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(depth == 0))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("depth == 0", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10150); AnnotateMozCrashReason("MOZ_ASSERT" "(" "depth == 0"
")"); do { *((volatile int*)__null) = 10150; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10151 return pn;
10152}
10153
10154template <class ParseHandler, typename Unit>
10155MOZ_ALWAYS_INLINEinline typename ParseHandler::NodeResult
10156GeneralParser<ParseHandler, Unit>::condExpr(InHandling inHandling,
10157 YieldHandling yieldHandling,
10158 TripledotHandling tripledotHandling,
10159 PossibleError* possibleError,
10160 InvokedPrediction invoked) {
10161 Node condition;
10162 MOZ_TRY_VAR(condition, orExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (orExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (condition) = mozTryVarTempResult_.unwrap(
); } while (0)
10163 possibleError, invoked))do { auto mozTryVarTempResult_ = (orExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (condition) = mozTryVarTempResult_.unwrap(
); } while (0)
;
10164
10165 bool matched;
10166 if (!tokenStream.matchToken(&matched, TokenKind::Hook,
10167 TokenStream::SlashIsInvalid)) {
10168 return errorResult();
10169 }
10170 if (!matched) {
10171 return condition;
10172 }
10173
10174 Node thenExpr;
10175 MOZ_TRY_VAR(thenExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (thenExpr) = mozTryVarTempResult_.unwrap(); } while (0)
10176 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (thenExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
10177
10178 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_IN_COND)) {
10179 return errorResult();
10180 }
10181
10182 Node elseExpr;
10183 MOZ_TRY_VAR(elseExpr,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (elseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
10184 assignExpr(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (elseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
10185
10186 return handler_.newConditional(condition, thenExpr, elseExpr);
10187}
10188
10189template <class ParseHandler, typename Unit>
10190typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::assignExpr(
10191 InHandling inHandling, YieldHandling yieldHandling,
10192 TripledotHandling tripledotHandling,
10193 PossibleError* possibleError /* = nullptr */,
10194 InvokedPrediction invoked /* = PredictUninvoked */) {
10195 AutoCheckRecursionLimit recursion(this->fc_);
10196 if (!recursion.check(this->fc_)) {
10197 return errorResult();
10198 }
10199
10200 // It's very common at this point to have a "detectably simple" expression,
10201 // i.e. a name/number/string token followed by one of the following tokens
10202 // that obviously isn't part of an expression: , ; : ) ] }
10203 //
10204 // (In Parsemark this happens 81.4% of the time; in code with large
10205 // numeric arrays, such as some Kraken benchmarks, it happens more often.)
10206 //
10207 // In such cases, we can avoid the full expression parsing route through
10208 // assignExpr(), condExpr(), orExpr(), unaryExpr(), memberExpr(), and
10209 // primaryExpr().
10210
10211 TokenKind firstToken;
10212 if (!tokenStream.getToken(&firstToken, TokenStream::SlashIsRegExp)) {
10213 return errorResult();
10214 }
10215
10216 TokenPos exprPos = pos();
10217
10218 bool endsExpr;
10219
10220 // This only handles identifiers that *never* have special meaning anywhere
10221 // in the language. Contextual keywords, reserved words in strict mode,
10222 // and other hard cases are handled outside this fast path.
10223 if (firstToken == TokenKind::Name) {
10224 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10225 return errorResult();
10226 }
10227 if (endsExpr) {
10228 TaggedParserAtomIndex name = identifierReference(yieldHandling);
10229 if (!name) {
10230 return errorResult();
10231 }
10232
10233 return identifierReference(name);
10234 }
10235 }
10236
10237 if (firstToken == TokenKind::Number) {
10238 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10239 return errorResult();
10240 }
10241 if (endsExpr) {
10242 return newNumber(anyChars.currentToken());
10243 }
10244 }
10245
10246 if (firstToken == TokenKind::String) {
10247 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10248 return errorResult();
10249 }
10250 if (endsExpr) {
10251 return stringLiteral();
10252 }
10253 }
10254
10255 if (firstToken == TokenKind::Yield && yieldExpressionsSupported()) {
10256 return yieldExpression(inHandling);
10257 }
10258
10259 bool maybeAsyncArrow = false;
10260 if (firstToken == TokenKind::Async) {
10261 TokenKind nextSameLine = TokenKind::Eof;
10262 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
10263 return errorResult();
10264 }
10265
10266 if (TokenKindIsPossibleIdentifier(nextSameLine)) {
10267 maybeAsyncArrow = true;
10268 }
10269 }
10270
10271 anyChars.ungetToken();
10272
10273 // Save the tokenizer state in case we find an arrow function and have to
10274 // rewind.
10275 Position start(tokenStream);
10276 auto ghostToken = this->compilationState_.getPosition();
10277
10278 PossibleError possibleErrorInner(*this);
10279 Node lhs;
10280 TokenKind tokenAfterLHS;
10281 bool isArrow;
10282 if (maybeAsyncArrow) {
10283 tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::SlashIsRegExp);
10284
10285 TokenKind tokenAfterAsync;
10286 if (!tokenStream.getToken(&tokenAfterAsync)) {
10287 return errorResult();
10288 }
10289 MOZ_ASSERT(TokenKindIsPossibleIdentifier(tokenAfterAsync))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(tokenAfterAsync))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(tokenAfterAsync)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(tokenAfterAsync)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10289); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(tokenAfterAsync)"
")"); do { *((volatile int*)__null) = 10289; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10290
10291 // Check yield validity here.
10292 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
10293 if (!name) {
10294 return errorResult();
10295 }
10296
10297 if (!tokenStream.peekToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)) {
10298 return errorResult();
10299 }
10300
10301 isArrow = tokenAfterLHS == TokenKind::Arrow;
10302
10303 // |async [no LineTerminator] of| without being followed by => is only
10304 // possible in for-await-of loops, e.g. |for await (async of [])|. Pretend
10305 // the |async| token was parsed an identifier reference and then proceed
10306 // with the rest of this function.
10307 if (!isArrow) {
10308 anyChars.ungetToken(); // unget the binding identifier
10309
10310 // The next token is guaranteed to never be a Div (, because it's an
10311 // identifier), so it's okay to re-get the token with SlashIsRegExp.
10312 anyChars.allowGettingNextTokenWithSlashIsRegExp();
10313
10314 TaggedParserAtomIndex asyncName = identifierReference(yieldHandling);
10315 if (!asyncName) {
10316 return errorResult();
10317 }
10318
10319 MOZ_TRY_VAR(lhs, identifierReference(asyncName))do { auto mozTryVarTempResult_ = (identifierReference(asyncName
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10320 }
10321 } else {
10322 MOZ_TRY_VAR(lhs, condExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (condExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner, invoked)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
10323 &possibleErrorInner, invoked))do { auto mozTryVarTempResult_ = (condExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner, invoked)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10324
10325 // Use SlashIsRegExp here because the ConditionalExpression parsed above
10326 // could be the entirety of this AssignmentExpression, and then ASI
10327 // permits this token to be a regular expression.
10328 if (!tokenStream.peekToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)) {
10329 return errorResult();
10330 }
10331
10332 isArrow = tokenAfterLHS == TokenKind::Arrow;
10333 }
10334
10335 if (isArrow) {
10336 // Rewind to reparse as an arrow function.
10337 //
10338 // Note: We do not call CompilationState::rewind here because parsing
10339 // during delazification will see the same rewind and need the same sequence
10340 // of inner functions to skip over.
10341 // Instead, we mark inner functions as "ghost".
10342 //
10343 // See GHOST_FUNCTION in FunctionFlags.h for more details.
10344 tokenStream.rewind(start);
10345 this->compilationState_.markGhost(ghostToken);
10346
10347 TokenKind next;
10348 if (!tokenStream.getToken(&next, TokenStream::SlashIsRegExp)) {
10349 return errorResult();
10350 }
10351 TokenPos startPos = pos();
10352 uint32_t toStringStart = startPos.begin;
10353 anyChars.ungetToken();
10354
10355 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
10356
10357 if (next == TokenKind::Async) {
10358 tokenStream.consumeKnownToken(next, TokenStream::SlashIsRegExp);
10359
10360 TokenKind nextSameLine = TokenKind::Eof;
10361 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
10362 return errorResult();
10363 }
10364
10365 // The AsyncArrowFunction production are
10366 // async [no LineTerminator here] AsyncArrowBindingIdentifier ...
10367 // async [no LineTerminator here] ArrowFormalParameters ...
10368 if (TokenKindIsPossibleIdentifier(nextSameLine) ||
10369 nextSameLine == TokenKind::LeftParen) {
10370 asyncKind = FunctionAsyncKind::AsyncFunction;
10371 } else {
10372 anyChars.ungetToken();
10373 }
10374 }
10375
10376 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Arrow;
10377 FunctionNodeType funNode;
10378 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, startPos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, startPos)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10379
10380 return functionDefinition(funNode, toStringStart, inHandling, yieldHandling,
10381 TaggedParserAtomIndex::null(), syntaxKind,
10382 GeneratorKind::NotGenerator, asyncKind);
10383 }
10384
10385 MOZ_ALWAYS_TRUE(do { if ((__builtin_expect(!!(tokenStream.getToken(&tokenAfterLHS
, TokenStream::SlashIsRegExp)), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10386); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")"); do { *((volatile int*)__null) = 10386; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
10386 tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp))do { if ((__builtin_expect(!!(tokenStream.getToken(&tokenAfterLHS
, TokenStream::SlashIsRegExp)), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10386); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")"); do { *((volatile int*)__null) = 10386; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
;
10387
10388 ParseNodeKind kind;
10389 switch (tokenAfterLHS) {
10390 case TokenKind::Assign:
10391 kind = ParseNodeKind::AssignExpr;
10392 break;
10393 case TokenKind::AddAssign:
10394 kind = ParseNodeKind::AddAssignExpr;
10395 break;
10396 case TokenKind::SubAssign:
10397 kind = ParseNodeKind::SubAssignExpr;
10398 break;
10399 case TokenKind::CoalesceAssign:
10400 kind = ParseNodeKind::CoalesceAssignExpr;
10401 break;
10402 case TokenKind::OrAssign:
10403 kind = ParseNodeKind::OrAssignExpr;
10404 break;
10405 case TokenKind::AndAssign:
10406 kind = ParseNodeKind::AndAssignExpr;
10407 break;
10408 case TokenKind::BitOrAssign:
10409 kind = ParseNodeKind::BitOrAssignExpr;
10410 break;
10411 case TokenKind::BitXorAssign:
10412 kind = ParseNodeKind::BitXorAssignExpr;
10413 break;
10414 case TokenKind::BitAndAssign:
10415 kind = ParseNodeKind::BitAndAssignExpr;
10416 break;
10417 case TokenKind::LshAssign:
10418 kind = ParseNodeKind::LshAssignExpr;
10419 break;
10420 case TokenKind::RshAssign:
10421 kind = ParseNodeKind::RshAssignExpr;
10422 break;
10423 case TokenKind::UrshAssign:
10424 kind = ParseNodeKind::UrshAssignExpr;
10425 break;
10426 case TokenKind::MulAssign:
10427 kind = ParseNodeKind::MulAssignExpr;
10428 break;
10429 case TokenKind::DivAssign:
10430 kind = ParseNodeKind::DivAssignExpr;
10431 break;
10432 case TokenKind::ModAssign:
10433 kind = ParseNodeKind::ModAssignExpr;
10434 break;
10435 case TokenKind::PowAssign:
10436 kind = ParseNodeKind::PowAssignExpr;
10437 break;
10438
10439 default:
10440 MOZ_ASSERT(!anyChars.isCurrentTokenAssignment())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!anyChars.isCurrentTokenAssignment())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!anyChars.isCurrentTokenAssignment
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!anyChars.isCurrentTokenAssignment()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10440); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!anyChars.isCurrentTokenAssignment()"
")"); do { *((volatile int*)__null) = 10440; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10441 if (!possibleError) {
10442 if (!possibleErrorInner.checkForExpressionError()) {
10443 return errorResult();
10444 }
10445 } else {
10446 possibleErrorInner.transferErrorsTo(possibleError);
10447 }
10448
10449 anyChars.ungetToken();
10450 return lhs;
10451 }
10452
10453 // Verify the left-hand side expression doesn't have a forbidden form.
10454 if (handler_.isUnparenthesizedDestructuringPattern(lhs)) {
10455 if (kind != ParseNodeKind::AssignExpr) {
10456 error(JSMSG_BAD_DESTRUCT_ASS);
10457 return errorResult();
10458 }
10459
10460 if (!possibleErrorInner.checkForDestructuringErrorOrWarning()) {
10461 return errorResult();
10462 }
10463 } else if (handler_.isName(lhs)) {
10464 if (const char* chars = nameIsArgumentsOrEval(lhs)) {
10465 // |chars| is "arguments" or "eval" here.
10466 if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_STRICT_ASSIGN, chars)) {
10467 return errorResult();
10468 }
10469 }
10470 } else if (handler_.isArgumentsLength(lhs)) {
10471 pc_->sc()->setIneligibleForArgumentsLength();
10472 } else if (handler_.isPropertyOrPrivateMemberAccess(lhs)) {
10473 // Permitted: no additional testing/fixup needed.
10474 } else if (handler_.isFunctionCall(lhs)) {
10475 // We don't have to worry about backward compatibility issues with the new
10476 // compound assignment operators, so we always throw here. Also that way we
10477 // don't have to worry if |f() &&= expr| should always throw an error or
10478 // only if |f()| returns true.
10479 if (kind == ParseNodeKind::CoalesceAssignExpr ||
10480 kind == ParseNodeKind::OrAssignExpr ||
10481 kind == ParseNodeKind::AndAssignExpr) {
10482 errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
10483 return errorResult();
10484 }
10485
10486 if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS)) {
10487 return errorResult();
10488 }
10489
10490 if (possibleError) {
10491 possibleError->setPendingDestructuringErrorAt(exprPos,
10492 JSMSG_BAD_DESTRUCT_TARGET);
10493 }
10494 } else {
10495 errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
10496 return errorResult();
10497 }
10498
10499 if (!possibleErrorInner.checkForExpressionError()) {
10500 return errorResult();
10501 }
10502
10503 Node rhs;
10504 MOZ_TRY_VAR(rhs, assignExpr(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
10505
10506 return handler_.newAssignment(kind, lhs, rhs);
10507}
10508
10509template <class ParseHandler>
10510const char* PerHandlerParser<ParseHandler>::nameIsArgumentsOrEval(Node node) {
10511 MOZ_ASSERT(handler_.isName(node),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(handler_.isName(node))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(handler_.isName(node)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("handler_.isName(node)"
" (" "must only call this function on known names" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10512); AnnotateMozCrashReason("MOZ_ASSERT" "(" "handler_.isName(node)"
") (" "must only call this function on known names" ")"); do
{ *((volatile int*)__null) = 10512; __attribute__((nomerge))
::abort(); } while (false); } } while (false)
10512 "must only call this function on known names")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(handler_.isName(node))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(handler_.isName(node)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("handler_.isName(node)"
" (" "must only call this function on known names" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10512); AnnotateMozCrashReason("MOZ_ASSERT" "(" "handler_.isName(node)"
") (" "must only call this function on known names" ")"); do
{ *((volatile int*)__null) = 10512; __attribute__((nomerge))
::abort(); } while (false); } } while (false)
;
10513
10514 if (handler_.isEvalName(node)) {
10515 return "eval";
10516 }
10517 if (handler_.isArgumentsName(node)) {
10518 return "arguments";
10519 }
10520 return nullptr;
10521}
10522
10523template <class ParseHandler, typename Unit>
10524bool GeneralParser<ParseHandler, Unit>::checkIncDecOperand(
10525 Node operand, uint32_t operandOffset) {
10526 if (handler_.isName(operand)) {
10527 if (const char* chars = nameIsArgumentsOrEval(operand)) {
10528 if (!strictModeErrorAt(operandOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) {
10529 return false;
10530 }
10531 }
10532 } else if (handler_.isArgumentsLength(operand)) {
10533 pc_->sc()->setIneligibleForArgumentsLength();
10534 } else if (handler_.isPropertyOrPrivateMemberAccess(operand)) {
10535 // Permitted: no additional testing/fixup needed.
10536 } else if (handler_.isFunctionCall(operand)) {
10537 // Assignment to function calls is forbidden in ES6. We're still
10538 // somewhat concerned about sites using this in dead code, so forbid it
10539 // only in strict mode code.
10540 if (!strictModeErrorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND)) {
10541 return false;
10542 }
10543 } else {
10544 errorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND);
10545 return false;
10546 }
10547 return true;
10548}
10549
10550template <class ParseHandler, typename Unit>
10551typename ParseHandler::UnaryNodeResult
10552GeneralParser<ParseHandler, Unit>::unaryOpExpr(YieldHandling yieldHandling,
10553 ParseNodeKind kind,
10554 uint32_t begin) {
10555 Node kid;
10556 MOZ_TRY_VAR(kid, unaryExpr(yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, TripledotProhibited
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (kid) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10557 return handler_.newUnary(kind, begin, kid);
10558}
10559
10560template <class ParseHandler, typename Unit>
10561typename ParseHandler::NodeResult
10562GeneralParser<ParseHandler, Unit>::optionalExpr(
10563 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10564 TokenKind tt, PossibleError* possibleError /* = nullptr */,
10565 InvokedPrediction invoked /* = PredictUninvoked */) {
10566 AutoCheckRecursionLimit recursion(this->fc_);
10567 if (!recursion.check(this->fc_)) {
10568 return errorResult();
10569 }
10570
10571 uint32_t begin = pos().begin;
10572
10573 Node lhs;
10574 MOZ_TRY_VAR(lhs,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, tripledotHandling
, tt, true, possibleError, invoked)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (lhs) = mozTryVarTempResult_.unwrap(); } while
(0)
10575 memberExpr(yieldHandling, tripledotHandling, tt,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, tripledotHandling
, tt, true, possibleError, invoked)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (lhs) = mozTryVarTempResult_.unwrap(); } while
(0)
10576 /* allowCallSyntax = */ true, possibleError, invoked))do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, tripledotHandling
, tt, true, possibleError, invoked)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (lhs) = mozTryVarTempResult_.unwrap(); } while
(0)
;
10577
10578 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsDiv)) {
10579 return errorResult();
10580 }
10581
10582 if (tt != TokenKind::OptionalChain) {
10583 return lhs;
10584 }
10585
10586 while (true) {
10587 if (!tokenStream.getToken(&tt)) {
10588 return errorResult();
10589 }
10590
10591 if (tt == TokenKind::Eof) {
10592 anyChars.ungetToken();
10593 break;
10594 }
10595
10596 Node nextMember;
10597 if (tt == TokenKind::OptionalChain) {
10598 if (!tokenStream.getToken(&tt)) {
10599 return errorResult();
10600 }
10601 if (TokenKindIsPossibleIdentifierName(tt)) {
10602 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
10603 memberPropertyAccess(lhs, OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10604 } else if (tt == TokenKind::PrivateName) {
10605 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
10606 memberPrivateAccess(lhs, OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10607 } else if (tt == TokenKind::LeftBracket) {
10608 MOZ_TRY_VAR(nextMember, memberElemAccess(lhs, yieldHandling,do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
, OptionalKind::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
10609 OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
, OptionalKind::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
;
10610 } else if (tt == TokenKind::LeftParen) {
10611 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError, OptionalKind::Optional)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nextMember) = mozTryVarTempResult_.unwrap
(); } while (0)
10612 memberCall(tt, lhs, yieldHandling, possibleError,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError, OptionalKind::Optional)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nextMember) = mozTryVarTempResult_.unwrap
(); } while (0)
10613 OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError, OptionalKind::Optional)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nextMember) = mozTryVarTempResult_.unwrap
(); } while (0)
;
10614 } else {
10615 error(JSMSG_NAME_AFTER_DOT);
10616 return errorResult();
10617 }
10618 } else if (tt == TokenKind::Dot) {
10619 if (!tokenStream.getToken(&tt)) {
10620 return errorResult();
10621 }
10622 if (TokenKindIsPossibleIdentifierName(tt)) {
10623 MOZ_TRY_VAR(nextMember, memberPropertyAccess(lhs))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nextMember)
= mozTryVarTempResult_.unwrap(); } while (0)
;
10624 } else if (tt == TokenKind::PrivateName) {
10625 MOZ_TRY_VAR(nextMember, memberPrivateAccess(lhs))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (nextMember) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10626 } else {
10627 error(JSMSG_NAME_AFTER_DOT);
10628 return errorResult();
10629 }
10630 } else if (tt == TokenKind::LeftBracket) {
10631 MOZ_TRY_VAR(nextMember, memberElemAccess(lhs, yieldHandling))do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10632 } else if (tt == TokenKind::LeftParen) {
10633 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
10634 memberCall(tt, lhs, yieldHandling, possibleError))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
;
10635 } else if (tt == TokenKind::TemplateHead ||
10636 tt == TokenKind::NoSubsTemplate) {
10637 error(JSMSG_BAD_OPTIONAL_TEMPLATE);
10638 return errorResult();
10639 } else {
10640 anyChars.ungetToken();
10641 break;
10642 }
10643
10644 MOZ_ASSERT(nextMember)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nextMember)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nextMember))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("nextMember", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10644); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nextMember"
")"); do { *((volatile int*)__null) = 10644; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10645 lhs = nextMember;
10646 }
10647
10648 return handler_.newOptionalChain(begin, lhs);
10649}
10650
10651template <class ParseHandler, typename Unit>
10652typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::unaryExpr(
10653 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10654 PossibleError* possibleError /* = nullptr */,
10655 InvokedPrediction invoked /* = PredictUninvoked */,
10656 PrivateNameHandling privateNameHandling /* = PrivateNameProhibited */) {
10657 AutoCheckRecursionLimit recursion(this->fc_);
10658 if (!recursion.check(this->fc_)) {
10659 return errorResult();
10660 }
10661
10662 TokenKind tt;
10663 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
10664 return errorResult();
10665 }
10666 uint32_t begin = pos().begin;
10667 switch (tt) {
10668 case TokenKind::Void:
10669 return unaryOpExpr(yieldHandling, ParseNodeKind::VoidExpr, begin);
10670 case TokenKind::Not:
10671 return unaryOpExpr(yieldHandling, ParseNodeKind::NotExpr, begin);
10672 case TokenKind::BitNot:
10673 return unaryOpExpr(yieldHandling, ParseNodeKind::BitNotExpr, begin);
10674 case TokenKind::Add:
10675 return unaryOpExpr(yieldHandling, ParseNodeKind::PosExpr, begin);
10676 case TokenKind::Sub:
10677 return unaryOpExpr(yieldHandling, ParseNodeKind::NegExpr, begin);
10678
10679 case TokenKind::TypeOf: {
10680 // The |typeof| operator is specially parsed to distinguish its
10681 // application to a name, from its application to a non-name
10682 // expression:
10683 //
10684 // // Looks up the name, doesn't find it and so evaluates to
10685 // // "undefined".
10686 // assertEq(typeof nonExistentName, "undefined");
10687 //
10688 // // Evaluates expression, triggering a runtime ReferenceError for
10689 // // the undefined name.
10690 // typeof (1, nonExistentName);
10691 Node kid;
10692 MOZ_TRY_VAR(kid, unaryExpr(yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, TripledotProhibited
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (kid) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10693
10694 return handler_.newTypeof(begin, kid);
10695 }
10696
10697 case TokenKind::Inc:
10698 case TokenKind::Dec: {
10699 TokenKind tt2;
10700 if (!tokenStream.getToken(&tt2, TokenStream::SlashIsRegExp)) {
10701 return errorResult();
10702 }
10703
10704 uint32_t operandOffset = pos().begin;
10705 Node operand;
10706 MOZ_TRY_VAR(operand,do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt2)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (operand) = mozTryVarTempResult_.unwrap(); } while (0)
10707 optionalExpr(yieldHandling, TripledotProhibited, tt2))do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt2)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (operand) = mozTryVarTempResult_.unwrap(); } while (0)
;
10708 if (!checkIncDecOperand(operand, operandOffset)) {
10709 return errorResult();
10710 }
10711 ParseNodeKind pnk = (tt == TokenKind::Inc)
10712 ? ParseNodeKind::PreIncrementExpr
10713 : ParseNodeKind::PreDecrementExpr;
10714 return handler_.newUpdate(pnk, begin, operand);
10715 }
10716 case TokenKind::PrivateName: {
10717 if (privateNameHandling == PrivateNameHandling::PrivateNameAllowed) {
10718 TaggedParserAtomIndex field = anyChars.currentName();
10719 return privateNameReference(field);
10720 }
10721 error(JSMSG_INVALID_PRIVATE_NAME_IN_UNARY_EXPR);
10722 return errorResult();
10723 }
10724
10725 case TokenKind::Delete: {
10726 uint32_t exprOffset;
10727 if (!tokenStream.peekOffset(&exprOffset, TokenStream::SlashIsRegExp)) {
10728 return errorResult();
10729 }
10730
10731 Node expr;
10732 MOZ_TRY_VAR(expr, unaryExpr(yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, TripledotProhibited
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (expr) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10733
10734 // Per spec, deleting most unary expressions is valid -- it simply
10735 // returns true -- except for two cases:
10736 // 1. `var x; ...; delete x` is a syntax error in strict mode.
10737 // 2. Private fields cannot be deleted.
10738 if (handler_.isName(expr)) {
10739 if (!strictModeErrorAt(exprOffset, JSMSG_DEPRECATED_DELETE_OPERAND)) {
10740 return errorResult();
10741 }
10742
10743 pc_->sc()->setBindingsAccessedDynamically();
10744 }
10745
10746 if (handler_.isPrivateMemberAccess(expr)) {
10747 errorAt(exprOffset, JSMSG_PRIVATE_DELETE);
10748 return errorResult();
10749 }
10750
10751 return handler_.newDelete(begin, expr);
10752 }
10753 case TokenKind::Await: {
10754 // If we encounter an await in a module, mark it as async.
10755 if (!pc_->isAsync() && pc_->sc()->isModule()) {
10756 if (!options().topLevelAwait) {
10757 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
10758 return errorResult();
10759 }
10760 pc_->sc()->asModuleContext()->setIsAsync();
10761 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10761); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 10761; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10762 }
10763
10764 if (pc_->isAsync()) {
10765 if (inParametersOfAsyncFunction()) {
10766 error(JSMSG_AWAIT_IN_PARAMETER);
10767 return errorResult();
10768 }
10769 Node kid;
10770 MOZ_TRY_VAR(kid, unaryExpr(yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
10771 possibleError, invoked))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
10772 pc_->lastAwaitOffset = begin;
10773 return handler_.newAwaitExpression(begin, kid);
10774 }
10775 }
10776
10777 [[fallthrough]];
10778
10779 default: {
10780 Node expr;
10781 MOZ_TRY_VAR(expr, optionalExpr(yieldHandling, tripledotHandling, tt,do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
tripledotHandling, tt, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
10782 possibleError, invoked))do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
tripledotHandling, tt, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
10783
10784 /* Don't look across a newline boundary for a postfix incop. */
10785 if (!tokenStream.peekTokenSameLine(&tt)) {
10786 return errorResult();
10787 }
10788
10789 if (tt != TokenKind::Inc && tt != TokenKind::Dec) {
10790 return expr;
10791 }
10792
10793 tokenStream.consumeKnownToken(tt);
10794 if (!checkIncDecOperand(expr, begin)) {
10795 return errorResult();
10796 }
10797
10798 ParseNodeKind pnk = (tt == TokenKind::Inc)
10799 ? ParseNodeKind::PostIncrementExpr
10800 : ParseNodeKind::PostDecrementExpr;
10801 return handler_.newUpdate(pnk, begin, expr);
10802 }
10803 }
10804}
10805
10806template <class ParseHandler, typename Unit>
10807typename ParseHandler::NodeResult
10808GeneralParser<ParseHandler, Unit>::assignExprWithoutYieldOrAwait(
10809 YieldHandling yieldHandling) {
10810 uint32_t startYieldOffset = pc_->lastYieldOffset;
10811 uint32_t startAwaitOffset = pc_->lastAwaitOffset;
10812
10813 Node res;
10814 MOZ_TRY_VAR(res, assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (res) = mozTryVarTempResult_.unwrap(); } while (0)
;
10815
10816 if (pc_->lastYieldOffset != startYieldOffset) {
10817 errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
10818 return errorResult();
10819 }
10820 if (pc_->lastAwaitOffset != startAwaitOffset) {
10821 errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
10822 return errorResult();
10823 }
10824 return res;
10825}
10826
10827template <class ParseHandler, typename Unit>
10828typename ParseHandler::ListNodeResult
10829GeneralParser<ParseHandler, Unit>::argumentList(
10830 YieldHandling yieldHandling, bool* isSpread,
10831 PossibleError* possibleError /* = nullptr */) {
10832 ListNodeType argsList;
10833 MOZ_TRY_VAR(argsList, handler_.newArguments(pos()))do { auto mozTryVarTempResult_ = (handler_.newArguments(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10834
10835 bool matched;
10836 if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
10837 TokenStream::SlashIsRegExp)) {
10838 return errorResult();
10839 }
10840 if (matched) {
10841 handler_.setEndPosition(argsList, pos().end);
10842 return argsList;
10843 }
10844
10845 while (true) {
10846 bool spread = false;
10847 uint32_t begin = 0;
10848 if (!tokenStream.matchToken(&matched, TokenKind::TripleDot,
10849 TokenStream::SlashIsRegExp)) {
10850 return errorResult();
10851 }
10852 if (matched) {
10853 spread = true;
10854 begin = pos().begin;
10855 *isSpread = true;
10856 }
10857
10858 Node argNode;
10859 MOZ_TRY_VAR(argNode, assignExpr(InAllowed, yieldHandling,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, possibleError)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (argNode) = mozTryVarTempResult_.unwrap();
} while (0)
10860 TripledotProhibited, possibleError))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, possibleError)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (argNode) = mozTryVarTempResult_.unwrap();
} while (0)
;
10861 if (spread) {
10862 MOZ_TRY_VAR(argNode, handler_.newSpread(begin, argNode))do { auto mozTryVarTempResult_ = (handler_.newSpread(begin, argNode
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argNode)
= mozTryVarTempResult_.unwrap(); } while (0)
;
10863 }
10864
10865 handler_.addList(argsList, argNode);
10866
10867 bool matched;
10868 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
10869 TokenStream::SlashIsRegExp)) {
10870 return errorResult();
10871 }
10872 if (!matched) {
10873 break;
10874 }
10875
10876 TokenKind tt;
10877 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
10878 return errorResult();
10879 }
10880 if (tt == TokenKind::RightParen) {
10881 break;
10882 }
10883 }
10884
10885 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_ARGS)) {
10886 return errorResult();
10887 }
10888
10889 handler_.setEndPosition(argsList, pos().end);
10890 return argsList;
10891}
10892
10893bool ParserBase::checkAndMarkSuperScope() {
10894 if (!pc_->sc()->allowSuperProperty()) {
10895 return false;
10896 }
10897
10898 pc_->setSuperScopeNeedsHomeObject();
10899 return true;
10900}
10901
10902template <class ParseHandler, typename Unit>
10903bool GeneralParser<ParseHandler, Unit>::computeErrorMetadata(
10904 ErrorMetadata* err, const ErrorReportMixin::ErrorOffset& offset) const {
10905 if (offset.is<ErrorReportMixin::Current>()) {
10906 return tokenStream.computeErrorMetadata(err, AsVariant(pos().begin));
10907 }
10908 return tokenStream.computeErrorMetadata(err, offset);
10909}
10910
10911template <class ParseHandler, typename Unit>
10912typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::memberExpr(
10913 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10914 TokenKind tt, bool allowCallSyntax, PossibleError* possibleError,
10915 InvokedPrediction invoked) {
10916 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10916); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 10916; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10917
10918 Node lhs;
10919
10920 AutoCheckRecursionLimit recursion(this->fc_);
10921 if (!recursion.check(this->fc_)) {
10922 return errorResult();
10923 }
10924
10925 /* Check for new expression first. */
10926 if (tt == TokenKind::New) {
10927 uint32_t newBegin = pos().begin;
10928 // Make sure this wasn't a |new.target| in disguise.
10929 NewTargetNodeType newTarget;
10930 if (!tryNewTarget(&newTarget)) {
10931 return errorResult();
10932 }
10933 if (newTarget) {
10934 lhs = newTarget;
10935 } else {
10936 // Gotten by tryNewTarget
10937 tt = anyChars.currentToken().type;
10938 Node ctorExpr;
10939 MOZ_TRY_VAR(ctorExpr,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
10940 memberExpr(yieldHandling, TripledotProhibited, tt,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
10941 /* allowCallSyntax = */ false,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
10942 /* possibleError = */ nullptr, PredictInvoked))do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
;
10943
10944 // If we have encountered an optional chain, in the form of `new
10945 // ClassName?.()` then we need to throw, as this is disallowed by the
10946 // spec.
10947 bool optionalToken;
10948 if (!tokenStream.matchToken(&optionalToken, TokenKind::OptionalChain)) {
10949 return errorResult();
10950 }
10951 if (optionalToken) {
10952 errorAt(newBegin, JSMSG_BAD_NEW_OPTIONAL);
10953 return errorResult();
10954 }
10955
10956 bool matched;
10957 if (!tokenStream.matchToken(&matched, TokenKind::LeftParen)) {
10958 return errorResult();
10959 }
10960
10961 bool isSpread = false;
10962 ListNodeType args;
10963 if (matched) {
10964 MOZ_TRY_VAR(args, argumentList(yieldHandling, &isSpread))do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (args) = mozTryVarTempResult_.unwrap(); } while (0)
;
10965 } else {
10966 MOZ_TRY_VAR(args, handler_.newArguments(pos()))do { auto mozTryVarTempResult_ = (handler_.newArguments(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (args) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10967 }
10968
10969 if (!args) {
10970 return errorResult();
10971 }
10972
10973 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (handler_.newNewExpression(newBegin
, ctorExpr, args, isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
10974 lhs, handler_.newNewExpression(newBegin, ctorExpr, args, isSpread))do { auto mozTryVarTempResult_ = (handler_.newNewExpression(newBegin
, ctorExpr, args, isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
10975 }
10976 } else if (tt == TokenKind::Super) {
10977 NameNodeType thisName;
10978 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
10979 MOZ_TRY_VAR(lhs, handler_.newSuperBase(thisName, pos()))do { auto mozTryVarTempResult_ = (handler_.newSuperBase(thisName
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (lhs
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10980 } else if (tt == TokenKind::Import) {
10981 MOZ_TRY_VAR(lhs, importExpr(yieldHandling, allowCallSyntax))do { auto mozTryVarTempResult_ = (importExpr(yieldHandling, allowCallSyntax
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10982 } else {
10983 MOZ_TRY_VAR(lhs, primaryExpr(yieldHandling, tripledotHandling, tt,do { auto mozTryVarTempResult_ = (primaryExpr(yieldHandling, tripledotHandling
, tt, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
10984 possibleError, invoked))do { auto mozTryVarTempResult_ = (primaryExpr(yieldHandling, tripledotHandling
, tt, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
10985 }
10986
10987 MOZ_ASSERT_IF(handler_.isSuperBase(lhs),do { if (handler_.isSuperBase(lhs)) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Super))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Super)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Super)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10988); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Super)"
")"); do { *((volatile int*)__null) = 10988; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
10988 anyChars.isCurrentTokenType(TokenKind::Super))do { if (handler_.isSuperBase(lhs)) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Super))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Super)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Super)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10988); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Super)"
")"); do { *((volatile int*)__null) = 10988; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
;
10989
10990 while (true) {
10991 if (!tokenStream.getToken(&tt)) {
10992 return errorResult();
10993 }
10994 if (tt == TokenKind::Eof) {
10995 anyChars.ungetToken();
10996 break;
10997 }
10998
10999 Node nextMember;
11000 if (tt == TokenKind::Dot) {
11001 if (!tokenStream.getToken(&tt)) {
11002 return errorResult();
11003 }
11004
11005 if (TokenKindIsPossibleIdentifierName(tt)) {
11006 MOZ_TRY_VAR(nextMember, memberPropertyAccess(lhs))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nextMember)
= mozTryVarTempResult_.unwrap(); } while (0)
;
11007 } else if (tt == TokenKind::PrivateName) {
11008 MOZ_TRY_VAR(nextMember, memberPrivateAccess(lhs))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (nextMember) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11009 } else {
11010 error(JSMSG_NAME_AFTER_DOT);
11011 return errorResult();
11012 }
11013 } else if (tt == TokenKind::LeftBracket) {
11014 MOZ_TRY_VAR(nextMember, memberElemAccess(lhs, yieldHandling))do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11015 } else if ((allowCallSyntax && tt == TokenKind::LeftParen) ||
11016 tt == TokenKind::TemplateHead ||
11017 tt == TokenKind::NoSubsTemplate) {
11018 if (handler_.isSuperBase(lhs)) {
11019 if (!pc_->sc()->allowSuperCall()) {
11020 error(JSMSG_BAD_SUPERCALL);
11021 return errorResult();
11022 }
11023
11024 if (tt != TokenKind::LeftParen) {
11025 error(JSMSG_BAD_SUPER);
11026 return errorResult();
11027 }
11028
11029 MOZ_TRY_VAR(nextMember, memberSuperCall(lhs, yieldHandling))do { auto mozTryVarTempResult_ = (memberSuperCall(lhs, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11030
11031 if (!noteUsedName(
11032 TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
11033 return errorResult();
11034 }
11035#ifdef ENABLE_DECORATORS
11036 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
11037 dot_instanceExtraInitializers_())) {
11038 return null();
11039 }
11040#endif
11041 } else {
11042 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
11043 memberCall(tt, lhs, yieldHandling, possibleError))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
;
11044 }
11045 } else {
11046 anyChars.ungetToken();
11047 if (handler_.isSuperBase(lhs)) {
11048 break;
11049 }
11050 return lhs;
11051 }
11052
11053 lhs = nextMember;
11054 }
11055
11056 if (handler_.isSuperBase(lhs)) {
11057 error(JSMSG_BAD_SUPER);
11058 return errorResult();
11059 }
11060
11061 return lhs;
11062}
11063
11064template <class ParseHandler, typename Unit>
11065typename ParseHandler::NodeResult
11066GeneralParser<ParseHandler, Unit>::decoratorExpr(YieldHandling yieldHandling,
11067 TokenKind tt) {
11068 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11068); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 11068; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11069
11070 AutoCheckRecursionLimit recursion(this->fc_);
11071 if (!recursion.check(this->fc_)) {
11072 return errorResult();
11073 }
11074
11075 if (tt == TokenKind::LeftParen) {
11076 // DecoratorParenthesizedExpression
11077 Node expr;
11078 MOZ_TRY_VAR(expr, exprInParens(InAllowed, yieldHandling, TripledotAllowed,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (expr) = mozTryVarTempResult_.unwrap(); } while (0)
11079 /* possibleError*/ nullptr))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (expr) = mozTryVarTempResult_.unwrap(); } while (0)
;
11080 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_DECORATOR)) {
11081 return errorResult();
11082 }
11083
11084 return handler_.parenthesize(expr);
11085 }
11086
11087 if (!TokenKindIsPossibleIdentifier(tt)) {
11088 error(JSMSG_DECORATOR_NAME_EXPECTED);
11089 return errorResult();
11090 }
11091
11092 TaggedParserAtomIndex name = identifierReference(yieldHandling);
11093 if (!name) {
11094 return errorResult();
11095 }
11096
11097 Node lhs;
11098 MOZ_TRY_VAR(lhs, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11099
11100 while (true) {
11101 if (!tokenStream.getToken(&tt)) {
11102 return errorResult();
11103 }
11104 if (tt == TokenKind::Eof) {
11105 anyChars.ungetToken();
11106 break;
11107 }
11108
11109 Node nextMember;
11110 if (tt == TokenKind::Dot) {
11111 if (!tokenStream.getToken(&tt)) {
11112 return errorResult();
11113 }
11114
11115 if (TokenKindIsPossibleIdentifierName(tt)) {
11116 MOZ_TRY_VAR(nextMember, memberPropertyAccess(lhs))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nextMember)
= mozTryVarTempResult_.unwrap(); } while (0)
;
11117 } else if (tt == TokenKind::PrivateName) {
11118 MOZ_TRY_VAR(nextMember, memberPrivateAccess(lhs))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (nextMember) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11119 } else {
11120 error(JSMSG_NAME_AFTER_DOT);
11121 return errorResult();
11122 }
11123 } else if (tt == TokenKind::LeftParen) {
11124 MOZ_TRY_VAR(nextMember, memberCall(tt, lhs, yieldHandling,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
11125 /* possibleError */ nullptr))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11126 lhs = nextMember;
11127 // This is a `DecoratorCallExpression` and it's defined at the top level
11128 // of `Decorator`, no other `DecoratorMemberExpression` is allowed to
11129 // follow after the arguments.
11130 break;
11131 } else {
11132 anyChars.ungetToken();
11133 break;
11134 }
11135
11136 lhs = nextMember;
11137 }
11138
11139 return lhs;
11140}
11141
11142template <class ParseHandler>
11143inline typename ParseHandler::NameNodeResult
11144PerHandlerParser<ParseHandler>::newName(TaggedParserAtomIndex name) {
11145 return newName(name, pos());
11146}
11147
11148template <class ParseHandler>
11149inline typename ParseHandler::NameNodeResult
11150PerHandlerParser<ParseHandler>::newName(TaggedParserAtomIndex name,
11151 TokenPos pos) {
11152 if (name == TaggedParserAtomIndex::WellKnown::arguments()) {
11153 this->pc_->numberOfArgumentsNames++;
11154 }
11155 return handler_.newName(name, pos);
11156}
11157
11158template <class ParseHandler>
11159inline typename ParseHandler::NameNodeResult
11160PerHandlerParser<ParseHandler>::newPrivateName(TaggedParserAtomIndex name) {
11161 return handler_.newPrivateName(name, pos());
11162}
11163
11164template <class ParseHandler, typename Unit>
11165typename ParseHandler::NodeResult
11166GeneralParser<ParseHandler, Unit>::memberPropertyAccess(
11167 Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11168 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11169); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11169; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
11169 anyChars.currentToken().type == TokenKind::PrivateName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11169); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11169; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11170 TaggedParserAtomIndex field = anyChars.currentName();
11171 if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
11172 error(JSMSG_BAD_SUPERPROP, "property");
11173 return errorResult();
11174 }
11175
11176 NameNodeType name;
11177 MOZ_TRY_VAR(name, handler_.newPropertyName(field, pos()))do { auto mozTryVarTempResult_ = (handler_.newPropertyName(field
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (name
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11178
11179 if (optionalKind == OptionalKind::Optional) {
11180 MOZ_ASSERT(!handler_.isSuperBase(lhs))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!handler_.isSuperBase(lhs))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!handler_.isSuperBase(lhs)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!handler_.isSuperBase(lhs)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11180); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11180; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11181 return handler_.newOptionalPropertyAccess(lhs, name);
11182 }
11183
11184 if (handler_.isArgumentsName(lhs) && handler_.isLengthName(name)) {
11185 MOZ_ASSERT(pc_->numberOfArgumentsNames > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->numberOfArgumentsNames > 0)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(pc_->numberOfArgumentsNames > 0))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->numberOfArgumentsNames > 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11185); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->numberOfArgumentsNames > 0"
")"); do { *((volatile int*)__null) = 11185; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11186 pc_->numberOfArgumentsNames--;
11187 // Currently when resuming Generators don't get their argument length set
11188 // in the interpreter frame (see InterpreterStack::resumeGeneratorCallFrame,
11189 // and its call to initCallFrame).
11190 if (pc_->isGeneratorOrAsync()) {
11191 pc_->sc()->setIneligibleForArgumentsLength();
11192 }
11193 return handler_.newArgumentsLength(lhs, name);
11194 }
11195
11196 return handler_.newPropertyAccess(lhs, name);
11197}
11198
11199template <class ParseHandler, typename Unit>
11200typename ParseHandler::NodeResult
11201GeneralParser<ParseHandler, Unit>::memberPrivateAccess(
11202 Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11203 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::PrivateName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::PrivateName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::PrivateName
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"anyChars.currentToken().type == TokenKind::PrivateName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11203); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11203; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11204
11205 TaggedParserAtomIndex field = anyChars.currentName();
11206 // Cannot access private fields on super.
11207 if (handler_.isSuperBase(lhs)) {
11208 error(JSMSG_BAD_SUPERPRIVATE);
11209 return errorResult();
11210 }
11211
11212 NameNodeType privateName;
11213 MOZ_TRY_VAR(privateName, privateNameReference(field))do { auto mozTryVarTempResult_ = (privateNameReference(field)
); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)
)) { return mozTryVarTempResult_.propagateErr(); } (privateName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11214
11215 if (optionalKind == OptionalKind::Optional) {
11216 MOZ_ASSERT(!handler_.isSuperBase(lhs))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!handler_.isSuperBase(lhs))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!handler_.isSuperBase(lhs)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!handler_.isSuperBase(lhs)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11216); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11216; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11217 return handler_.newOptionalPrivateMemberAccess(lhs, privateName, pos().end);
11218 }
11219 return handler_.newPrivateMemberAccess(lhs, privateName, pos().end);
11220}
11221
11222template <class ParseHandler, typename Unit>
11223typename ParseHandler::NodeResult
11224GeneralParser<ParseHandler, Unit>::memberElemAccess(
11225 Node lhs, YieldHandling yieldHandling,
11226 OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11227 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::LeftBracket)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::LeftBracket
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::LeftBracket
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"anyChars.currentToken().type == TokenKind::LeftBracket", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11227); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::LeftBracket"
")"); do { *((volatile int*)__null) = 11227; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11228 Node propExpr;
11229 MOZ_TRY_VAR(propExpr, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
11230
11231 if (!mustMatchToken(TokenKind::RightBracket, JSMSG_BRACKET_IN_INDEX)) {
11232 return errorResult();
11233 }
11234
11235 if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
11236 error(JSMSG_BAD_SUPERPROP, "member");
11237 return errorResult();
11238 }
11239 if (optionalKind == OptionalKind::Optional) {
11240 MOZ_ASSERT(!handler_.isSuperBase(lhs))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!handler_.isSuperBase(lhs))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!handler_.isSuperBase(lhs)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!handler_.isSuperBase(lhs)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11240); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11240; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11241 return handler_.newOptionalPropertyByValue(lhs, propExpr, pos().end);
11242 }
11243 return handler_.newPropertyByValue(lhs, propExpr, pos().end);
11244}
11245
11246template <class ParseHandler, typename Unit>
11247typename ParseHandler::NodeResult
11248GeneralParser<ParseHandler, Unit>::memberSuperCall(
11249 Node lhs, YieldHandling yieldHandling) {
11250 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::LeftParen)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::LeftParen
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::LeftParen
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"anyChars.currentToken().type == TokenKind::LeftParen", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11250); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::LeftParen"
")"); do { *((volatile int*)__null) = 11250; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11251 // Despite the fact that it's impossible to have |super()| in a
11252 // generator, we still inherit the yieldHandling of the
11253 // memberExpression, per spec. Curious.
11254 bool isSpread = false;
11255 ListNodeType args;
11256 MOZ_TRY_VAR(args, argumentList(yieldHandling, &isSpread))do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (args) = mozTryVarTempResult_.unwrap(); } while (0)
;
11257
11258 CallNodeType superCall;
11259 MOZ_TRY_VAR(superCall, handler_.newSuperCall(lhs, args, isSpread))do { auto mozTryVarTempResult_ = (handler_.newSuperCall(lhs, args
, isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (superCall
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11260
11261 // |super()| implicitly reads |new.target|.
11262 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
11263 return errorResult();
11264 }
11265
11266 NameNodeType thisName;
11267 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
11268
11269 return handler_.newSetThis(thisName, superCall);
11270}
11271
11272template <class ParseHandler, typename Unit>
11273typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::memberCall(
11274 TokenKind tt, Node lhs, YieldHandling yieldHandling,
11275 PossibleError* possibleError /* = nullptr */,
11276 OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11277 if (options().selfHostingMode &&
11278 (handler_.isPropertyOrPrivateMemberAccess(lhs) ||
11279 handler_.isOptionalPropertyOrPrivateMemberAccess(lhs))) {
11280 error(JSMSG_SELFHOSTED_METHOD_CALL);
11281 return errorResult();
11282 }
11283
11284 MOZ_ASSERT(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead
|| tt == TokenKind::NoSubsTemplate)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::LeftParen ||
tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
" (" "Unexpected token kind for member call" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11286; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
11285 tt == TokenKind::NoSubsTemplate,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead
|| tt == TokenKind::NoSubsTemplate)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::LeftParen ||
tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
" (" "Unexpected token kind for member call" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11286; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
11286 "Unexpected token kind for member call")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead
|| tt == TokenKind::NoSubsTemplate)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::LeftParen ||
tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
" (" "Unexpected token kind for member call" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11286; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
11287
11288 JSOp op = JSOp::Call;
11289 bool maybeAsyncArrow = false;
11290 if (tt == TokenKind::LeftParen && optionalKind == OptionalKind::NonOptional) {
11291 if (handler_.isAsyncKeyword(lhs)) {
11292 // |async (| can be the start of an async arrow
11293 // function, so we need to defer reporting possible
11294 // errors from destructuring syntax. To give better
11295 // error messages, we only allow the AsyncArrowHead
11296 // part of the CoverCallExpressionAndAsyncArrowHead
11297 // syntax when the initial name is "async".
11298 maybeAsyncArrow = true;
11299 } else if (handler_.isEvalName(lhs)) {
11300 // Select the right Eval op and flag pc_ as having a
11301 // direct eval.
11302 op = pc_->sc()->strict() ? JSOp::StrictEval : JSOp::Eval;
11303 pc_->sc()->setBindingsAccessedDynamically();
11304 pc_->sc()->setHasDirectEval();
11305
11306 // In non-strict mode code, direct calls to eval can
11307 // add variables to the call object.
11308 if (pc_->isFunctionBox() && !pc_->sc()->strict()) {
11309 pc_->functionBox()->setFunHasExtensibleScope();
11310 }
11311
11312 // If we're in a method, mark the method as requiring
11313 // support for 'super', since direct eval code can use
11314 // it. (If we're not in a method, that's fine, so
11315 // ignore the return value.)
11316 checkAndMarkSuperScope();
11317 }
11318 }
11319
11320 if (tt == TokenKind::LeftParen) {
11321 bool isSpread = false;
11322 PossibleError* asyncPossibleError =
11323 maybeAsyncArrow ? possibleError : nullptr;
11324 ListNodeType args;
11325 MOZ_TRY_VAR(args,do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread, asyncPossibleError)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (args) = mozTryVarTempResult_.unwrap(); } while
(0)
11326 argumentList(yieldHandling, &isSpread, asyncPossibleError))do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread, asyncPossibleError)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (args) = mozTryVarTempResult_.unwrap(); } while
(0)
;
11327 if (isSpread) {
11328 if (op == JSOp::Eval) {
11329 op = JSOp::SpreadEval;
11330 } else if (op == JSOp::StrictEval) {
11331 op = JSOp::StrictSpreadEval;
11332 } else {
11333 op = JSOp::SpreadCall;
11334 }
11335 }
11336
11337 if (optionalKind == OptionalKind::Optional) {
11338 return handler_.newOptionalCall(lhs, args, op);
11339 }
11340 return handler_.newCall(lhs, args, op);
11341 }
11342
11343 ListNodeType args;
11344 MOZ_TRY_VAR(args, handler_.newArguments(pos()))do { auto mozTryVarTempResult_ = (handler_.newArguments(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (args) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11345
11346 if (!taggedTemplate(yieldHandling, args, tt)) {
11347 return errorResult();
11348 }
11349
11350 if (optionalKind == OptionalKind::Optional) {
11351 error(JSMSG_BAD_OPTIONAL_TEMPLATE);
11352 return errorResult();
11353 }
11354
11355 return handler_.newTaggedTemplate(lhs, args, op);
11356}
11357
11358template <class ParseHandler, typename Unit>
11359bool GeneralParser<ParseHandler, Unit>::checkLabelOrIdentifierReference(
11360 TaggedParserAtomIndex ident, uint32_t offset, YieldHandling yieldHandling,
11361 TokenKind hint /* = TokenKind::Limit */) {
11362 TokenKind tt;
11363 if (hint == TokenKind::Limit) {
11364 tt = ReservedWordTokenKind(ident);
11365 } else {
11366 // All non-reserved word kinds are folded into TokenKind::Limit in
11367 // ReservedWordTokenKind and the following code.
11368 if (hint == TokenKind::Name || hint == TokenKind::PrivateName) {
11369 hint = TokenKind::Limit;
11370 }
11371 MOZ_ASSERT(hint == ReservedWordTokenKind(ident),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hint == ReservedWordTokenKind(ident))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hint == ReservedWordTokenKind
(ident)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("hint == ReservedWordTokenKind(ident)" " (" "hint doesn't match actual token kind"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hint == ReservedWordTokenKind(ident)"
") (" "hint doesn't match actual token kind" ")"); do { *((volatile
int*)__null) = 11372; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
11372 "hint doesn't match actual token kind")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hint == ReservedWordTokenKind(ident))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hint == ReservedWordTokenKind
(ident)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("hint == ReservedWordTokenKind(ident)" " (" "hint doesn't match actual token kind"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hint == ReservedWordTokenKind(ident)"
") (" "hint doesn't match actual token kind" ")"); do { *((volatile
int*)__null) = 11372; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
11373 tt = hint;
11374 }
11375
11376 if (!pc_->sc()->allowArguments() &&
11377 ident == TaggedParserAtomIndex::WellKnown::arguments()) {
11378 error(JSMSG_BAD_ARGUMENTS);
11379 return false;
11380 }
11381
11382 if (tt == TokenKind::Limit) {
11383 // Either TokenKind::Name or TokenKind::PrivateName
11384 return true;
11385 }
11386 if (TokenKindIsContextualKeyword(tt)) {
11387 if (tt == TokenKind::Yield) {
11388 if (yieldHandling == YieldIsKeyword) {
11389 errorAt(offset, JSMSG_RESERVED_ID, "yield");
11390 return false;
11391 }
11392 if (pc_->sc()->strict()) {
11393 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "yield")) {
11394 return false;
11395 }
11396 }
11397 return true;
11398 }
11399 if (tt == TokenKind::Await) {
11400 if (awaitIsKeyword() || awaitIsDisallowed()) {
11401 errorAt(offset, JSMSG_RESERVED_ID, "await");
11402 return false;
11403 }
11404 return true;
11405 }
11406 if (pc_->sc()->strict()) {
11407 if (tt == TokenKind::Let) {
11408 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "let")) {
11409 return false;
11410 }
11411 return true;
11412 }
11413 if (tt == TokenKind::Static) {
11414 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "static")) {
11415 return false;
11416 }
11417 return true;
11418 }
11419 }
11420 return true;
11421 }
11422 if (TokenKindIsStrictReservedWord(tt)) {
11423 if (pc_->sc()->strict()) {
11424 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID,
11425 ReservedWordToCharZ(tt))) {
11426 return false;
11427 }
11428 }
11429 return true;
11430 }
11431 if (TokenKindIsKeyword(tt) || TokenKindIsReservedWordLiteral(tt)) {
11432 errorAt(offset, JSMSG_INVALID_ID, ReservedWordToCharZ(tt));
11433 return false;
11434 }
11435 if (TokenKindIsFutureReservedWord(tt)) {
11436 errorAt(offset, JSMSG_RESERVED_ID, ReservedWordToCharZ(tt));
11437 return false;
11438 }
11439 MOZ_ASSERT_UNREACHABLE("Unexpected reserved word kind.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Unexpected reserved word kind." ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11439); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected reserved word kind." ")"
); do { *((volatile int*)__null) = 11439; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
11440 return false;
11441}
11442
11443template <class ParseHandler, typename Unit>
11444bool GeneralParser<ParseHandler, Unit>::checkBindingIdentifier(
11445 TaggedParserAtomIndex ident, uint32_t offset, YieldHandling yieldHandling,
11446 TokenKind hint /* = TokenKind::Limit */) {
11447 if (pc_->sc()->strict()) {
11448 if (ident == TaggedParserAtomIndex::WellKnown::arguments()) {
11449 if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "arguments")) {
11450 return false;
11451 }
11452 return true;
11453 }
11454
11455 if (ident == TaggedParserAtomIndex::WellKnown::eval()) {
11456 if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "eval")) {
11457 return false;
11458 }
11459 return true;
11460 }
11461 }
11462
11463 return checkLabelOrIdentifierReference(ident, offset, yieldHandling, hint);
11464}
11465
11466template <class ParseHandler, typename Unit>
11467TaggedParserAtomIndex
11468GeneralParser<ParseHandler, Unit>::labelOrIdentifierReference(
11469 YieldHandling yieldHandling) {
11470 // ES 2017 draft 12.1.1.
11471 // StringValue of IdentifierName normalizes any Unicode escape sequences
11472 // in IdentifierName hence such escapes cannot be used to write an
11473 // Identifier whose code point sequence is the same as a ReservedWord.
11474 //
11475 // Use const ParserName* instead of TokenKind to reflect the normalization.
11476
11477 // Unless the name contains escapes, we can reuse the current TokenKind
11478 // to determine if the name is a restricted identifier.
11479 TokenKind hint = !anyChars.currentNameHasEscapes(this->parserAtoms())
11480 ? anyChars.currentToken().type
11481 : TokenKind::Limit;
11482 TaggedParserAtomIndex ident = anyChars.currentName();
11483 if (!checkLabelOrIdentifierReference(ident, pos().begin, yieldHandling,
11484 hint)) {
11485 return TaggedParserAtomIndex::null();
11486 }
11487 return ident;
11488}
11489
11490template <class ParseHandler, typename Unit>
11491TaggedParserAtomIndex GeneralParser<ParseHandler, Unit>::bindingIdentifier(
11492 YieldHandling yieldHandling) {
11493 TokenKind hint = !anyChars.currentNameHasEscapes(this->parserAtoms())
11494 ? anyChars.currentToken().type
11495 : TokenKind::Limit;
11496 TaggedParserAtomIndex ident = anyChars.currentName();
11497 if (!checkBindingIdentifier(ident, pos().begin, yieldHandling, hint)) {
11498 return TaggedParserAtomIndex::null();
11499 }
11500 return ident;
11501}
11502
11503template <class ParseHandler>
11504typename ParseHandler::NameNodeResult
11505PerHandlerParser<ParseHandler>::identifierReference(
11506 TaggedParserAtomIndex name) {
11507 NameNodeType id;
11508 MOZ_TRY_VAR(id, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (id) = mozTryVarTempResult_.unwrap(); } while
(0)
;
11509
11510 if (!noteUsedName(name)) {
11511 return errorResult();
11512 }
11513
11514 return id;
11515}
11516
11517template <class ParseHandler>
11518typename ParseHandler::NameNodeResult
11519PerHandlerParser<ParseHandler>::privateNameReference(
11520 TaggedParserAtomIndex name) {
11521 NameNodeType id;
11522 MOZ_TRY_VAR(id, newPrivateName(name))do { auto mozTryVarTempResult_ = (newPrivateName(name)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (id) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11523
11524 if (!noteUsedName(name, NameVisibility::Private, Some(pos()))) {
11525 return errorResult();
11526 }
11527
11528 return id;
11529}
11530
11531template <class ParseHandler>
11532typename ParseHandler::NameNodeResult
11533PerHandlerParser<ParseHandler>::stringLiteral() {
11534 return handler_.newStringLiteral(anyChars.currentToken().atom(), pos());
11535}
11536
11537template <class ParseHandler>
11538typename ParseHandler::NodeResult
11539PerHandlerParser<ParseHandler>::noSubstitutionTaggedTemplate() {
11540 if (anyChars.hasInvalidTemplateEscape()) {
11541 anyChars.clearInvalidTemplateEscape();
11542 return handler_.newRawUndefinedLiteral(pos());
11543 }
11544
11545 return handler_.newTemplateStringLiteral(anyChars.currentToken().atom(),
11546 pos());
11547}
11548
11549template <class ParseHandler, typename Unit>
11550typename ParseHandler::NameNodeResult
11551GeneralParser<ParseHandler, Unit>::noSubstitutionUntaggedTemplate() {
11552 if (!tokenStream.checkForInvalidTemplateEscapeError()) {
11553 return errorResult();
11554 }
11555
11556 return handler_.newTemplateStringLiteral(anyChars.currentToken().atom(),
11557 pos());
11558}
11559
11560template <typename Unit>
11561FullParseHandler::RegExpLiteralResult
11562Parser<FullParseHandler, Unit>::newRegExp() {
11563 MOZ_ASSERT(!options().selfHostingMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!options().selfHostingMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!options().selfHostingMode))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!options().selfHostingMode"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11563); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 11563; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11564
11565 // Create the regexp and check its syntax.
11566 const auto& chars = tokenStream.getCharBuffer();
11567 mozilla::Range<const char16_t> range(chars.begin(), chars.length());
11568 RegExpFlags flags = anyChars.currentToken().regExpFlags();
11569
11570 uint32_t offset = anyChars.currentToken().pos.begin;
11571 uint32_t line;
11572 JS::LimitedColumnNumberOneOrigin column;
11573 tokenStream.computeLineAndColumn(offset, &line, &column);
11574
11575 if (!handler_.reuseRegexpSyntaxParse()) {
11576 // Verify that the Regexp will syntax parse when the time comes to
11577 // instantiate it. If we have already done a syntax parse, we can
11578 // skip this.
11579 if (!irregexp::CheckPatternSyntax(
11580 this->alloc_, this->fc_->stackLimit(), anyChars, range, flags,
11581 Some(line), Some(JS::ColumnNumberOneOrigin(column)))) {
11582 return errorResult();
11583 }
11584 }
11585
11586 auto atom =
11587 this->parserAtoms().internChar16(fc_, chars.begin(), chars.length());
11588 if (!atom) {
11589 return errorResult();
11590 }
11591 // RegExp patterm must be atomized.
11592 this->parserAtoms().markUsedByStencil(atom, ParserAtom::Atomize::Yes);
11593
11594 RegExpIndex index(this->compilationState_.regExpData.length());
11595 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
11596 ReportAllocationOverflow(fc_);
11597 return errorResult();
11598 }
11599 if (!this->compilationState_.regExpData.emplaceBack(atom, flags)) {
11600 js::ReportOutOfMemory(this->fc_);
11601 return errorResult();
11602 }
11603
11604 return handler_.newRegExp(index, pos());
11605}
11606
11607template <typename Unit>
11608SyntaxParseHandler::RegExpLiteralResult
11609Parser<SyntaxParseHandler, Unit>::newRegExp() {
11610 MOZ_ASSERT(!options().selfHostingMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!options().selfHostingMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!options().selfHostingMode))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!options().selfHostingMode"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 11610; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11611
11612 // Only check the regexp's syntax, but don't create a regexp object.
11613 const auto& chars = tokenStream.getCharBuffer();
11614 RegExpFlags flags = anyChars.currentToken().regExpFlags();
11615
11616 uint32_t offset = anyChars.currentToken().pos.begin;
11617 uint32_t line;
11618 JS::LimitedColumnNumberOneOrigin column;
11619 tokenStream.computeLineAndColumn(offset, &line, &column);
11620
11621 mozilla::Range<const char16_t> source(chars.begin(), chars.length());
11622 if (!irregexp::CheckPatternSyntax(this->alloc_, this->fc_->stackLimit(),
11623 anyChars, source, flags, Some(line),
11624 Some(JS::ColumnNumberOneOrigin(column)))) {
11625 return errorResult();
11626 }
11627
11628 return handler_.newRegExp(SyntaxParseHandler::Node::NodeGeneric, pos());
11629}
11630
11631template <class ParseHandler, typename Unit>
11632typename ParseHandler::RegExpLiteralResult
11633GeneralParser<ParseHandler, Unit>::newRegExp() {
11634 return asFinalParser()->newRegExp();
11635}
11636
11637template <typename Unit>
11638FullParseHandler::BigIntLiteralResult
11639Parser<FullParseHandler, Unit>::newBigInt() {
11640 // The token's charBuffer contains the DecimalIntegerLiteral or
11641 // NonDecimalIntegerLiteral production, and as such does not include the
11642 // BigIntLiteralSuffix (the trailing "n"). Note that NonDecimalIntegerLiteral
11643 // productions start with 0[bBoOxX], indicating binary/octal/hex.
11644 const auto& chars = tokenStream.getCharBuffer();
11645 if (chars.length() > UINT32_MAX(4294967295U)) {
11646 ReportAllocationOverflow(fc_);
11647 return errorResult();
11648 }
11649
11650 BigIntIndex index(this->compilationState_.bigIntData.length());
11651 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
11652 ReportAllocationOverflow(fc_);
11653 return errorResult();
11654 }
11655 if (!this->compilationState_.bigIntData.emplaceBack()) {
11656 js::ReportOutOfMemory(this->fc_);
11657 return errorResult();
11658 }
11659
11660 if (!this->compilationState_.bigIntData[index].init(
11661 this->fc_, this->stencilAlloc(), chars)) {
11662 return errorResult();
11663 }
11664
11665 bool isZero = this->compilationState_.bigIntData[index].isZero();
11666
11667 // Should the operations below fail, the buffer held by data will
11668 // be cleaned up by the CompilationState destructor.
11669 return handler_.newBigInt(index, isZero, pos());
11670}
11671
11672template <typename Unit>
11673SyntaxParseHandler::BigIntLiteralResult
11674Parser<SyntaxParseHandler, Unit>::newBigInt() {
11675 // The tokenizer has already checked the syntax of the bigint.
11676
11677 return handler_.newBigInt();
11678}
11679
11680template <class ParseHandler, typename Unit>
11681typename ParseHandler::BigIntLiteralResult
11682GeneralParser<ParseHandler, Unit>::newBigInt() {
11683 return asFinalParser()->newBigInt();
11684}
11685
11686// |exprPossibleError| is the PossibleError state within |expr|,
11687// |possibleError| is the surrounding PossibleError state.
11688template <class ParseHandler, typename Unit>
11689bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentTarget(
11690 Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
11691 PossibleError* possibleError, TargetBehavior behavior) {
11692 // Report any pending expression error if we're definitely not in a
11693 // destructuring context or the possible destructuring target is a
11694 // property accessor.
11695 if (!possibleError || handler_.isPropertyOrPrivateMemberAccess(expr)) {
11696 return exprPossibleError->checkForExpressionError();
11697 }
11698
11699 // |expr| may end up as a destructuring assignment target, so we need to
11700 // validate it's either a name or can be parsed as a nested destructuring
11701 // pattern. Property accessors are also valid assignment targets, but
11702 // those are already handled above.
11703
11704 exprPossibleError->transferErrorsTo(possibleError);
11705
11706 // Return early if a pending destructuring error is already present.
11707 if (possibleError->hasPendingDestructuringError()) {
11708 return true;
11709 }
11710
11711 if (handler_.isName(expr)) {
11712 checkDestructuringAssignmentName(handler_.asNameNode(expr), exprPos,
11713 possibleError);
11714 return true;
11715 }
11716
11717 if (handler_.isUnparenthesizedDestructuringPattern(expr)) {
11718 if (behavior == TargetBehavior::ForbidAssignmentPattern) {
11719 possibleError->setPendingDestructuringErrorAt(exprPos,
11720 JSMSG_BAD_DESTRUCT_TARGET);
11721 }
11722 return true;
11723 }
11724
11725 // Parentheses are forbidden around destructuring *patterns* (but allowed
11726 // around names). Use our nicer error message for parenthesized, nested
11727 // patterns if nested destructuring patterns are allowed.
11728 if (handler_.isParenthesizedDestructuringPattern(expr) &&
11729 behavior != TargetBehavior::ForbidAssignmentPattern) {
11730 possibleError->setPendingDestructuringErrorAt(exprPos,
11731 JSMSG_BAD_DESTRUCT_PARENS);
11732 } else {
11733 possibleError->setPendingDestructuringErrorAt(exprPos,
11734 JSMSG_BAD_DESTRUCT_TARGET);
11735 }
11736
11737 return true;
11738}
11739
11740template <class ParseHandler, typename Unit>
11741void GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentName(
11742 NameNodeType name, TokenPos namePos, PossibleError* possibleError) {
11743#ifdef DEBUG1
11744 // GCC 8.0.1 crashes if this is a one-liner.
11745 bool isName = handler_.isName(name);
11746 MOZ_ASSERT(isName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isName)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(isName))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11746); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isName" ")"
); do { *((volatile int*)__null) = 11746; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
11747#endif
11748
11749 // Return early if a pending destructuring error is already present.
11750 if (possibleError->hasPendingDestructuringError()) {
11751 return;
11752 }
11753
11754 if (handler_.isArgumentsLength(name)) {
11755 pc_->sc()->setIneligibleForArgumentsLength();
11756 }
11757
11758 if (pc_->sc()->strict()) {
11759 if (handler_.isArgumentsName(name)) {
11760 if (pc_->sc()->strict()) {
11761 possibleError->setPendingDestructuringErrorAt(
11762 namePos, JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
11763 } else {
11764 possibleError->setPendingDestructuringWarningAt(
11765 namePos, JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
11766 }
11767 return;
11768 }
11769
11770 if (handler_.isEvalName(name)) {
11771 if (pc_->sc()->strict()) {
11772 possibleError->setPendingDestructuringErrorAt(
11773 namePos, JSMSG_BAD_STRICT_ASSIGN_EVAL);
11774 } else {
11775 possibleError->setPendingDestructuringWarningAt(
11776 namePos, JSMSG_BAD_STRICT_ASSIGN_EVAL);
11777 }
11778 return;
11779 }
11780 }
11781}
11782
11783template <class ParseHandler, typename Unit>
11784bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentElement(
11785 Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
11786 PossibleError* possibleError) {
11787 // ES2018 draft rev 0719f44aab93215ed9a626b2f45bd34f36916834
11788 // 12.15.5 Destructuring Assignment
11789 //
11790 // AssignmentElement[Yield, Await]:
11791 // DestructuringAssignmentTarget[?Yield, ?Await]
11792 // DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In,
11793 // ?Yield,
11794 // ?Await]
11795
11796 // If |expr| is an assignment element with an initializer expression, its
11797 // destructuring assignment target was already validated in assignExpr().
11798 // Otherwise we need to check that |expr| is a valid destructuring target.
11799 if (handler_.isUnparenthesizedAssignment(expr)) {
11800 // Report any pending expression error if we're definitely not in a
11801 // destructuring context.
11802 if (!possibleError) {
11803 return exprPossibleError->checkForExpressionError();
11804 }
11805
11806 exprPossibleError->transferErrorsTo(possibleError);
11807 return true;
11808 }
11809 return checkDestructuringAssignmentTarget(expr, exprPos, exprPossibleError,
11810 possibleError);
11811}
11812
11813template <class ParseHandler, typename Unit>
11814typename ParseHandler::ListNodeResult
11815GeneralParser<ParseHandler, Unit>::arrayInitializer(
11816 YieldHandling yieldHandling, PossibleError* possibleError) {
11817 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11817); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 11817; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11818
11819 uint32_t begin = pos().begin;
11820 ListNodeType literal;
11821 MOZ_TRY_VAR(literal, handler_.newArrayLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newArrayLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
11822
11823 TokenKind tt;
11824 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
11825 return errorResult();
11826 }
11827
11828 if (tt == TokenKind::RightBracket) {
11829 /*
11830 * Mark empty arrays as non-constant, since we cannot easily
11831 * determine their type.
11832 */
11833 handler_.setListHasNonConstInitializer(literal);
11834 } else {
11835 anyChars.ungetToken();
11836
11837 for (uint32_t index = 0;; index++) {
11838 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
11839 error(JSMSG_ARRAY_INIT_TOO_BIG);
11840 return errorResult();
11841 }
11842
11843 TokenKind tt;
11844 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
11845 return errorResult();
11846 }
11847 if (tt == TokenKind::RightBracket) {
11848 break;
11849 }
11850
11851 if (tt == TokenKind::Comma) {
11852 tokenStream.consumeKnownToken(TokenKind::Comma,
11853 TokenStream::SlashIsRegExp);
11854 if (!handler_.addElision(literal, pos())) {
11855 return errorResult();
11856 }
11857 continue;
11858 }
11859
11860 if (tt == TokenKind::TripleDot) {
11861 tokenStream.consumeKnownToken(TokenKind::TripleDot,
11862 TokenStream::SlashIsRegExp);
11863 uint32_t begin = pos().begin;
11864
11865 TokenPos innerPos;
11866 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
11867 return errorResult();
11868 }
11869
11870 PossibleError possibleErrorInner(*this);
11871 Node inner;
11872 MOZ_TRY_VAR(inner,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
11873 assignExpr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
11874 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
;
11875 if (!checkDestructuringAssignmentTarget(
11876 inner, innerPos, &possibleErrorInner, possibleError)) {
11877 return errorResult();
11878 }
11879
11880 if (!handler_.addSpreadElement(literal, begin, inner)) {
11881 return errorResult();
11882 }
11883 } else {
11884 TokenPos elementPos;
11885 if (!tokenStream.peekTokenPos(&elementPos,
11886 TokenStream::SlashIsRegExp)) {
11887 return errorResult();
11888 }
11889
11890 PossibleError possibleErrorInner(*this);
11891 Node element;
11892 MOZ_TRY_VAR(element,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (element) = mozTryVarTempResult_.unwrap();
} while (0)
11893 assignExpr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (element) = mozTryVarTempResult_.unwrap();
} while (0)
11894 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (element) = mozTryVarTempResult_.unwrap();
} while (0)
;
11895 if (!checkDestructuringAssignmentElement(
11896 element, elementPos, &possibleErrorInner, possibleError)) {
11897 return errorResult();
11898 }
11899 handler_.addArrayElement(literal, element);
11900 }
11901
11902 bool matched;
11903 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
11904 TokenStream::SlashIsRegExp)) {
11905 return errorResult();
11906 }
11907 if (!matched) {
11908 break;
11909 }
11910
11911 if (tt == TokenKind::TripleDot && possibleError) {
11912 possibleError->setPendingDestructuringErrorAt(pos(),
11913 JSMSG_REST_WITH_COMMA);
11914 }
11915 }
11916
11917 if (!mustMatchToken(
11918 TokenKind::RightBracket, [this, begin](TokenKind actual) {
11919 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
11920 JSMSG_BRACKET_OPENED, begin);
11921 })) {
11922 return errorResult();
11923 }
11924 }
11925
11926 handler_.setEndPosition(literal, pos().end);
11927 return literal;
11928}
11929
11930template <class ParseHandler, typename Unit>
11931typename ParseHandler::NodeResult
11932GeneralParser<ParseHandler, Unit>::propertyName(
11933 YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
11934 const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
11935 TaggedParserAtomIndex* propAtomOut) {
11936 // PropertyName[Yield, Await]:
11937 // LiteralPropertyName
11938 // ComputedPropertyName[?Yield, ?Await]
11939 //
11940 // LiteralPropertyName:
11941 // IdentifierName
11942 // StringLiteral
11943 // NumericLiteral
11944 TokenKind ltok = anyChars.currentToken().type;
11945
11946 *propAtomOut = TaggedParserAtomIndex::null();
11947 switch (ltok) {
11948 case TokenKind::Number: {
11949 auto numAtom = NumberToParserAtom(fc_, this->parserAtoms(),
11950 anyChars.currentToken().number());
11951 if (!numAtom) {
11952 return errorResult();
11953 }
11954 *propAtomOut = numAtom;
11955 return newNumber(anyChars.currentToken());
11956 }
11957
11958 case TokenKind::BigInt: {
11959 Node biNode;
11960 MOZ_TRY_VAR(biNode, newBigInt())do { auto mozTryVarTempResult_ = (newBigInt()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (biNode) = mozTryVarTempResult_.unwrap(); }
while (0)
;
11961 return handler_.newSyntheticComputedName(biNode, pos().begin, pos().end);
11962 }
11963 case TokenKind::String: {
11964 auto str = anyChars.currentToken().atom();
11965 *propAtomOut = str;
11966 uint32_t index;
11967 if (this->parserAtoms().isIndex(str, &index)) {
11968 return handler_.newNumber(index, NoDecimal, pos());
11969 }
11970 return stringLiteral();
11971 }
11972
11973 case TokenKind::LeftBracket:
11974 return computedPropertyName(yieldHandling, maybeDecl, propertyNameContext,
11975 propList);
11976
11977 case TokenKind::PrivateName: {
11978 if (propertyNameContext != PropertyNameContext::PropertyNameInClass) {
11979 error(JSMSG_ILLEGAL_PRIVATE_FIELD);
11980 return errorResult();
11981 }
11982
11983 TaggedParserAtomIndex propName = anyChars.currentName();
11984 *propAtomOut = propName;
11985 return privateNameReference(propName);
11986 }
11987
11988 default: {
11989 if (!TokenKindIsPossibleIdentifierName(ltok)) {
11990 error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(ltok));
11991 return errorResult();
11992 }
11993
11994 TaggedParserAtomIndex name = anyChars.currentName();
11995 *propAtomOut = name;
11996 return handler_.newObjectLiteralPropertyName(name, pos());
11997 }
11998 }
11999}
12000
12001// True if `kind` can be the first token of a PropertyName.
12002static bool TokenKindCanStartPropertyName(TokenKind tt) {
12003 return TokenKindIsPossibleIdentifierName(tt) || tt == TokenKind::String ||
12004 tt == TokenKind::Number || tt == TokenKind::LeftBracket ||
12005 tt == TokenKind::Mul || tt == TokenKind::BigInt ||
12006 tt == TokenKind::PrivateName;
12007}
12008
12009template <class ParseHandler, typename Unit>
12010typename ParseHandler::NodeResult
12011GeneralParser<ParseHandler, Unit>::propertyOrMethodName(
12012 YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
12013 const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
12014 PropertyType* propType, TaggedParserAtomIndex* propAtomOut) {
12015 // We're parsing an object literal, class, or destructuring pattern;
12016 // propertyNameContext tells which one. This method parses any of the
12017 // following, storing the corresponding PropertyType in `*propType` to tell
12018 // the caller what we parsed:
12019 //
12020 // async [no LineTerminator here] PropertyName
12021 // ==> PropertyType::AsyncMethod
12022 // async [no LineTerminator here] * PropertyName
12023 // ==> PropertyType::AsyncGeneratorMethod
12024 // * PropertyName ==> PropertyType::GeneratorMethod
12025 // get PropertyName ==> PropertyType::Getter
12026 // set PropertyName ==> PropertyType::Setter
12027 // accessor PropertyName ==> PropertyType::FieldWithAccessor
12028 // PropertyName : ==> PropertyType::Normal
12029 // PropertyName ==> see below
12030 //
12031 // In the last case, where there's not a `:` token to consume, we peek at
12032 // (but don't consume) the next token to decide how to set `*propType`.
12033 //
12034 // `,` or `}` ==> PropertyType::Shorthand
12035 // `(` ==> PropertyType::Method
12036 // `=`, not in a class ==> PropertyType::CoverInitializedName
12037 // '=', in a class ==> PropertyType::Field
12038 // any token, in a class ==> PropertyType::Field (ASI)
12039 //
12040 // The caller must check `*propType` and throw if whatever we parsed isn't
12041 // allowed here (for example, a getter in a destructuring pattern).
12042 //
12043 // This method does *not* match `static` (allowed in classes) or `...`
12044 // (allowed in object literals and patterns). The caller must take care of
12045 // those before calling this method.
12046
12047 TokenKind ltok;
12048 if (!tokenStream.getToken(&ltok, TokenStream::SlashIsInvalid)) {
12049 return errorResult();
12050 }
12051
12052 MOZ_ASSERT(ltok != TokenKind::RightCurly,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ltok != TokenKind::RightCurly)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(ltok != TokenKind::RightCurly
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"ltok != TokenKind::RightCurly" " (" "caller should have handled TokenKind::RightCurly"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12053); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ltok != TokenKind::RightCurly"
") (" "caller should have handled TokenKind::RightCurly" ")"
); do { *((volatile int*)__null) = 12053; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
12053 "caller should have handled TokenKind::RightCurly")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ltok != TokenKind::RightCurly)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(ltok != TokenKind::RightCurly
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"ltok != TokenKind::RightCurly" " (" "caller should have handled TokenKind::RightCurly"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12053); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ltok != TokenKind::RightCurly"
") (" "caller should have handled TokenKind::RightCurly" ")"
); do { *((volatile int*)__null) = 12053; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
12054
12055 // Accept `async` and/or `*`, indicating an async or generator method;
12056 // or `get` or `set` or `accessor`, indicating an accessor.
12057 bool isGenerator = false;
12058 bool isAsync = false;
12059 bool isGetter = false;
12060 bool isSetter = false;
12061#ifdef ENABLE_DECORATORS
12062 bool hasAccessor = false;
12063#endif
12064
12065 if (ltok == TokenKind::Async) {
12066 // `async` is also a PropertyName by itself (it's a conditional keyword),
12067 // so peek at the next token to see if we're really looking at a method.
12068 TokenKind tt = TokenKind::Eof;
12069 if (!tokenStream.peekTokenSameLine(&tt)) {
12070 return errorResult();
12071 }
12072 if (TokenKindCanStartPropertyName(tt)) {
12073 isAsync = true;
12074 tokenStream.consumeKnownToken(tt);
12075 ltok = tt;
12076 }
12077 }
12078
12079 if (ltok == TokenKind::Mul) {
12080 isGenerator = true;
12081 if (!tokenStream.getToken(&ltok)) {
12082 return errorResult();
12083 }
12084 }
12085
12086 if (!isAsync && !isGenerator &&
12087 (ltok == TokenKind::Get || ltok == TokenKind::Set)) {
12088 // We have parsed |get| or |set|. Look for an accessor property
12089 // name next.
12090 TokenKind tt;
12091 if (!tokenStream.peekToken(&tt)) {
12092 return errorResult();
12093 }
12094 if (TokenKindCanStartPropertyName(tt)) {
12095 tokenStream.consumeKnownToken(tt);
12096 isGetter = (ltok == TokenKind::Get);
12097 isSetter = (ltok == TokenKind::Set);
12098 }
12099 }
12100
12101#ifdef ENABLE_DECORATORS
12102 if (!isGenerator && !isAsync && propertyNameContext == PropertyNameInClass &&
12103 ltok == TokenKind::Accessor) {
12104 MOZ_ASSERT(!isGetter && !isSetter)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!isGetter && !isSetter)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!isGetter && !isSetter
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!isGetter && !isSetter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12104); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!isGetter && !isSetter"
")"); do { *((volatile int*)__null) = 12104; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12105 TokenKind tt;
12106 if (!tokenStream.peekTokenSameLine(&tt)) {
12107 return errorResult();
12108 }
12109
12110 // The target rule is `accessor [no LineTerminator here]
12111 // ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt`
12112 if (TokenKindCanStartPropertyName(tt)) {
12113 tokenStream.consumeKnownToken(tt);
12114 hasAccessor = true;
12115 }
12116 }
12117#endif
12118
12119 Node propName;
12120 MOZ_TRY_VAR(propName, propertyName(yieldHandling, propertyNameContext,do { auto mozTryVarTempResult_ = (propertyName(yieldHandling,
propertyNameContext, maybeDecl, propList, propAtomOut)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propName) = mozTryVarTempResult_
.unwrap(); } while (0)
12121 maybeDecl, propList, propAtomOut))do { auto mozTryVarTempResult_ = (propertyName(yieldHandling,
propertyNameContext, maybeDecl, propList, propAtomOut)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propName) = mozTryVarTempResult_
.unwrap(); } while (0)
;
12122
12123 // Grab the next token following the property/method name.
12124 // (If this isn't a colon, we're going to either put it back or throw.)
12125 TokenKind tt;
12126 if (!tokenStream.getToken(&tt)) {
12127 return errorResult();
12128 }
12129
12130 if (tt == TokenKind::Colon) {
12131 if (isGenerator || isAsync || isGetter || isSetter
12132#ifdef ENABLE_DECORATORS
12133 || hasAccessor
12134#endif
12135 ) {
12136 error(JSMSG_BAD_PROP_ID);
12137 return errorResult();
12138 }
12139 *propType = PropertyType::Normal;
12140 return propName;
12141 }
12142
12143 if (propertyNameContext != PropertyNameInClass &&
12144 TokenKindIsPossibleIdentifierName(ltok) &&
12145 (tt == TokenKind::Comma || tt == TokenKind::RightCurly ||
12146 tt == TokenKind::Assign)) {
12147#ifdef ENABLE_DECORATORS
12148 MOZ_ASSERT(!hasAccessor)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!hasAccessor)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!hasAccessor))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!hasAccessor", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12148); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!hasAccessor"
")"); do { *((volatile int*)__null) = 12148; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12149#endif
12150 if (isGenerator || isAsync || isGetter || isSetter) {
12151 error(JSMSG_BAD_PROP_ID);
12152 return errorResult();
12153 }
12154
12155 anyChars.ungetToken();
12156 *propType = tt == TokenKind::Assign ? PropertyType::CoverInitializedName
12157 : PropertyType::Shorthand;
12158 return propName;
12159 }
12160
12161 if (tt == TokenKind::LeftParen) {
12162 anyChars.ungetToken();
12163
12164#ifdef ENABLE_RECORD_TUPLE
12165 if (propertyNameContext == PropertyNameInRecord) {
12166 // Record & Tuple proposal, section 7.1.1:
12167 // RecordPropertyDefinition doesn't cover methods
12168 error(JSMSG_BAD_PROP_ID);
12169 return errorResult();
12170 }
12171#endif
12172
12173#ifdef ENABLE_DECORATORS
12174 if (hasAccessor) {
12175 error(JSMSG_BAD_PROP_ID);
12176 return errorResult();
12177 }
12178#endif
12179
12180 if (isGenerator && isAsync) {
12181 *propType = PropertyType::AsyncGeneratorMethod;
12182 } else if (isGenerator) {
12183 *propType = PropertyType::GeneratorMethod;
12184 } else if (isAsync) {
12185 *propType = PropertyType::AsyncMethod;
12186 } else if (isGetter) {
12187 *propType = PropertyType::Getter;
12188 } else if (isSetter) {
12189 *propType = PropertyType::Setter;
12190 } else {
12191 *propType = PropertyType::Method;
12192 }
12193 return propName;
12194 }
12195
12196 if (propertyNameContext == PropertyNameInClass) {
12197 if (isGenerator || isAsync || isGetter || isSetter) {
12198 error(JSMSG_BAD_PROP_ID);
12199 return errorResult();
12200 }
12201 anyChars.ungetToken();
12202#ifdef ENABLE_DECORATORS
12203 if (!hasAccessor) {
12204 *propType = PropertyType::Field;
12205 } else {
12206 *propType = PropertyType::FieldWithAccessor;
12207 }
12208#else
12209 *propType = PropertyType::Field;
12210#endif
12211 return propName;
12212 }
12213
12214 error(JSMSG_COLON_AFTER_ID);
12215 return errorResult();
12216}
12217
12218template <class ParseHandler, typename Unit>
12219typename ParseHandler::UnaryNodeResult
12220GeneralParser<ParseHandler, Unit>::computedPropertyName(
12221 YieldHandling yieldHandling, const Maybe<DeclarationKind>& maybeDecl,
12222 PropertyNameContext propertyNameContext, ListNodeType literal) {
12223 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12223); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 12223; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12224
12225 uint32_t begin = pos().begin;
12226
12227 if (maybeDecl) {
12228 if (*maybeDecl == DeclarationKind::FormalParameter) {
12229 pc_->functionBox()->hasParameterExprs = true;
12230 }
12231 } else if (propertyNameContext ==
12232 PropertyNameContext::PropertyNameInLiteral) {
12233 handler_.setListHasNonConstInitializer(literal);
12234 }
12235
12236 Node assignNode;
12237 MOZ_TRY_VAR(assignNode,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assignNode) = mozTryVarTempResult_.unwrap(); } while (0)
12238 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assignNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
12239
12240 if (!mustMatchToken(TokenKind::RightBracket, JSMSG_COMP_PROP_UNTERM_EXPR)) {
12241 return errorResult();
12242 }
12243 return handler_.newComputedName(assignNode, begin, pos().end);
12244}
12245
12246template <class ParseHandler, typename Unit>
12247typename ParseHandler::ListNodeResult
12248GeneralParser<ParseHandler, Unit>::objectLiteral(YieldHandling yieldHandling,
12249 PossibleError* possibleError) {
12250 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12250); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 12250; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12251
12252 uint32_t openedPos = pos().begin;
12253
12254 ListNodeType literal;
12255 MOZ_TRY_VAR(literal, handler_.newObjectLiteral(pos().begin))do { auto mozTryVarTempResult_ = (handler_.newObjectLiteral(pos
().begin)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (literal
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12256
12257 bool seenPrototypeMutation = false;
12258 bool seenCoverInitializedName = false;
12259 Maybe<DeclarationKind> declKind = Nothing();
12260 TaggedParserAtomIndex propAtom;
12261 for (;;) {
12262 TokenKind tt;
12263 if (!tokenStream.peekToken(&tt)) {
12264 return errorResult();
12265 }
12266 if (tt == TokenKind::RightCurly) {
12267 break;
12268 }
12269
12270 if (tt == TokenKind::TripleDot) {
12271 tokenStream.consumeKnownToken(TokenKind::TripleDot);
12272 uint32_t begin = pos().begin;
12273
12274 TokenPos innerPos;
12275 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12276 return errorResult();
12277 }
12278
12279 PossibleError possibleErrorInner(*this);
12280 Node inner;
12281 MOZ_TRY_VAR(inner, assignExpr(InAllowed, yieldHandling,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
12282 TripledotProhibited, &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
;
12283 if (!checkDestructuringAssignmentTarget(
12284 inner, innerPos, &possibleErrorInner, possibleError,
12285 TargetBehavior::ForbidAssignmentPattern)) {
12286 return errorResult();
12287 }
12288 if (!handler_.addSpreadProperty(literal, begin, inner)) {
12289 return errorResult();
12290 }
12291 } else {
12292 TokenPos namePos = anyChars.nextToken().pos;
12293
12294 PropertyType propType;
12295 Node propName;
12296 MOZ_TRY_VAR(propName, propertyOrMethodName(do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInLiteral, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12297 yieldHandling, PropertyNameInLiteral, declKind,do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInLiteral, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12298 literal, &propType, &propAtom))do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInLiteral, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12299
12300 if (propType == PropertyType::Normal) {
12301 TokenPos exprPos;
12302 if (!tokenStream.peekTokenPos(&exprPos, TokenStream::SlashIsRegExp)) {
12303 return errorResult();
12304 }
12305
12306 PossibleError possibleErrorInner(*this);
12307 Node propExpr;
12308 MOZ_TRY_VAR(propExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
12309 assignExpr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
12310 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
;
12311
12312 if (!checkDestructuringAssignmentElement(
12313 propExpr, exprPos, &possibleErrorInner, possibleError)) {
12314 return errorResult();
12315 }
12316
12317 if (propAtom == TaggedParserAtomIndex::WellKnown::proto_()) {
12318 if (seenPrototypeMutation) {
12319 // Directly report the error when we're definitely not
12320 // in a destructuring context.
12321 if (!possibleError) {
12322 errorAt(namePos.begin, JSMSG_DUPLICATE_PROTO_PROPERTY);
12323 return errorResult();
12324 }
12325
12326 // Otherwise delay error reporting until we've
12327 // determined whether or not we're destructuring.
12328 possibleError->setPendingExpressionErrorAt(
12329 namePos, JSMSG_DUPLICATE_PROTO_PROPERTY);
12330 }
12331 seenPrototypeMutation = true;
12332
12333 // This occurs *only* if we observe PropertyType::Normal!
12334 // Only |__proto__: v| mutates [[Prototype]]. Getters,
12335 // setters, method/generator definitions, computed
12336 // property name versions of all of these, and shorthands
12337 // do not.
12338 if (!handler_.addPrototypeMutation(literal, namePos.begin,
12339 propExpr)) {
12340 return errorResult();
12341 }
12342 } else {
12343 BinaryNodeType propDef;
12344 MOZ_TRY_VAR(propDef,do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
12345 handler_.newPropertyDefinition(propName, propExpr))do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
;
12346
12347 handler_.addPropertyDefinition(literal, propDef);
12348 }
12349 } else if (propType == PropertyType::Shorthand) {
12350 /*
12351 * Support, e.g., |({x, y} = o)| as destructuring shorthand
12352 * for |({x: x, y: y} = o)|, and |var o = {x, y}| as
12353 * initializer shorthand for |var o = {x: x, y: y}|.
12354 */
12355 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12356 if (!name) {
12357 return errorResult();
12358 }
12359
12360 NameNodeType nameExpr;
12361 MOZ_TRY_VAR(nameExpr, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nameExpr) =
mozTryVarTempResult_.unwrap(); } while (0)
;
12362
12363 if (possibleError) {
12364 checkDestructuringAssignmentName(nameExpr, namePos, possibleError);
12365 }
12366
12367 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
12368 nameExpr)) {
12369 return errorResult();
12370 }
12371 } else if (propType == PropertyType::CoverInitializedName) {
12372 /*
12373 * Support, e.g., |({x=1, y=2} = o)| as destructuring
12374 * shorthand with default values, as per ES6 12.14.5
12375 */
12376 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12377 if (!name) {
12378 return errorResult();
12379 }
12380
12381 Node lhs;
12382 MOZ_TRY_VAR(lhs, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
12383
12384 tokenStream.consumeKnownToken(TokenKind::Assign);
12385
12386 if (!seenCoverInitializedName) {
12387 // "shorthand default" or "CoverInitializedName" syntax is
12388 // only valid in the case of destructuring.
12389 seenCoverInitializedName = true;
12390
12391 if (!possibleError) {
12392 // Destructuring defaults are definitely not allowed
12393 // in this object literal, because of something the
12394 // caller knows about the preceding code. For example,
12395 // maybe the preceding token is an operator:
12396 // |x + {y=z}|.
12397 error(JSMSG_COLON_AFTER_ID);
12398 return errorResult();
12399 }
12400
12401 // Here we set a pending error so that later in the parse,
12402 // once we've determined whether or not we're
12403 // destructuring, the error can be reported or ignored
12404 // appropriately.
12405 possibleError->setPendingExpressionErrorAt(pos(),
12406 JSMSG_COLON_AFTER_ID);
12407 }
12408
12409 if (const char* chars = nameIsArgumentsOrEval(lhs)) {
12410 // |chars| is "arguments" or "eval" here.
12411 if (!strictModeErrorAt(namePos.begin, JSMSG_BAD_STRICT_ASSIGN,
12412 chars)) {
12413 return errorResult();
12414 }
12415 }
12416
12417 if (handler_.isArgumentsLength(lhs)) {
12418 pc_->sc()->setIneligibleForArgumentsLength();
12419 }
12420
12421 Node rhs;
12422 MOZ_TRY_VAR(rhs,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
12423 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
12424
12425 BinaryNodeType propExpr;
12426 MOZ_TRY_VAR(propExpr, handler_.newAssignment(ParseNodeKind::AssignExpr,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
12427 lhs, rhs))do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
12428
12429 if (!handler_.addPropertyDefinition(literal, propName, propExpr)) {
12430 return errorResult();
12431 }
12432 } else {
12433 TaggedParserAtomIndex funName;
12434 bool hasStaticName =
12435 !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom;
12436 if (hasStaticName) {
12437 funName = propAtom;
12438
12439 if (propType == PropertyType::Getter ||
12440 propType == PropertyType::Setter) {
12441 funName = prefixAccessorName(propType, propAtom);
12442 if (!funName) {
12443 return errorResult();
12444 }
12445 }
12446 }
12447
12448 FunctionNodeType funNode;
12449 MOZ_TRY_VAR(funNode,do { auto mozTryVarTempResult_ = (methodDefinition(namePos.begin
, propType, funName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
12450 methodDefinition(namePos.begin, propType, funName))do { auto mozTryVarTempResult_ = (methodDefinition(namePos.begin
, propType, funName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
12451
12452 AccessorType atype = ToAccessorType(propType);
12453 if (!handler_.addObjectMethodDefinition(literal, propName, funNode,
12454 atype)) {
12455 return errorResult();
12456 }
12457
12458 if (possibleError) {
12459 possibleError->setPendingDestructuringErrorAt(
12460 namePos, JSMSG_BAD_DESTRUCT_TARGET);
12461 }
12462 }
12463 }
12464
12465 bool matched;
12466 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12467 TokenStream::SlashIsInvalid)) {
12468 return errorResult();
12469 }
12470 if (!matched) {
12471 break;
12472 }
12473 if (tt == TokenKind::TripleDot && possibleError) {
12474 possibleError->setPendingDestructuringErrorAt(pos(),
12475 JSMSG_REST_WITH_COMMA);
12476 }
12477 }
12478
12479 if (!mustMatchToken(
12480 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
12481 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
12482 JSMSG_CURLY_OPENED, openedPos);
12483 })) {
12484 return errorResult();
12485 }
12486
12487 handler_.setEndPosition(literal, pos().end);
12488 return literal;
12489}
12490
12491#ifdef ENABLE_RECORD_TUPLE
12492template <class ParseHandler, typename Unit>
12493typename ParseHandler::ListNodeResult
12494GeneralParser<ParseHandler, Unit>::recordLiteral(YieldHandling yieldHandling) {
12495 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::HashCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::HashCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::HashCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::HashCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12495); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::HashCurly)"
")"); do { *((volatile int*)__null) = 12495; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12496
12497 uint32_t openedPos = pos().begin;
12498
12499 ListNodeType literal;
12500 MOZ_TRY_VAR(literal, handler_.newRecordLiteral(pos().begin))do { auto mozTryVarTempResult_ = (handler_.newRecordLiteral(pos
().begin)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (literal
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12501
12502 TaggedParserAtomIndex propAtom;
12503 for (;;) {
12504 TokenKind tt;
12505 if (!tokenStream.peekToken(&tt)) {
12506 return errorResult();
12507 }
12508 if (tt == TokenKind::RightCurly) {
12509 break;
12510 }
12511
12512 if (tt == TokenKind::TripleDot) {
12513 tokenStream.consumeKnownToken(TokenKind::TripleDot);
12514 uint32_t begin = pos().begin;
12515
12516 TokenPos innerPos;
12517 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12518 return errorResult();
12519 }
12520
12521 Node inner;
12522 MOZ_TRY_VAR(inner,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
12523 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
;
12524
12525 if (!handler_.addSpreadProperty(literal, begin, inner)) {
12526 return errorResult();
12527 }
12528 } else {
12529 TokenPos namePos = anyChars.nextToken().pos;
12530
12531 PropertyType propType;
12532 Node propName;
12533 MOZ_TRY_VAR(propName,do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12534 propertyOrMethodName(yieldHandling, PropertyNameInRecord,do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12535 /* maybeDecl */ Nothing(), literal,do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12536 &propType, &propAtom))do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12537
12538 if (propType == PropertyType::Normal) {
12539 TokenPos exprPos;
12540 if (!tokenStream.peekTokenPos(&exprPos, TokenStream::SlashIsRegExp)) {
12541 return errorResult();
12542 }
12543
12544 Node propExpr;
12545 MOZ_TRY_VAR(propExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
12546 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
12547
12548 if (propAtom == TaggedParserAtomIndex::WellKnown::proto_()) {
12549 errorAt(namePos.begin, JSMSG_RECORD_NO_PROTO);
12550 return errorResult();
12551 }
12552
12553 BinaryNodeType propDef;
12554 MOZ_TRY_VAR(propDef,do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
12555 handler_.newPropertyDefinition(propName, propExpr))do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
;
12556
12557 handler_.addPropertyDefinition(literal, propDef);
12558 } else if (propType == PropertyType::Shorthand) {
12559 /*
12560 * Support |var o = #{x, y}| as initializer shorthand for
12561 * |var o = #{x: x, y: y}|.
12562 */
12563 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12564 if (!name) {
12565 return errorResult();
12566 }
12567
12568 NameNodeType nameExpr;
12569 MOZ_TRY_VAR(nameExpr, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nameExpr) =
mozTryVarTempResult_.unwrap(); } while (0)
;
12570
12571 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
12572 nameExpr)) {
12573 return errorResult();
12574 }
12575 } else {
12576 error(JSMSG_BAD_PROP_ID);
12577 return errorResult();
12578 }
12579 }
12580
12581 bool matched;
12582 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12583 TokenStream::SlashIsInvalid)) {
12584 return errorResult();
12585 }
12586 if (!matched) {
12587 break;
12588 }
12589 }
12590
12591 if (!mustMatchToken(
12592 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
12593 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
12594 JSMSG_CURLY_OPENED, openedPos);
12595 })) {
12596 return errorResult();
12597 }
12598
12599 handler_.setEndPosition(literal, pos().end);
12600 return literal;
12601}
12602
12603template <class ParseHandler, typename Unit>
12604typename ParseHandler::ListNodeResult
12605GeneralParser<ParseHandler, Unit>::tupleLiteral(YieldHandling yieldHandling) {
12606 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::HashBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::HashBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::HashBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::HashBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12606); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::HashBracket)"
")"); do { *((volatile int*)__null) = 12606; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12607
12608 uint32_t begin = pos().begin;
12609 ListNodeType literal;
12610 MOZ_TRY_VAR(literal, handler_.newTupleLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newTupleLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
12611
12612 for (uint32_t index = 0;; index++) {
12613 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
12614 error(JSMSG_ARRAY_INIT_TOO_BIG);
12615 return errorResult();
12616 }
12617
12618 TokenKind tt;
12619 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
12620 return errorResult();
12621 }
12622 if (tt == TokenKind::RightBracket) {
12623 break;
12624 }
12625
12626 if (tt == TokenKind::TripleDot) {
12627 tokenStream.consumeKnownToken(TokenKind::TripleDot,
12628 TokenStream::SlashIsRegExp);
12629 uint32_t begin = pos().begin;
12630
12631 TokenPos innerPos;
12632 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12633 return errorResult();
12634 }
12635
12636 Node inner;
12637 MOZ_TRY_VAR(inner,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
12638 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
;
12639
12640 if (!handler_.addSpreadElement(literal, begin, inner)) {
12641 return errorResult();
12642 }
12643 } else {
12644 TokenPos elementPos;
12645 if (!tokenStream.peekTokenPos(&elementPos, TokenStream::SlashIsRegExp)) {
12646 return errorResult();
12647 }
12648
12649 Node element;
12650 MOZ_TRY_VAR(element,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (element) = mozTryVarTempResult_.unwrap(); } while (0)
12651 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (element) = mozTryVarTempResult_.unwrap(); } while (0)
;
12652 handler_.addArrayElement(literal, element);
12653 }
12654
12655 bool matched;
12656 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12657 TokenStream::SlashIsRegExp)) {
12658 return errorResult();
12659 }
12660 if (!matched) {
12661 break;
12662 }
12663 }
12664
12665 if (!mustMatchToken(TokenKind::RightBracket, [this, begin](TokenKind actual) {
12666 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
12667 JSMSG_BRACKET_OPENED, begin);
12668 })) {
12669 return errorResult();
12670 }
12671
12672 handler_.setEndPosition(literal, pos().end);
12673 return literal;
12674}
12675#endif
12676
12677template <class ParseHandler, typename Unit>
12678typename ParseHandler::FunctionNodeResult
12679GeneralParser<ParseHandler, Unit>::methodDefinition(
12680 uint32_t toStringStart, PropertyType propType,
12681 TaggedParserAtomIndex funName) {
12682 FunctionSyntaxKind syntaxKind;
12683 switch (propType) {
12684 case PropertyType::Getter:
12685 syntaxKind = FunctionSyntaxKind::Getter;
12686 break;
12687
12688 case PropertyType::Setter:
12689 syntaxKind = FunctionSyntaxKind::Setter;
12690 break;
12691
12692 case PropertyType::Method:
12693 case PropertyType::GeneratorMethod:
12694 case PropertyType::AsyncMethod:
12695 case PropertyType::AsyncGeneratorMethod:
12696 syntaxKind = FunctionSyntaxKind::Method;
12697 break;
12698
12699 case PropertyType::Constructor:
12700 syntaxKind = FunctionSyntaxKind::ClassConstructor;
12701 break;
12702
12703 case PropertyType::DerivedConstructor:
12704 syntaxKind = FunctionSyntaxKind::DerivedClassConstructor;
12705 break;
12706
12707 default:
12708 MOZ_CRASH("unexpected property type")do { do { } while (false); MOZ_ReportCrash("" "unexpected property type"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12708); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected property type"
")"); do { *((volatile int*)__null) = 12708; __attribute__((
nomerge)) ::abort(); } while (false); } while (false)
;
12709 }
12710
12711 GeneratorKind generatorKind = (propType == PropertyType::GeneratorMethod ||
12712 propType == PropertyType::AsyncGeneratorMethod)
12713 ? GeneratorKind::Generator
12714 : GeneratorKind::NotGenerator;
12715
12716 FunctionAsyncKind asyncKind = (propType == PropertyType::AsyncMethod ||
12717 propType == PropertyType::AsyncGeneratorMethod)
12718 ? FunctionAsyncKind::AsyncFunction
12719 : FunctionAsyncKind::SyncFunction;
12720
12721 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
12722
12723 FunctionNodeType funNode;
12724 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12725
12726 return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
12727 funName, syntaxKind, generatorKind, asyncKind);
12728}
12729
12730template <class ParseHandler, typename Unit>
12731bool GeneralParser<ParseHandler, Unit>::tryNewTarget(
12732 NewTargetNodeType* newTarget) {
12733 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::New))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::New))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::New)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::New)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12733); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::New)"
")"); do { *((volatile int*)__null) = 12733; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12734
12735 *newTarget = null();
12736
12737 NullaryNodeType newHolder;
12738 MOZ_TRY_VAR_OR_RETURN(newHolder, handler_.newPosHolder(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newPosHolder(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (newHolder) = parserTryVarTempResult_
.unwrap(); } while (0)
;
12739
12740 uint32_t begin = pos().begin;
12741
12742 // |new| expects to look for an operand, so we will honor that.
12743 TokenKind next;
12744 if (!tokenStream.getToken(&next, TokenStream::SlashIsRegExp)) {
12745 return false;
12746 }
12747
12748 // Don't unget the token, since lookahead cannot handle someone calling
12749 // getToken() with a different modifier. Callers should inspect
12750 // currentToken().
12751 if (next != TokenKind::Dot) {
12752 return true;
12753 }
12754
12755 if (!tokenStream.getToken(&next)) {
12756 return false;
12757 }
12758 if (next != TokenKind::Target) {
12759 error(JSMSG_UNEXPECTED_TOKEN, "target", TokenKindToDesc(next));
12760 return false;
12761 }
12762
12763 if (!pc_->sc()->allowNewTarget()) {
12764 errorAt(begin, JSMSG_BAD_NEWTARGET);
12765 return false;
12766 }
12767
12768 NullaryNodeType targetHolder;
12769 MOZ_TRY_VAR_OR_RETURN(targetHolder, handler_.newPosHolder(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newPosHolder(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (targetHolder) = parserTryVarTempResult_
.unwrap(); } while (0)
;
12770
12771 NameNodeType newTargetName;
12772 MOZ_TRY_VAR_OR_RETURN(newTargetName, newNewTargetName(), false)do { auto parserTryVarTempResult_ = (newNewTargetName()); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (newTargetName) = parserTryVarTempResult_.
unwrap(); } while (0)
;
12773
12774 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newNewTarget(newHolder
, targetHolder, newTargetName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*newTarget) = parserTryVarTempResult_
.unwrap(); } while (0)
12775 *newTarget, handler_.newNewTarget(newHolder, targetHolder, newTargetName),do { auto parserTryVarTempResult_ = (handler_.newNewTarget(newHolder
, targetHolder, newTargetName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*newTarget) = parserTryVarTempResult_
.unwrap(); } while (0)
12776 false)do { auto parserTryVarTempResult_ = (handler_.newNewTarget(newHolder
, targetHolder, newTargetName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*newTarget) = parserTryVarTempResult_
.unwrap(); } while (0)
;
12777
12778 return true;
12779}
12780
12781template <class ParseHandler, typename Unit>
12782typename ParseHandler::BinaryNodeResult
12783GeneralParser<ParseHandler, Unit>::importExpr(YieldHandling yieldHandling,
12784 bool allowCallSyntax) {
12785 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Import))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Import)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Import)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12785); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 12785; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12786
12787 NullaryNodeType importHolder;
12788 MOZ_TRY_VAR(importHolder, handler_.newPosHolder(pos()))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (importHolder
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12789
12790 TokenKind next;
12791 if (!tokenStream.getToken(&next)) {
12792 return errorResult();
12793 }
12794
12795 if (next == TokenKind::Dot) {
12796 if (!tokenStream.getToken(&next)) {
12797 return errorResult();
12798 }
12799 if (next != TokenKind::Meta) {
12800 error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
12801 return errorResult();
12802 }
12803
12804 if (parseGoal() != ParseGoal::Module) {
12805 errorAt(pos().begin, JSMSG_IMPORT_META_OUTSIDE_MODULE);
12806 return errorResult();
12807 }
12808
12809 NullaryNodeType metaHolder;
12810 MOZ_TRY_VAR(metaHolder, handler_.newPosHolder(pos()))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (metaHolder
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12811
12812 return handler_.newImportMeta(importHolder, metaHolder);
12813 }
12814
12815 if (next == TokenKind::LeftParen && allowCallSyntax) {
12816 Node arg;
12817 MOZ_TRY_VAR(arg, assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (arg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12818
12819 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12820 return errorResult();
12821 }
12822
12823 Node optionalArg;
12824 if (options().importAttributes()) {
12825 if (next == TokenKind::Comma) {
12826 tokenStream.consumeKnownToken(TokenKind::Comma,
12827 TokenStream::SlashIsRegExp);
12828
12829 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12830 return errorResult();
12831 }
12832
12833 if (next != TokenKind::RightParen) {
12834 MOZ_TRY_VAR(optionalArg, assignExpr(InAllowed, yieldHandling,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12835 TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12836
12837 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12838 return errorResult();
12839 }
12840
12841 if (next == TokenKind::Comma) {
12842 tokenStream.consumeKnownToken(TokenKind::Comma,
12843 TokenStream::SlashIsRegExp);
12844 }
12845 } else {
12846 MOZ_TRY_VAR(optionalArg,do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12847 handler_.newPosHolder(TokenPos(pos().end, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12848 }
12849 } else {
12850 MOZ_TRY_VAR(optionalArg,do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12851 handler_.newPosHolder(TokenPos(pos().end, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12852 }
12853 } else {
12854 MOZ_TRY_VAR(optionalArg,do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12855 handler_.newPosHolder(TokenPos(pos().end, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12856 }
12857
12858 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_ARGS)) {
12859 return errorResult();
12860 }
12861
12862 Node spec;
12863 MOZ_TRY_VAR(spec, handler_.newCallImportSpec(arg, optionalArg))do { auto mozTryVarTempResult_ = (handler_.newCallImportSpec(
arg, optionalArg)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (spec) = mozTryVarTempResult_.unwrap(); } while (0)
;
12864
12865 return handler_.newCallImport(importHolder, spec);
12866 }
12867
12868 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
12869 return errorResult();
12870}
12871
12872template <class ParseHandler, typename Unit>
12873typename ParseHandler::NodeResult
12874GeneralParser<ParseHandler, Unit>::primaryExpr(
12875 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
12876 TokenKind tt, PossibleError* possibleError, InvokedPrediction invoked) {
12877 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12877); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 12877; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12878 AutoCheckRecursionLimit recursion(this->fc_);
12879 if (!recursion.check(this->fc_)) {
12880 return errorResult();
12881 }
12882
12883 switch (tt) {
12884 case TokenKind::Function:
12885 return functionExpr(pos().begin, invoked,
12886 FunctionAsyncKind::SyncFunction);
12887
12888 case TokenKind::Class:
12889 return classDefinition(yieldHandling, ClassExpression, NameRequired);
12890
12891 case TokenKind::LeftBracket:
12892 return arrayInitializer(yieldHandling, possibleError);
12893
12894 case TokenKind::LeftCurly:
12895 return objectLiteral(yieldHandling, possibleError);
12896
12897#ifdef ENABLE_RECORD_TUPLE
12898 case TokenKind::HashCurly:
12899 return recordLiteral(yieldHandling);
12900
12901 case TokenKind::HashBracket:
12902 return tupleLiteral(yieldHandling);
12903#endif
12904
12905#ifdef ENABLE_DECORATORS
12906 case TokenKind::At:
12907 return classDefinition(yieldHandling, ClassExpression, NameRequired);
12908#endif
12909
12910 case TokenKind::LeftParen: {
12911 TokenKind next;
12912 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12913 return errorResult();
12914 }
12915
12916 if (next == TokenKind::RightParen) {
12917 // Not valid expression syntax, but this is valid in an arrow function
12918 // with no params: `() => body`.
12919 tokenStream.consumeKnownToken(TokenKind::RightParen,
12920 TokenStream::SlashIsRegExp);
12921
12922 if (!tokenStream.peekToken(&next)) {
12923 return errorResult();
12924 }
12925 if (next != TokenKind::Arrow) {
12926 error(JSMSG_UNEXPECTED_TOKEN, "expression",
12927 TokenKindToDesc(TokenKind::RightParen));
12928 return errorResult();
12929 }
12930
12931 // Now just return something that will allow parsing to continue.
12932 // It doesn't matter what; when we reach the =>, we will rewind and
12933 // reparse the whole arrow function. See Parser::assignExpr.
12934 return handler_.newNullLiteral(pos());
12935 }
12936
12937 // Pass |possibleError| to support destructuring in arrow parameters.
12938 Node expr;
12939 MOZ_TRY_VAR(expr, exprInParens(InAllowed, yieldHandling, TripledotAllowed,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, possibleError)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
12940 possibleError))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, possibleError)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
12941 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_IN_PAREN)) {
12942 return errorResult();
12943 }
12944 return handler_.parenthesize(expr);
12945 }
12946
12947 case TokenKind::TemplateHead:
12948 return templateLiteral(yieldHandling);
12949
12950 case TokenKind::NoSubsTemplate:
12951 return noSubstitutionUntaggedTemplate();
12952
12953 case TokenKind::String:
12954 return stringLiteral();
12955
12956 default: {
12957 if (!TokenKindIsPossibleIdentifier(tt)) {
12958 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
12959 return errorResult();
12960 }
12961
12962 if (tt == TokenKind::Async) {
12963 TokenKind nextSameLine = TokenKind::Eof;
12964 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
12965 return errorResult();
12966 }
12967
12968 if (nextSameLine == TokenKind::Function) {
12969 uint32_t toStringStart = pos().begin;
12970 tokenStream.consumeKnownToken(TokenKind::Function);
12971 return functionExpr(toStringStart, PredictUninvoked,
12972 FunctionAsyncKind::AsyncFunction);
12973 }
12974 }
12975
12976 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12977 if (!name) {
12978 return errorResult();
12979 }
12980
12981 return identifierReference(name);
12982 }
12983
12984 case TokenKind::RegExp:
12985 return newRegExp();
12986
12987 case TokenKind::Number:
12988 return newNumber(anyChars.currentToken());
12989
12990 case TokenKind::BigInt:
12991 return newBigInt();
12992
12993 case TokenKind::True:
12994 return handler_.newBooleanLiteral(true, pos());
12995 case TokenKind::False:
12996 return handler_.newBooleanLiteral(false, pos());
12997 case TokenKind::This: {
12998 NameNodeType thisName = null();
12999 if (pc_->sc()->hasFunctionThisBinding()) {
13000 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
13001 }
13002 return handler_.newThisLiteral(pos(), thisName);
13003 }
13004 case TokenKind::Null:
13005 return handler_.newNullLiteral(pos());
13006
13007 case TokenKind::TripleDot: {
13008 // This isn't valid expression syntax, but it's valid in an arrow
13009 // function as a trailing rest param: `(a, b, ...rest) => body`. Check
13010 // if it's directly under
13011 // CoverParenthesizedExpressionAndArrowParameterList, and check for a
13012 // name, closing parenthesis, and arrow, and allow it only if all are
13013 // present.
13014 if (tripledotHandling != TripledotAllowed) {
13015 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
13016 return errorResult();
13017 }
13018
13019 TokenKind next;
13020 if (!tokenStream.getToken(&next)) {
13021 return errorResult();
13022 }
13023
13024 if (next == TokenKind::LeftBracket || next == TokenKind::LeftCurly) {
13025 // Validate, but don't store the pattern right now. The whole arrow
13026 // function is reparsed in functionFormalParametersAndBody().
13027 MOZ_TRY(destructuringDeclaration(DeclarationKind::CoverArrowParameter,do { auto mozTryTempResult_ = ::mozilla::ToResult(destructuringDeclaration
(DeclarationKind::CoverArrowParameter, yieldHandling, next));
if ((__builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return
mozTryTempResult_.propagateErr(); } } while (0)
13028 yieldHandling, next))do { auto mozTryTempResult_ = ::mozilla::ToResult(destructuringDeclaration
(DeclarationKind::CoverArrowParameter, yieldHandling, next));
if ((__builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return
mozTryTempResult_.propagateErr(); } } while (0)
;
13029 } else {
13030 // This doesn't check that the provided name is allowed, e.g. if
13031 // the enclosing code is strict mode code, any of "let", "yield",
13032 // or "arguments" should be prohibited. Argument-parsing code
13033 // handles that.
13034 if (!TokenKindIsPossibleIdentifier(next)) {
13035 error(JSMSG_UNEXPECTED_TOKEN, "rest argument name",
13036 TokenKindToDesc(next));
13037 return errorResult();
13038 }
13039 }
13040
13041 if (!tokenStream.getToken(&next)) {
13042 return errorResult();
13043 }
13044 if (next != TokenKind::RightParen) {
13045 error(JSMSG_UNEXPECTED_TOKEN, "closing parenthesis",
13046 TokenKindToDesc(next));
13047 return errorResult();
13048 }
13049
13050 if (!tokenStream.peekToken(&next)) {
13051 return errorResult();
13052 }
13053 if (next != TokenKind::Arrow) {
13054 // Advance the scanner for proper error location reporting.
13055 tokenStream.consumeKnownToken(next);
13056 error(JSMSG_UNEXPECTED_TOKEN, "'=>' after argument list",
13057 TokenKindToDesc(next));
13058 return errorResult();
13059 }
13060
13061 anyChars.ungetToken(); // put back right paren
13062
13063 // Return an arbitrary expression node. See case TokenKind::RightParen
13064 // above.
13065 return handler_.newNullLiteral(pos());
13066 }
13067 }
13068}
13069
13070template <class ParseHandler, typename Unit>
13071typename ParseHandler::NodeResult
13072GeneralParser<ParseHandler, Unit>::exprInParens(
13073 InHandling inHandling, YieldHandling yieldHandling,
13074 TripledotHandling tripledotHandling,
13075 PossibleError* possibleError /* = nullptr */) {
13076 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftParen))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftParen))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftParen))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftParen)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 13076); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftParen)"
")"); do { *((volatile int*)__null) = 13076; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
13077 return expr(inHandling, yieldHandling, tripledotHandling, possibleError,
13078 PredictInvoked);
13079}
13080
13081template class PerHandlerParser<FullParseHandler>;
13082template class PerHandlerParser<SyntaxParseHandler>;
13083template class GeneralParser<FullParseHandler, Utf8Unit>;
13084template class GeneralParser<SyntaxParseHandler, Utf8Unit>;
13085template class GeneralParser<FullParseHandler, char16_t>;
13086template class GeneralParser<SyntaxParseHandler, char16_t>;
13087template class Parser<FullParseHandler, Utf8Unit>;
13088template class Parser<SyntaxParseHandler, Utf8Unit>;
13089template class Parser<FullParseHandler, char16_t>;
13090template class Parser<SyntaxParseHandler, char16_t>;
13091
13092} // namespace js::frontend

/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h

1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7#ifndef vm_Scope_h
8#define vm_Scope_h
9
10#include "mozilla/Assertions.h" // MOZ_ASSERT, MOZ_ASSERT_IF
11#include "mozilla/Attributes.h" // MOZ_IMPLICIT, MOZ_INIT_OUTSIDE_CTOR, MOZ_STACK_CLASS
12#include "mozilla/Casting.h" // mozilla::AssertedCast
13#include "mozilla/Maybe.h" // mozilla::Maybe
14#include "mozilla/MemoryReporting.h" // mozilla::MallocSizeOf
15#include "mozilla/Span.h" // mozilla::Span
16
17#include <algorithm> // std::fill_n
18#include <stddef.h> // size_t
19#include <stdint.h> // uint8_t, uint16_t, uint32_t, uintptr_t
20#include <type_traits> // std::is_same_v, std::is_base_of_v
21
22#include "builtin/ModuleObject.h" // ModuleObject, Handle<ModuleObject*>
23#include "frontend/ParserAtom.h" // frontend::TaggedParserAtomIndex
24#include "gc/Barrier.h" // HeapPtr
25#include "gc/Cell.h" // TenuredCellWithNonGCPointer
26#include "js/GCPolicyAPI.h" // GCPolicy, IgnoreGCPolicy
27#include "js/HeapAPI.h" // CellFlagBitsReservedForGC
28#include "js/RootingAPI.h" // Handle, MutableHandle
29#include "js/TraceKind.h" // JS::TraceKind
30#include "js/TypeDecls.h" // HandleFunction
31#include "js/UbiNode.h" // ubi::*
32#include "js/UniquePtr.h" // UniquePtr
33#include "util/Poison.h" // AlwaysPoison, JS_SCOPE_DATA_TRAILING_NAMES_PATTERN, MemCheckKind
34#include "vm/JSFunction.h" // JSFunction
35#include "vm/ScopeKind.h" // ScopeKind
36#include "vm/Shape.h" // Shape
37#include "wasm/WasmJS.h" // WasmInstanceObject
38
39class JSAtom;
40class JSScript;
41class JSTracer;
42struct JSContext;
43
44namespace js {
45
46class JS_PUBLIC_API GenericPrinter;
47
48namespace frontend {
49class ScopeStencil;
50struct ScopeStencilRef;
51class RuntimeScopeBindingCache;
52} // namespace frontend
53
54template <typename NameT>
55class AbstractBaseScopeData;
56
57template <typename NameT>
58class BaseAbstractBindingIter;
59
60template <typename NameT>
61class AbstractBindingIter;
62
63template <typename NameT>
64class AbstractPositionalFormalParameterIter;
65
66using BindingIter = AbstractBindingIter<JSAtom>;
67
68class AbstractScopePtr;
69
70static inline bool ScopeKindIsCatch(ScopeKind kind) {
71 return kind == ScopeKind::SimpleCatch || kind == ScopeKind::Catch;
72}
73
74static inline bool ScopeKindIsInBody(ScopeKind kind) {
75 return kind == ScopeKind::Lexical || kind == ScopeKind::SimpleCatch ||
76 kind == ScopeKind::Catch || kind == ScopeKind::With ||
77 kind == ScopeKind::FunctionLexical ||
78 kind == ScopeKind::FunctionBodyVar || kind == ScopeKind::ClassBody;
79}
80
81const char* BindingKindString(BindingKind kind);
82const char* ScopeKindString(ScopeKind kind);
83
84template <typename NameT>
85class AbstractBindingName;
86
87template <>
88class AbstractBindingName<JSAtom> {
89 public:
90 using NameT = JSAtom;
91 using NamePointerT = NameT*;
92
93 private:
94 // A JSAtom* with its low bit used as a tag for the:
95 // * whether it is closed over (i.e., exists in the environment shape)
96 // * whether it is a top-level function binding in global or eval scope,
97 // instead of var binding (both are in the same range in Scope data)
98 uintptr_t bits_;
99
100 static constexpr uintptr_t ClosedOverFlag = 0x1;
101 // TODO: We should reuse this bit for let vs class distinction to
102 // show the better redeclaration error message (bug 1428672).
103 static constexpr uintptr_t TopLevelFunctionFlag = 0x2;
104 static constexpr uintptr_t FlagMask = 0x3;
105
106 public:
107 AbstractBindingName() : bits_(0) {}
108
109 AbstractBindingName(NameT* name, bool closedOver,
110 bool isTopLevelFunction = false)
111 : bits_(uintptr_t(name) | (closedOver ? ClosedOverFlag : 0x0) |
112 (isTopLevelFunction ? TopLevelFunctionFlag : 0x0)) {}
113
114 NamePointerT name() const {
115 return reinterpret_cast<NameT*>(bits_ & ~FlagMask);
116 }
117
118 bool closedOver() const { return bits_ & ClosedOverFlag; }
119
120 private:
121 friend class BaseAbstractBindingIter<NameT>;
122
123 // This method should be called only for binding names in `vars` range in
124 // BindingIter.
125 bool isTopLevelFunction() const { return bits_ & TopLevelFunctionFlag; }
126
127 public:
128 void trace(JSTracer* trc) {
129 if (JSAtom* atom = name()) {
130 TraceManuallyBarrieredEdge(trc, &atom, "binding name");
131 }
132 }
133};
134
135template <>
136class AbstractBindingName<frontend::TaggedParserAtomIndex> {
137 uint32_t bits_;
138
139 using TaggedParserAtomIndex = frontend::TaggedParserAtomIndex;
140
141 public:
142 using NameT = TaggedParserAtomIndex;
143 using NamePointerT = NameT;
144
145 private:
146 static constexpr size_t TaggedIndexBit = TaggedParserAtomIndex::IndexBit + 2;
147
148 static constexpr size_t FlagShift = TaggedIndexBit;
149 static constexpr size_t FlagBit = 2;
150 static constexpr uint32_t FlagMask = BitMask(FlagBit) << FlagShift;
151
152 static constexpr uint32_t ClosedOverFlag = 1 << FlagShift;
153 static constexpr uint32_t TopLevelFunctionFlag = 2 << FlagShift;
154
155 public:
156 AbstractBindingName() : bits_(TaggedParserAtomIndex::NullTag) {
157 // TaggedParserAtomIndex's tags shouldn't overlap with flags.
158 static_assert((TaggedParserAtomIndex::NullTag & FlagMask) == 0);
159 static_assert((TaggedParserAtomIndex::ParserAtomIndexTag & FlagMask) == 0);
160 static_assert((TaggedParserAtomIndex::WellKnownTag & FlagMask) == 0);
161 }
162
163 AbstractBindingName(TaggedParserAtomIndex name, bool closedOver,
164 bool isTopLevelFunction = false)
165 : bits_(name.rawData() | (closedOver ? ClosedOverFlag : 0x0) |
166 (isTopLevelFunction ? TopLevelFunctionFlag : 0x0)) {}
167
168 public:
169 NamePointerT name() const {
170 return TaggedParserAtomIndex::fromRaw(bits_ & ~FlagMask);
171 }
172
173 bool closedOver() const { return bits_ & ClosedOverFlag; }
174
175 AbstractBindingName<JSAtom> copyWithNewAtom(JSAtom* newName) const {
176 return AbstractBindingName<JSAtom>(newName, closedOver(),
177 isTopLevelFunction());
178 }
179
180 void updateNameAfterStencilMerge(TaggedParserAtomIndex name) {
181 bits_ = (bits_ & FlagMask) | name.rawData();
182 }
183
184 private:
185 friend class BaseAbstractBindingIter<TaggedParserAtomIndex>;
186 friend class frontend::ScopeStencil;
187
188 // This method should be called only for binding names in `vars` range in
189 // BindingIter.
190 bool isTopLevelFunction() const { return bits_ & TopLevelFunctionFlag; }
191};
192
193using BindingName = AbstractBindingName<JSAtom>;
194
195static inline void TraceBindingNames(JSTracer* trc, BindingName* names,
196 uint32_t length) {
197 for (uint32_t i = 0; i < length; i++) {
198 JSAtom* name = names[i].name();
199 MOZ_ASSERT(name)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(name))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("name", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 199); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name" ")"); do
{ *((volatile int*)__null) = 199; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
200 TraceManuallyBarrieredEdge(trc, &name, "scope name");
201 }
202};
203static inline void TraceNullableBindingNames(JSTracer* trc, BindingName* names,
204 uint32_t length) {
205 for (uint32_t i = 0; i < length; i++) {
206 if (JSAtom* name = names[i].name()) {
207 TraceManuallyBarrieredEdge(trc, &name, "scope name");
208 }
209 }
210};
211
212const size_t ScopeDataAlignBytes = size_t(1) << gc::CellFlagBitsReservedForGC;
213
214/**
215 * Base class for scope {Runtime,Parser}Data classes to inherit from.
216 *
217 * `js::Scope` stores a pointer to RuntimeData classes in their first word, so
218 * they must be suitably aligned to allow storing GC flags in the low bits.
219 */
220template <typename NameT>
221class AbstractBaseScopeData {
222 public:
223 using NameType = NameT;
224
225 // The length of names after specialized ScopeData subclasses.
226 uint32_t length = 0;
227};
228
229template <typename ScopeDataT>
230static inline void AssertDerivedScopeData() {
231 static_assert(
232 !std::is_same_v<ScopeDataT,
233 AbstractBaseScopeData<typename ScopeDataT::NameType>>,
234 "ScopeDataT shouldn't be AbstractBaseScopeData");
235 static_assert(
236 std::is_base_of_v<AbstractBaseScopeData<typename ScopeDataT::NameType>,
237 ScopeDataT>,
238 "ScopeDataT should be subclass of AbstractBaseScopeData");
239}
240
241template <typename ScopeDataT>
242static inline size_t GetOffsetOfScopeDataTrailingNames() {
243 AssertDerivedScopeData<ScopeDataT>();
244 return sizeof(ScopeDataT);
245}
246
247template <typename ScopeDataT>
248static inline AbstractBindingName<typename ScopeDataT::NameType>*
249GetScopeDataTrailingNamesPointer(ScopeDataT* data) {
250 AssertDerivedScopeData<ScopeDataT>();
251 return reinterpret_cast<AbstractBindingName<typename ScopeDataT::NameType>*>(
252 data + 1);
253}
254
255template <typename ScopeDataT>
256static inline const AbstractBindingName<typename ScopeDataT::NameType>*
257GetScopeDataTrailingNamesPointer(const ScopeDataT* data) {
258 AssertDerivedScopeData<ScopeDataT>();
259 return reinterpret_cast<
260 const AbstractBindingName<typename ScopeDataT::NameType>*>(data + 1);
261}
262
263template <typename ScopeDataT>
264static inline mozilla::Span<AbstractBindingName<typename ScopeDataT::NameType>>
265GetScopeDataTrailingNames(ScopeDataT* data) {
266 return mozilla::Span(GetScopeDataTrailingNamesPointer(data), data->length);
17
Access to field 'length' results in a dereference of a null pointer (loaded from variable 'data')
267}
268
269template <typename ScopeDataT>
270static inline mozilla::Span<
271 const AbstractBindingName<typename ScopeDataT::NameType>>
272GetScopeDataTrailingNames(const ScopeDataT* data) {
273 return mozilla::Span(GetScopeDataTrailingNamesPointer(data), data->length);
274}
275
276using BaseScopeData = AbstractBaseScopeData<JSAtom>;
277
278inline void PoisonNames(AbstractBindingName<JSAtom>* data, uint32_t length) {
279 AlwaysPoison(data, JS_SCOPE_DATA_TRAILING_NAMES_PATTERN,
280 sizeof(AbstractBindingName<JSAtom>) * length,
281 MemCheckKind::MakeUndefined);
282}
283
284// frontend::TaggedParserAtomIndex doesn't require poison value.
285// Fill with null value instead.
286inline void PoisonNames(
287 AbstractBindingName<frontend::TaggedParserAtomIndex>* data,
288 uint32_t length) {
289 std::fill_n(data, length,
290 AbstractBindingName<frontend::TaggedParserAtomIndex>());
291}
292
293template <typename ScopeDataT>
294static inline void PoisonNames(ScopeDataT* data, uint32_t length) {
295 if (length) {
296 PoisonNames(GetScopeDataTrailingNamesPointer(data), length);
297 }
298}
299
300//
301// Allow using is<T> and as<T> on Rooted<Scope*> and Handle<Scope*>.
302//
303template <typename Wrapper>
304class WrappedPtrOperations<Scope*, Wrapper> {
305 public:
306 template <class U>
307 JS::Handle<U*> as() const {
308 const Wrapper& self = *static_cast<const Wrapper*>(this);
309 MOZ_ASSERT_IF(self, self->template is<U>())do { if (self) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(self->template is<U>())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(self->template is<U>
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("self->template is<U>()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 309); AnnotateMozCrashReason("MOZ_ASSERT" "(" "self->template is<U>()"
")"); do { *((volatile int*)__null) = 309; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
310 return Handle<U*>::fromMarkedLocation(
311 reinterpret_cast<U* const*>(self.address()));
312 }
313};
314
315//
316// The base class of all Scopes.
317//
318class Scope : public gc::TenuredCellWithNonGCPointer<BaseScopeData> {
319 friend class GCMarker;
320 friend class frontend::ScopeStencil;
321 friend class js::AbstractBindingIter<JSAtom>;
322 friend class js::frontend::RuntimeScopeBindingCache;
323 friend class gc::CellAllocator;
324
325 protected:
326 // The raw data pointer, stored in the cell header.
327 BaseScopeData* rawData() { return headerPtr(); }
328 const BaseScopeData* rawData() const { return headerPtr(); }
329
330 // The kind determines data_.
331 const ScopeKind kind_;
332
333 // If there are any aliased bindings, the shape for the
334 // EnvironmentObject. Otherwise nullptr.
335 const HeapPtr<SharedShape*> environmentShape_;
336
337 // The enclosing scope or nullptr.
338 HeapPtr<Scope*> enclosingScope_;
339
340 Scope(ScopeKind kind, Scope* enclosing, SharedShape* environmentShape)
341 : TenuredCellWithNonGCPointer(nullptr),
342 kind_(kind),
343 environmentShape_(environmentShape),
344 enclosingScope_(enclosing) {}
345
346 static Scope* create(JSContext* cx, ScopeKind kind, Handle<Scope*> enclosing,
347 Handle<SharedShape*> envShape);
348
349 template <typename ConcreteScope>
350 void initData(
351 MutableHandle<UniquePtr<typename ConcreteScope::RuntimeData>> data);
352
353 template <typename F>
354 void applyScopeDataTyped(F&& f);
355
356 static void updateEnvShapeIfRequired(mozilla::Maybe<uint32_t>* envShape,
357 bool needsEnvironment);
358
359 public:
360 template <typename ConcreteScope>
361 static ConcreteScope* create(
362 JSContext* cx, ScopeKind kind, Handle<Scope*> enclosing,
363 Handle<SharedShape*> envShape,
364 MutableHandle<UniquePtr<typename ConcreteScope::RuntimeData>> data);
365
366 static const JS::TraceKind TraceKind = JS::TraceKind::Scope;
367
368 template <typename T>
369 bool is() const {
370 return kind_ == T::classScopeKind_;
371 }
372
373 template <typename T>
374 T& as() {
375 MOZ_ASSERT(this->is<T>())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->is<T>())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(this->is<T>()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("this->is<T>()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 375); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->is<T>()"
")"); do { *((volatile int*)__null) = 375; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
376 return *static_cast<T*>(this);
377 }
378
379 template <typename T>
380 const T& as() const {
381 MOZ_ASSERT(this->is<T>())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->is<T>())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(this->is<T>()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("this->is<T>()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->is<T>()"
")"); do { *((volatile int*)__null) = 381; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
382 return *static_cast<const T*>(this);
383 }
384
385 ScopeKind kind() const { return kind_; }
386
387 bool isNamedLambda() const {
388 return kind() == ScopeKind::NamedLambda ||
389 kind() == ScopeKind::StrictNamedLambda;
390 }
391
392 SharedShape* environmentShape() const { return environmentShape_; }
393
394 Scope* enclosing() const { return enclosingScope_; }
395
396 static bool hasEnvironment(ScopeKind kind, bool hasEnvironmentShape = false) {
397 switch (kind) {
398 case ScopeKind::With:
399 case ScopeKind::Global:
400 case ScopeKind::NonSyntactic:
401 return true;
402 default:
403 // If there's a shape, an environment must be created for this scope.
404 return hasEnvironmentShape;
405 }
406 }
407
408 bool hasEnvironment() const {
409 return hasEnvironment(kind_, !!environmentShape());
410 }
411
412 uint32_t firstFrameSlot() const;
413
414 uint32_t chainLength() const;
415 uint32_t environmentChainLength() const;
416
417 template <typename T>
418 bool hasOnChain() const {
419 for (const Scope* it = this; it; it = it->enclosing()) {
420 if (it->is<T>()) {
421 return true;
422 }
423 }
424 return false;
425 }
426
427 bool hasOnChain(ScopeKind kind) const {
428 for (const Scope* it = this; it; it = it->enclosing()) {
429 if (it->kind() == kind) {
430 return true;
431 }
432 }
433 return false;
434 }
435
436 void traceChildren(JSTracer* trc);
437 void finalize(JS::GCContext* gcx);
438
439 size_t sizeOfExcludingThis(mozilla::MallocSizeOf mallocSizeOf) const;
440
441 void dump();
442#if defined(DEBUG1) || defined(JS_JITSPEW1)
443 static bool dumpForDisassemble(JSContext* cx, JS::Handle<Scope*> scope,
444 GenericPrinter& out, const char* indent);
445#endif /* defined(DEBUG) || defined(JS_JITSPEW) */
446};
447
448template <class DataT>
449inline size_t SizeOfScopeData(uint32_t length) {
450 using BindingT = AbstractBindingName<typename DataT::NameType>;
451 return GetOffsetOfScopeDataTrailingNames<DataT>() + length * sizeof(BindingT);
452}
453
454//
455// A useful typedef for selecting between a gc-aware wrappers
456// around pointers to BaseScopeData-derived types, and around raw
457// pointer wrappers around BaseParserScopeData-derived types.
458//
459template <typename ScopeT, typename AtomT>
460using AbstractScopeData = typename ScopeT::template AbstractData<AtomT>;
461
462// Binding names are stored from `this+1`.
463// Make sure the class aligns the binding name size.
464template <typename SlotInfo>
465struct alignas(alignof(AbstractBindingName<frontend::TaggedParserAtomIndex>))
466 ParserScopeData
467 : public AbstractBaseScopeData<frontend::TaggedParserAtomIndex> {
468 SlotInfo slotInfo;
469
470 explicit ParserScopeData(size_t length) { PoisonNames(this, length); }
471 ParserScopeData() = delete;
472};
473
474// RuntimeScopeData has 2 requirements:
475// * It aligns with `BindingName`, that is stored after `this+1`
476// * It aligns with ScopeDataAlignBytes, in order to put it in the first
477// word of `js::Scope`
478static_assert(alignof(BindingName) <= ScopeDataAlignBytes);
479template <typename SlotInfo>
480struct alignas(ScopeDataAlignBytes) RuntimeScopeData
481 : public AbstractBaseScopeData<JSAtom> {
482 SlotInfo slotInfo;
483
484 explicit RuntimeScopeData(size_t length) { PoisonNames(this, length); }
485 RuntimeScopeData() = delete;
486
487 void trace(JSTracer* trc);
488};
489
490//
491// A lexical scope that holds let and const bindings. There are 4 kinds of
492// LexicalScopes.
493//
494// Lexical
495// A plain lexical scope.
496//
497// SimpleCatch
498// Holds the single catch parameter of a catch block.
499//
500// Catch
501// Holds the catch parameters (and only the catch parameters) of a catch
502// block.
503//
504// NamedLambda
505// StrictNamedLambda
506// Holds the single name of the callee for a named lambda expression.
507//
508// All kinds of LexicalScopes correspond to LexicalEnvironmentObjects on the
509// environment chain.
510//
511class LexicalScope : public Scope {
512 friend class Scope;
513 friend class AbstractBindingIter<JSAtom>;
514 friend class GCMarker;
515 friend class frontend::ScopeStencil;
516
517 public:
518 struct SlotInfo {
519 // Frame slots [0, nextFrameSlot) are live when this is the innermost
520 // scope.
521 uint32_t nextFrameSlot = 0;
522
523 // Bindings are sorted by kind in both frames and environments.
524 //
525 // lets - [0, constStart)
526 // consts - [constStart, length)
527 uint32_t constStart = 0;
528#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
529 // consts - [constStart, usingStart)
530 // usings - [usingStart, length)
531 uint32_t usingStart = 0;
532#endif
533 };
534
535 using RuntimeData = RuntimeScopeData<SlotInfo>;
536 using ParserData = ParserScopeData<SlotInfo>;
537
538 template <typename NameT>
539 using AbstractData =
540 typename std::conditional_t<std::is_same<NameT, JSAtom>::value,
541 RuntimeData, ParserData>;
542
543 private:
544 static void prepareForScopeCreation(ScopeKind kind, uint32_t firstFrameSlot,
545 LexicalScope::ParserData* data,
546 mozilla::Maybe<uint32_t>* envShape);
547
548 RuntimeData& data() { return *static_cast<RuntimeData*>(rawData()); }
549 const RuntimeData& data() const {
550 return *static_cast<const RuntimeData*>(rawData());
551 }
552
553 public:
554 static uint32_t nextFrameSlot(Scope* scope);
555
556 uint32_t nextFrameSlot() const { return data().slotInfo.nextFrameSlot; }
557
558 // Returns an empty shape for extensible global and non-syntactic lexical
559 // scopes.
560 static SharedShape* getEmptyExtensibleEnvironmentShape(JSContext* cx);
561};
562
563template <>
564inline bool Scope::is<LexicalScope>() const {
565 return kind_ == ScopeKind::Lexical || kind_ == ScopeKind::SimpleCatch ||
566 kind_ == ScopeKind::Catch || kind_ == ScopeKind::NamedLambda ||
567 kind_ == ScopeKind::StrictNamedLambda ||
568 kind_ == ScopeKind::FunctionLexical;
569}
570
571// The body scope of a JS class, containing only synthetic bindings for private
572// class members. (The binding for the class name, `C` in the example below, is
573// in another scope, a `LexicalScope`, that encloses the `ClassBodyScope`.)
574// Example:
575//
576// class C {
577// #f = 0;
578// #m() {
579// return this.#f++;
580// }
581// }
582//
583// This class has a ClassBodyScope with four synthetic bindings:
584// - `#f` (private name)
585// - `#m` (private name)
586// - `#m.method` (function object)
587// - `.privateBrand` (the class's private brand)
588class ClassBodyScope : public Scope {
589 friend class Scope;
590 friend class AbstractBindingIter<JSAtom>;
591 friend class GCMarker;
592 friend class frontend::ScopeStencil;
593 friend class AbstractScopePtr;
594
595 static const ScopeKind classScopeKind_ = ScopeKind::ClassBody;
596
597 public:
598 struct SlotInfo {
599 // Frame slots [0, nextFrameSlot) are live when this is the innermost
600 // scope.
601 uint32_t nextFrameSlot = 0;
602
603 // Bindings are sorted by kind in both frames and environments.
604 //
605 // synthetic - [0, privateMethodStart)
606 // privateMethod - [privateMethodStart, length)
607 uint32_t privateMethodStart = 0;
608 };
609
610 using RuntimeData = RuntimeScopeData<SlotInfo>;
611 using ParserData = ParserScopeData<SlotInfo>;
612
613 template <typename NameT>
614 using AbstractData =
615 typename std::conditional_t<std::is_same<NameT, JSAtom>::value,
616 RuntimeData, ParserData>;
617
618 private:
619 static void prepareForScopeCreation(ScopeKind kind, uint32_t firstFrameSlot,
620 ClassBodyScope::ParserData* data,
621 mozilla::Maybe<uint32_t>* envShape);
622
623 RuntimeData& data() { return *static_cast<RuntimeData*>(rawData()); }
624 const RuntimeData& data() const {
625 return *static_cast<const RuntimeData*>(rawData());
626 }
627
628 public:
629 static uint32_t nextFrameSlot(Scope* scope);
630
631 uint32_t nextFrameSlot() const { return data().slotInfo.nextFrameSlot; }
632
633 // Returns an empty shape for extensible global and non-syntactic lexical
634 // scopes.
635 static SharedShape* getEmptyExtensibleEnvironmentShape(JSContext* cx);
636};
637
638//
639// Scope corresponding to a function. Holds formal parameter names, special
640// internal names (see FunctionScope::isSpecialName), and, if the function
641// parameters contain no expressions that might possibly be evaluated, the
642// function's var bindings. For example, in these functions, the FunctionScope
643// will store a/b/c bindings but not d/e/f bindings:
644//
645// function f1(a, b) {
646// var c;
647// let e;
648// const f = 3;
649// }
650// function f2([a], b = 4, ...c) {
651// var d, e, f; // stored in VarScope
652// }
653//
654// Corresponds to CallObject on environment chain.
655//
656class FunctionScope : public Scope {
657 friend class GCMarker;
658 friend class AbstractBindingIter<JSAtom>;
659 friend class AbstractPositionalFormalParameterIter<JSAtom>;
660 friend class Scope;
661 friend class AbstractScopePtr;
662 static const ScopeKind classScopeKind_ = ScopeKind::Function;
663
664 public:
665 struct SlotInfo {
666 // Frame slots [0, nextFrameSlot) are live when this is the innermost
667 // scope.
668 uint32_t nextFrameSlot = 0;
669
670 // Flag bits.
671 // This uses uint32_t in order to make this struct packed.
672 uint32_t flags = 0;
673
674 // If parameter expressions are present, parameters act like lexical
675 // bindings.
676 static constexpr uint32_t HasParameterExprsFlag = 1;
677
678 // Bindings are sorted by kind in both frames and environments.
679 //
680 // Positional formal parameter names are those that are not
681 // destructured. They may be referred to by argument slots if
682 // !script()->hasParameterExprs().
683 //
684 // An argument slot that needs to be skipped due to being destructured
685 // or having defaults will have a nullptr name in the name array to
686 // advance the argument slot.
687 //
688 // Rest parameter binding is also included in positional formals.
689 // This also becomes nullptr if destructuring.
690 //
691 // The number of positional formals is equal to function.length if
692 // there's no rest, function.length+1 otherwise.
693 //
694 // Destructuring parameters and destructuring rest are included in
695 // "other formals" below.
696 //
697 // "vars" contains the following:
698 // * function's top level vars if !script()->hasParameterExprs()
699 // * special internal names (arguments, .this, .generator) if
700 // they're used.
701 //
702 // positional formals - [0, nonPositionalFormalStart)
703 // other formals - [nonPositionalParamStart, varStart)
704 // vars - [varStart, length)
705 uint16_t nonPositionalFormalStart = 0;
706 uint16_t varStart = 0;
707
708 bool hasParameterExprs() const { return flags & HasParameterExprsFlag; }
709 void setHasParameterExprs() { flags |= HasParameterExprsFlag; }
710 };
711
712 struct alignas(ScopeDataAlignBytes) RuntimeData
713 : public AbstractBaseScopeData<JSAtom> {
714 SlotInfo slotInfo;
715 // The canonical function of the scope, as during a scope walk we
716 // often query properties of the JSFunction (e.g., is the function an
717 // arrow).
718 HeapPtr<JSFunction*> canonicalFunction = {};
719
720 explicit RuntimeData(size_t length) { PoisonNames(this, length); }
721 RuntimeData() = delete;
722
723 void trace(JSTracer* trc);
724 };
725
726 using ParserData = ParserScopeData<SlotInfo>;
727
728 template <typename NameT>
729 using AbstractData =
730 typename std::conditional_t<std::is_same<NameT, JSAtom>::value,
731 RuntimeData, ParserData>;
732
733 static void prepareForScopeCreation(FunctionScope::ParserData* data,
734 bool hasParameterExprs,
735 bool needsEnvironment,
736 mozilla::Maybe<uint32_t>* envShape);
737
738 private:
739 RuntimeData& data() { return *static_cast<RuntimeData*>(rawData()); }
740
741 const RuntimeData& data() const {
742 return *static_cast<const RuntimeData*>(rawData());
743 }
744
745 public:
746 uint32_t nextFrameSlot() const { return data().slotInfo.nextFrameSlot; }
747
748 JSFunction* canonicalFunction() const { return data().canonicalFunction; }
749 void initCanonicalFunction(JSFunction* fun) {
750 data().canonicalFunction.init(fun);
751 }
752
753 JSScript* script() const;
754
755 bool hasParameterExprs() const { return data().slotInfo.hasParameterExprs(); }
756
757 uint32_t numPositionalFormalParameters() const {
758 return data().slotInfo.nonPositionalFormalStart;
759 }
760
761 static bool isSpecialName(frontend::TaggedParserAtomIndex name);
762};
763
764//
765// Scope holding only vars. There is a single kind of VarScopes.
766//
767// FunctionBodyVar
768// Corresponds to the extra var scope present in functions with parameter
769// expressions. See examples in comment above FunctionScope.
770//
771// Corresponds to VarEnvironmentObject on environment chain.
772//
773class VarScope : public Scope {
774 friend class GCMarker;
775 friend class AbstractBindingIter<JSAtom>;
776 friend class Scope;
777 friend class frontend::ScopeStencil;
778
779 public:
780 struct SlotInfo {
781 // Frame slots [0, nextFrameSlot) are live when this is the innermost
782 // scope.
783 uint32_t nextFrameSlot = 0;
784
785 // All bindings are vars.
786 //
787 // vars - [0, length)
788 };
789
790 using RuntimeData = RuntimeScopeData<SlotInfo>;
791 using ParserData = ParserScopeData<SlotInfo>;
792
793 template <typename NameT>
794 using AbstractData =
795 typename std::conditional_t<std::is_same<NameT, JSAtom>::value,
796 RuntimeData, ParserData>;
797
798 private:
799 static void prepareForScopeCreation(ScopeKind kind,
800 VarScope::ParserData* data,
801 uint32_t firstFrameSlot,
802 bool needsEnvironment,
803 mozilla::Maybe<uint32_t>* envShape);
804
805 RuntimeData& data() { return *static_cast<RuntimeData*>(rawData()); }
806
807 const RuntimeData& data() const {
808 return *static_cast<const RuntimeData*>(rawData());
809 }
810
811 public:
812 uint32_t nextFrameSlot() const { return data().slotInfo.nextFrameSlot; }
813};
814
815template <>
816inline bool Scope::is<VarScope>() const {
817 return kind_ == ScopeKind::FunctionBodyVar;
818}
819
820//
821// Scope corresponding to both the global object scope and the global lexical
822// scope.
823//
824// Both are extensible and are singletons across <script> tags, so these
825// scopes are a fragment of the names in global scope. In other words, two
826// global scripts may have two different GlobalScopes despite having the same
827// GlobalObject.
828//
829// There are 2 kinds of GlobalScopes.
830//
831// Global
832// Corresponds to a GlobalObject and its GlobalLexicalEnvironmentObject on
833// the environment chain.
834//
835// NonSyntactic
836// Corresponds to a non-GlobalObject created by the embedding on the
837// environment chain. This distinction is important for optimizations.
838//
839class GlobalScope : public Scope {
840 friend class Scope;
841 friend class AbstractBindingIter<JSAtom>;
842 friend class GCMarker;
843
844 public:
845 struct SlotInfo {
846 // Bindings are sorted by kind.
847 // `vars` includes top-level functions which is distinguished by a bit
848 // on the BindingName.
849 //
850 // vars - [0, letStart)
851 // lets - [letStart, constStart)
852 // consts - [constStart, length)
853 uint32_t letStart = 0;
854 uint32_t constStart = 0;
855 };
856
857 using RuntimeData = RuntimeScopeData<SlotInfo>;
858 using ParserData = ParserScopeData<SlotInfo>;
859
860 template <typename NameT>
861 using AbstractData =
862 typename std::conditional_t<std::is_same<NameT, JSAtom>::value,
863 RuntimeData, ParserData>;
864
865 static GlobalScope* createEmpty(JSContext* cx, ScopeKind kind);
866
867 private:
868 static GlobalScope* createWithData(
869 JSContext* cx, ScopeKind kind,
870 MutableHandle<UniquePtr<RuntimeData>> data);
871
872 RuntimeData& data() { return *static_cast<RuntimeData*>(rawData()); }
873
874 const RuntimeData& data() const {
875 return *static_cast<const RuntimeData*>(rawData());
876 }
877
878 public:
879 bool isSyntactic() const { return kind() != ScopeKind::NonSyntactic; }
880
881 bool hasBindings() const { return data().length > 0; }
882};
883
884template <>
885inline bool Scope::is<GlobalScope>() const {
886 return kind_ == ScopeKind::Global || kind_ == ScopeKind::NonSyntactic;
887}
888
889//
890// Scope of a 'with' statement. Has no bindings.
891//
892// Corresponds to a WithEnvironmentObject on the environment chain.
893class WithScope : public Scope {
894 friend class Scope;
895 friend class AbstractScopePtr;
896 static const ScopeKind classScopeKind_ = ScopeKind::With;
897
898 public:
899 static WithScope* create(JSContext* cx, Handle<Scope*> enclosing);
900};
901
902//
903// Scope of an eval. Holds var bindings. There are 2 kinds of EvalScopes.
904//
905// StrictEval
906// A strict eval. Corresponds to a VarEnvironmentObject, where its var
907// bindings lives.
908//
909// Eval
910// A sloppy eval. This is an empty scope, used only in the frontend, to
911// detect redeclaration errors. It has no Environment. Any `var`s declared
912// in the eval code are bound on the nearest enclosing var environment.
913//
914class EvalScope : public Scope {
915 friend class Scope;
916 friend class AbstractBindingIter<JSAtom>;
917 friend class GCMarker;
918 friend class frontend::ScopeStencil;
919
920 public:
921 struct SlotInfo {
922 // Frame slots [0, nextFrameSlot) are live when this is the innermost
923 // scope.
924 uint32_t nextFrameSlot = 0;
925
926 // All bindings in an eval script are 'var' bindings. The implicit
927 // lexical scope around the eval is present regardless of strictness
928 // and is its own LexicalScope.
929 // `vars` includes top-level functions which is distinguished by a bit
930 // on the BindingName.
931 //
932 // vars - [0, length)
933 };
934
935 using RuntimeData = RuntimeScopeData<SlotInfo>;
936 using ParserData = ParserScopeData<SlotInfo>;
937
938 template <typename NameT>
939 using AbstractData =
940 typename std::conditional_t<std::is_same<NameT, JSAtom>::value,
941 RuntimeData, ParserData>;
942
943 private:
944 static void prepareForScopeCreation(ScopeKind scopeKind,
945 EvalScope::ParserData* data,
946 mozilla::Maybe<uint32_t>* envShape);
947
948 RuntimeData& data() { return *static_cast<RuntimeData*>(rawData()); }
949
950 const RuntimeData& data() const {
951 return *static_cast<const RuntimeData*>(rawData());
952 }
953
954 public:
955 // Starting a scope, the nearest var scope that a direct eval can
956 // introduce vars on.
957 static Scope* nearestVarScopeForDirectEval(Scope* scope);
958
959 uint32_t nextFrameSlot() const { return data().slotInfo.nextFrameSlot; }
960
961 bool strict() const { return kind() == ScopeKind::StrictEval; }
962
963 bool hasBindings() const { return data().length > 0; }
964
965 bool isNonGlobal() const {
966 if (strict()) {
967 return true;
968 }
969 return !nearestVarScopeForDirectEval(enclosing())->is<GlobalScope>();
970 }
971};
972
973template <>
974inline bool Scope::is<EvalScope>() const {
975 return kind_ == ScopeKind::Eval || kind_ == ScopeKind::StrictEval;
976}
977
978//
979// Scope corresponding to the toplevel script in an ES module.
980//
981// Like GlobalScopes, these scopes contain both vars and lexical bindings, as
982// the treating of imports and exports requires putting them in one scope.
983//
984// Corresponds to a ModuleEnvironmentObject on the environment chain.
985//
986class ModuleScope : public Scope {
987 friend class GCMarker;
988 friend class AbstractBindingIter<JSAtom>;
989 friend class Scope;
990 friend class AbstractScopePtr;
991 friend class frontend::ScopeStencil;
992 static const ScopeKind classScopeKind_ = ScopeKind::Module;
993
994 public:
995 struct SlotInfo {
996 // Frame slots [0, nextFrameSlot) are live when this is the innermost
997 // scope.
998 uint32_t nextFrameSlot = 0;
999
1000 // Bindings are sorted by kind.
1001 //
1002 // imports - [0, varStart)
1003 // vars - [varStart, letStart)
1004 // lets - [letStart, constStart)
1005 // consts - [constStart, length)
1006 uint32_t varStart = 0;
1007 uint32_t letStart = 0;
1008 uint32_t constStart = 0;
1009#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1010 // consts - [constStart, usingStart)
1011 // usings - [usingStart, length)
1012 uint32_t usingStart = 0;
1013#endif
1014 };
1015
1016 struct alignas(ScopeDataAlignBytes) RuntimeData
1017 : public AbstractBaseScopeData<JSAtom> {
1018 SlotInfo slotInfo;
1019 // The module of the scope.
1020 HeapPtr<ModuleObject*> module = {};
1021
1022 explicit RuntimeData(size_t length);
1023 RuntimeData() = delete;
1024
1025 void trace(JSTracer* trc);
1026 };
1027
1028 using ParserData = ParserScopeData<SlotInfo>;
1029
1030 template <typename NameT>
1031 using AbstractData =
1032 typename std::conditional_t<std::is_same<NameT, JSAtom>::value,
1033 RuntimeData, ParserData>;
1034
1035 private:
1036 static void prepareForScopeCreation(ModuleScope::ParserData* data,
1037 mozilla::Maybe<uint32_t>* envShape);
1038
1039 RuntimeData& data() { return *static_cast<RuntimeData*>(rawData()); }
1040
1041 const RuntimeData& data() const {
1042 return *static_cast<const RuntimeData*>(rawData());
1043 }
1044
1045 public:
1046 uint32_t nextFrameSlot() const { return data().slotInfo.nextFrameSlot; }
1047
1048 ModuleObject* module() const { return data().module; }
1049 void initModule(ModuleObject* mod) { return data().module.init(mod); }
1050
1051 // Off-thread compilation needs to calculate environmentChainLength for
1052 // an emptyGlobalScope where the global may not be available.
1053 static const size_t EnclosingEnvironmentChainLength = 1;
1054};
1055
1056class WasmInstanceScope : public Scope {
1057 friend class AbstractBindingIter<JSAtom>;
1058 friend class Scope;
1059 friend class GCMarker;
1060 friend class AbstractScopePtr;
1061 static const ScopeKind classScopeKind_ = ScopeKind::WasmInstance;
1062
1063 public:
1064 struct SlotInfo {
1065 // Frame slots [0, nextFrameSlot) are live when this is the innermost
1066 // scope.
1067 uint32_t nextFrameSlot = 0;
1068
1069 // Bindings list the WASM memories and globals.
1070 //
1071 // memories - [0, globalsStart)
1072 // globals - [globalsStart, length)
1073 uint32_t memoriesStart = 0;
1074 uint32_t globalsStart = 0;
1075 };
1076
1077 struct alignas(ScopeDataAlignBytes) RuntimeData
1078 : public AbstractBaseScopeData<JSAtom> {
1079 SlotInfo slotInfo;
1080 // The wasm instance of the scope.
1081 HeapPtr<WasmInstanceObject*> instance = {};
1082
1083 explicit RuntimeData(size_t length);
1084 RuntimeData() = delete;
1085
1086 void trace(JSTracer* trc);
1087 };
1088
1089 using ParserData = ParserScopeData<SlotInfo>;
1090
1091 template <typename NameT>
1092 using AbstractData =
1093 typename std::conditional_t<std::is_same<NameT, JSAtom>::value,
1094 RuntimeData, ParserData>;
1095
1096 static WasmInstanceScope* create(JSContext* cx, WasmInstanceObject* instance);
1097
1098 private:
1099 RuntimeData& data() { return *static_cast<RuntimeData*>(rawData()); }
1100
1101 const RuntimeData& data() const {
1102 return *static_cast<const RuntimeData*>(rawData());
1103 }
1104
1105 public:
1106 WasmInstanceObject* instance() const { return data().instance; }
1107
1108 uint32_t memoriesStart() const { return data().slotInfo.memoriesStart; }
1109
1110 uint32_t globalsStart() const { return data().slotInfo.globalsStart; }
1111
1112 uint32_t namesCount() const { return data().length; }
1113};
1114
1115// Scope corresponding to the wasm function. A WasmFunctionScope is used by
1116// Debugger only, and not for wasm execution.
1117//
1118class WasmFunctionScope : public Scope {
1119 friend class AbstractBindingIter<JSAtom>;
1120 friend class Scope;
1121 friend class GCMarker;
1122 friend class AbstractScopePtr;
1123 static const ScopeKind classScopeKind_ = ScopeKind::WasmFunction;
1124
1125 public:
1126 struct SlotInfo {
1127 // Frame slots [0, nextFrameSlot) are live when this is the innermost
1128 // scope.
1129 uint32_t nextFrameSlot = 0;
1130
1131 // Bindings are the local variable names.
1132 //
1133 // vars - [0, length)
1134 };
1135
1136 using RuntimeData = RuntimeScopeData<SlotInfo>;
1137 using ParserData = ParserScopeData<SlotInfo>;
1138
1139 template <typename NameT>
1140 using AbstractData =
1141 typename std::conditional_t<std::is_same<NameT, JSAtom>::value,
1142 RuntimeData, ParserData>;
1143
1144 static WasmFunctionScope* create(JSContext* cx, Handle<Scope*> enclosing,
1145 uint32_t funcIndex);
1146
1147 private:
1148 RuntimeData& data() { return *static_cast<RuntimeData*>(rawData()); }
1149
1150 const RuntimeData& data() const {
1151 return *static_cast<const RuntimeData*>(rawData());
1152 }
1153};
1154
1155template <typename F>
1156void Scope::applyScopeDataTyped(F&& f) {
1157 switch (kind()) {
1158 case ScopeKind::Function: {
1159 f(&as<FunctionScope>().data());
1160 break;
1161 case ScopeKind::FunctionBodyVar:
1162 f(&as<VarScope>().data());
1163 break;
1164 case ScopeKind::Lexical:
1165 case ScopeKind::SimpleCatch:
1166 case ScopeKind::Catch:
1167 case ScopeKind::NamedLambda:
1168 case ScopeKind::StrictNamedLambda:
1169 case ScopeKind::FunctionLexical:
1170 f(&as<LexicalScope>().data());
1171 break;
1172 case ScopeKind::ClassBody:
1173 f(&as<ClassBodyScope>().data());
1174 break;
1175 case ScopeKind::With:
1176 // With scopes do not have data.
1177 break;
1178 case ScopeKind::Eval:
1179 case ScopeKind::StrictEval:
1180 f(&as<EvalScope>().data());
1181 break;
1182 case ScopeKind::Global:
1183 case ScopeKind::NonSyntactic:
1184 f(&as<GlobalScope>().data());
1185 break;
1186 case ScopeKind::Module:
1187 f(&as<ModuleScope>().data());
1188 break;
1189 case ScopeKind::WasmInstance:
1190 f(&as<WasmInstanceScope>().data());
1191 break;
1192 case ScopeKind::WasmFunction:
1193 f(&as<WasmFunctionScope>().data());
1194 break;
1195 }
1196 }
1197}
1198
1199//
1200// An iterator for a Scope's bindings. This is the source of truth for frame
1201// and environment object layout.
1202//
1203// It may be placed in GC containers; for example:
1204//
1205// for (Rooted<BindingIter> bi(cx, BindingIter(scope)); bi; bi++) {
1206// use(bi);
1207// SomeMayGCOperation();
1208// use(bi);
1209// }
1210//
1211template <typename NameT>
1212class BaseAbstractBindingIter {
1213 protected:
1214 // Bindings are sorted by kind. Because different Scopes have differently
1215 // laid out {Runtime,Parser}Data for packing, BindingIter must handle all
1216 // binding kinds.
1217 //
1218 // Kind ranges:
1219 //
1220 // imports - [0, positionalFormalStart)
1221 // positional formals - [positionalFormalStart, nonPositionalFormalStart)
1222 // other formals - [nonPositionalParamStart, varStart)
1223 // vars - [varStart, letStart)
1224 // lets - [letStart, constStart)
1225 // consts - [constStart, syntheticStart)
1226 // synthetic - [syntheticStart, privateMethodStart)
1227 // private methods = [privateMethodStart, length)
1228 //
1229 // If ENABLE_EXPLICIT_RESOURCE_MANAGEMENT is set, the consts range is split
1230 // into the following:
1231 // consts - [constStart, usingStart)
1232 // usings - [usingStart, syntheticStart)
1233 //
1234 // Access method when not closed over:
1235 //
1236 // imports - name
1237 // positional formals - argument slot
1238 // other formals - frame slot
1239 // vars - frame slot
1240 // lets - frame slot
1241 // consts - frame slot
1242 // synthetic - frame slot
1243 // private methods - frame slot
1244 //
1245 // Access method when closed over:
1246 //
1247 // imports - name
1248 // positional formals - environment slot or name
1249 // other formals - environment slot or name
1250 // vars - environment slot or name
1251 // lets - environment slot or name
1252 // consts - environment slot or name
1253 // synthetic - environment slot or name
1254 // private methods - environment slot or name
1255 MOZ_INIT_OUTSIDE_CTOR uint32_t positionalFormalStart_;
1256 MOZ_INIT_OUTSIDE_CTOR uint32_t nonPositionalFormalStart_;
1257 MOZ_INIT_OUTSIDE_CTOR uint32_t varStart_;
1258 MOZ_INIT_OUTSIDE_CTOR uint32_t letStart_;
1259 MOZ_INIT_OUTSIDE_CTOR uint32_t constStart_;
1260#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1261 MOZ_INIT_OUTSIDE_CTOR uint32_t usingStart_;
1262#endif
1263 MOZ_INIT_OUTSIDE_CTOR uint32_t syntheticStart_;
1264 MOZ_INIT_OUTSIDE_CTOR uint32_t privateMethodStart_;
1265 MOZ_INIT_OUTSIDE_CTOR uint32_t length_;
1266
1267 MOZ_INIT_OUTSIDE_CTOR uint32_t index_;
1268
1269 enum Flags : uint8_t {
1270 CannotHaveSlots = 0,
1271 CanHaveArgumentSlots = 1 << 0,
1272 CanHaveFrameSlots = 1 << 1,
1273 CanHaveEnvironmentSlots = 1 << 2,
1274
1275 // See comment in settle below.
1276 HasFormalParameterExprs = 1 << 3,
1277 IgnoreDestructuredFormalParameters = 1 << 4,
1278
1279 // Truly I hate named lambdas.
1280 IsNamedLambda = 1 << 5
1281 };
1282
1283 static const uint8_t CanHaveSlotsMask = 0x7;
1284
1285 MOZ_INIT_OUTSIDE_CTOR uint8_t flags_;
1286 MOZ_INIT_OUTSIDE_CTOR uint16_t argumentSlot_;
1287 MOZ_INIT_OUTSIDE_CTOR uint32_t frameSlot_;
1288 MOZ_INIT_OUTSIDE_CTOR uint32_t environmentSlot_;
1289
1290 MOZ_INIT_OUTSIDE_CTOR AbstractBindingName<NameT>* names_;
1291
1292 void init(uint32_t positionalFormalStart, uint32_t nonPositionalFormalStart,
1293 uint32_t varStart, uint32_t letStart, uint32_t constStart,
1294#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1295 uint32_t usingStart,
1296#endif
1297 uint32_t syntheticStart, uint32_t privateMethodStart, uint8_t flags,
1298 uint32_t firstFrameSlot, uint32_t firstEnvironmentSlot,
1299 mozilla::Span<AbstractBindingName<NameT>> names) {
1300 positionalFormalStart_ = positionalFormalStart;
1301 nonPositionalFormalStart_ = nonPositionalFormalStart;
1302 varStart_ = varStart;
1303 letStart_ = letStart;
1304 constStart_ = constStart;
1305#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1306 usingStart_ = usingStart;
1307#endif
1308 syntheticStart_ = syntheticStart;
1309 privateMethodStart_ = privateMethodStart;
1310 length_ = names.size();
1311
1312 index_ = 0;
1313 flags_ = flags;
1314 argumentSlot_ = 0;
1315 frameSlot_ = firstFrameSlot;
1316 environmentSlot_ = firstEnvironmentSlot;
1317 names_ = names.data();
1318
1319 settle();
1320 }
1321
1322 void init(LexicalScope::AbstractData<NameT>& data, uint32_t firstFrameSlot,
1323 uint8_t flags);
1324
1325 void init(ClassBodyScope::AbstractData<NameT>& data, uint32_t firstFrameSlot);
1326 void init(FunctionScope::AbstractData<NameT>& data, uint8_t flags);
1327
1328 void init(VarScope::AbstractData<NameT>& data, uint32_t firstFrameSlot);
1329 void init(GlobalScope::AbstractData<NameT>& data);
1330 void init(EvalScope::AbstractData<NameT>& data, bool strict);
1331 void init(ModuleScope::AbstractData<NameT>& data);
1332 void init(WasmInstanceScope::AbstractData<NameT>& data);
1333 void init(WasmFunctionScope::AbstractData<NameT>& data);
1334
1335 bool hasFormalParameterExprs() const {
1336 return flags_ & HasFormalParameterExprs;
1337 }
1338
1339 bool ignoreDestructuredFormalParameters() const {
1340 return flags_ & IgnoreDestructuredFormalParameters;
1341 }
1342
1343 bool isNamedLambda() const { return flags_ & IsNamedLambda; }
1344
1345 void increment() {
1346 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1346; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1347 if (flags_ & CanHaveSlotsMask) {
1348 if (canHaveArgumentSlots()) {
1349 if (index_ < nonPositionalFormalStart_) {
1350 MOZ_ASSERT(index_ >= positionalFormalStart_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(index_ >= positionalFormalStart_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(index_ >= positionalFormalStart_
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"index_ >= positionalFormalStart_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "index_ >= positionalFormalStart_"
")"); do { *((volatile int*)__null) = 1350; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1351 argumentSlot_++;
1352 }
1353 }
1354 if (closedOver()) {
1355 // Imports must not be given known slots. They are
1356 // indirect bindings.
1357 MOZ_ASSERT(kind() != BindingKind::Import)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind() != BindingKind::Import)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind() != BindingKind::Import
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"kind() != BindingKind::Import", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1357); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind() != BindingKind::Import"
")"); do { *((volatile int*)__null) = 1357; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1358 MOZ_ASSERT(canHaveEnvironmentSlots())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(canHaveEnvironmentSlots())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(canHaveEnvironmentSlots())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("canHaveEnvironmentSlots()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1358); AnnotateMozCrashReason("MOZ_ASSERT" "(" "canHaveEnvironmentSlots()"
")"); do { *((volatile int*)__null) = 1358; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1359 environmentSlot_++;
1360 } else if (canHaveFrameSlots()) {
1361 // Usually positional formal parameters don't have frame
1362 // slots, except when there are parameter expressions, in
1363 // which case they act like lets.
1364 if (index_ >= nonPositionalFormalStart_ ||
1365 (hasFormalParameterExprs() && name())) {
1366 frameSlot_++;
1367 }
1368 }
1369 }
1370 index_++;
1371 }
1372
1373 void settle() {
1374 if (ignoreDestructuredFormalParameters()) {
1375 while (!done() && !name()) {
1376 increment();
1377 }
1378 }
1379 }
1380
1381 BaseAbstractBindingIter() = default;
1382
1383 public:
1384 BaseAbstractBindingIter(LexicalScope::AbstractData<NameT>& data,
1385 uint32_t firstFrameSlot, bool isNamedLambda) {
1386 init(data, firstFrameSlot, isNamedLambda ? IsNamedLambda : 0);
1387 }
1388
1389 BaseAbstractBindingIter(ClassBodyScope::AbstractData<NameT>& data,
1390 uint32_t firstFrameSlot) {
1391 init(data, firstFrameSlot);
1392 }
1393
1394 BaseAbstractBindingIter(FunctionScope::AbstractData<NameT>& data,
1395 bool hasParameterExprs) {
1396 init(data, IgnoreDestructuredFormalParameters |
1397 (hasParameterExprs ? HasFormalParameterExprs : 0));
1398 }
1399
1400 BaseAbstractBindingIter(VarScope::AbstractData<NameT>& data,
1401 uint32_t firstFrameSlot) {
1402 init(data, firstFrameSlot);
1403 }
1404
1405 explicit BaseAbstractBindingIter(GlobalScope::AbstractData<NameT>& data) {
1406 init(data);
1407 }
1408
1409 explicit BaseAbstractBindingIter(ModuleScope::AbstractData<NameT>& data) {
1410 init(data);
1411 }
1412
1413 explicit BaseAbstractBindingIter(
1414 WasmFunctionScope::AbstractData<NameT>& data) {
1415 init(data);
1416 }
1417
1418 BaseAbstractBindingIter(EvalScope::AbstractData<NameT>& data, bool strict) {
1419 init(data, strict);
1420 }
1421
1422 MOZ_IMPLICIT BaseAbstractBindingIter(
1423 const BaseAbstractBindingIter<NameT>& bi) = default;
1424
1425 bool done() const { return index_ == length_; }
1426
1427 explicit operator bool() const { return !done(); }
1428
1429 void operator++(int) {
1430 increment();
1431 settle();
1432 }
1433
1434 bool isLast() const {
1435 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1435); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1435; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1436 return index_ + 1 == length_;
1437 }
1438
1439 bool canHaveArgumentSlots() const { return flags_ & CanHaveArgumentSlots; }
1440
1441 bool canHaveFrameSlots() const { return flags_ & CanHaveFrameSlots; }
1442
1443 bool canHaveEnvironmentSlots() const {
1444 return flags_ & CanHaveEnvironmentSlots;
1445 }
1446
1447 typename AbstractBindingName<NameT>::NamePointerT name() const {
1448 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1449 return names_[index_].name();
1450 }
1451
1452 bool closedOver() const {
1453 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1454 return names_[index_].closedOver();
1455 }
1456
1457 BindingLocation location() const {
1458 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1458); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1458; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1459 if (!(flags_ & CanHaveSlotsMask)) {
1460 return BindingLocation::Global();
1461 }
1462 if (index_ < positionalFormalStart_) {
1463 return BindingLocation::Import();
1464 }
1465 if (closedOver()) {
1466 MOZ_ASSERT(canHaveEnvironmentSlots())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(canHaveEnvironmentSlots())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(canHaveEnvironmentSlots())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("canHaveEnvironmentSlots()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1466); AnnotateMozCrashReason("MOZ_ASSERT" "(" "canHaveEnvironmentSlots()"
")"); do { *((volatile int*)__null) = 1466; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1467 return BindingLocation::Environment(environmentSlot_);
1468 }
1469 if (index_ < nonPositionalFormalStart_ && canHaveArgumentSlots()) {
1470 return BindingLocation::Argument(argumentSlot_);
1471 }
1472 if (canHaveFrameSlots()) {
1473 return BindingLocation::Frame(frameSlot_);
1474 }
1475 MOZ_ASSERT(isNamedLambda())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isNamedLambda())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isNamedLambda()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("isNamedLambda()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1475); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isNamedLambda()"
")"); do { *((volatile int*)__null) = 1475; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1476 return BindingLocation::NamedLambdaCallee();
1477 }
1478
1479 BindingKind kind() const {
1480 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1480); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1480; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1481 if (index_ < positionalFormalStart_) {
1482 return BindingKind::Import;
1483 }
1484 if (index_ < varStart_) {
1485 // When the parameter list has expressions, the parameters act
1486 // like lexical bindings and have TDZ.
1487 if (hasFormalParameterExprs()) {
1488 return BindingKind::Let;
1489 }
1490 return BindingKind::FormalParameter;
1491 }
1492 if (index_ < letStart_) {
1493 return BindingKind::Var;
1494 }
1495 if (index_ < constStart_) {
1496 return BindingKind::Let;
1497 }
1498#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1499 if (index_ < usingStart_) {
1500 return isNamedLambda() ? BindingKind::NamedLambdaCallee
1501 : BindingKind::Const;
1502 }
1503 if (index_ < syntheticStart_) {
1504 return BindingKind::Using;
1505 }
1506#else
1507 if (index_ < syntheticStart_) {
1508 return isNamedLambda() ? BindingKind::NamedLambdaCallee
1509 : BindingKind::Const;
1510 }
1511#endif
1512 if (index_ < privateMethodStart_) {
1513 return BindingKind::Synthetic;
1514 }
1515 return BindingKind::PrivateMethod;
1516 }
1517
1518 js::frontend::NameLocation nameLocation() const {
1519 using js::frontend::NameLocation;
1520
1521 BindingKind bindKind = kind();
1522 BindingLocation bl = location();
1523 switch (bl.kind()) {
1524 case BindingLocation::Kind::Global:
1525 return NameLocation::Global(bindKind);
1526 case BindingLocation::Kind::Argument:
1527 return NameLocation::ArgumentSlot(bl.argumentSlot());
1528 case BindingLocation::Kind::Frame:
1529 return NameLocation::FrameSlot(bindKind, bl.slot());
1530 case BindingLocation::Kind::Environment:
1531 return NameLocation::EnvironmentCoordinate(bindKind, 0, bl.slot());
1532 case BindingLocation::Kind::Import:
1533 return NameLocation::Import();
1534 case BindingLocation::Kind::NamedLambdaCallee:
1535 return NameLocation::NamedLambdaCallee();
1536 }
1537 MOZ_CRASH("Bad BindingKind")do { do { } while (false); MOZ_ReportCrash("" "Bad BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1537); AnnotateMozCrashReason("MOZ_CRASH(" "Bad BindingKind"
")"); do { *((volatile int*)__null) = 1537; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1538 }
1539
1540 bool isTopLevelFunction() const {
1541 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1541); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1541; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1542 bool result = names_[index_].isTopLevelFunction();
1543 MOZ_ASSERT_IF(result, kind() == BindingKind::Var)do { if (result) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(kind() == BindingKind::Var)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind() == BindingKind::Var))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("kind() == BindingKind::Var"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1543); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind() == BindingKind::Var"
")"); do { *((volatile int*)__null) = 1543; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1544 return result;
1545 }
1546
1547 bool hasArgumentSlot() const {
1548 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1548); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1548; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1549 if (hasFormalParameterExprs()) {
1550 return false;
1551 }
1552 return index_ >= positionalFormalStart_ &&
1553 index_ < nonPositionalFormalStart_;
1554 }
1555
1556 uint16_t argumentSlot() const {
1557 MOZ_ASSERT(canHaveArgumentSlots())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(canHaveArgumentSlots())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(canHaveArgumentSlots()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("canHaveArgumentSlots()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1557); AnnotateMozCrashReason("MOZ_ASSERT" "(" "canHaveArgumentSlots()"
")"); do { *((volatile int*)__null) = 1557; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1558 return mozilla::AssertedCast<uint16_t>(index_);
1559 }
1560
1561 uint32_t nextFrameSlot() const {
1562 MOZ_ASSERT(canHaveFrameSlots())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(canHaveFrameSlots())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(canHaveFrameSlots()))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("canHaveFrameSlots()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1562); AnnotateMozCrashReason("MOZ_ASSERT" "(" "canHaveFrameSlots()"
")"); do { *((volatile int*)__null) = 1562; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1563 return frameSlot_;
1564 }
1565
1566 uint32_t nextEnvironmentSlot() const {
1567 MOZ_ASSERT(canHaveEnvironmentSlots())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(canHaveEnvironmentSlots())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(canHaveEnvironmentSlots())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("canHaveEnvironmentSlots()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1567); AnnotateMozCrashReason("MOZ_ASSERT" "(" "canHaveEnvironmentSlots()"
")"); do { *((volatile int*)__null) = 1567; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1568 return environmentSlot_;
1569 }
1570};
1571
1572template <typename NameT>
1573class AbstractBindingIter;
1574
1575template <>
1576class AbstractBindingIter<JSAtom> : public BaseAbstractBindingIter<JSAtom> {
1577 using Base = BaseAbstractBindingIter<JSAtom>;
1578
1579 public:
1580 AbstractBindingIter(ScopeKind kind, BaseScopeData* data,
1581 uint32_t firstFrameSlot);
1582
1583 explicit AbstractBindingIter(Scope* scope);
1584 explicit AbstractBindingIter(JSScript* script);
1585
1586 using Base::Base;
1587
1588 inline void trace(JSTracer* trc) {
1589 TraceNullableBindingNames(trc, names_, length_);
1590 }
1591};
1592
1593template <>
1594class AbstractBindingIter<frontend::TaggedParserAtomIndex>
1595 : public BaseAbstractBindingIter<frontend::TaggedParserAtomIndex> {
1596 using Base = BaseAbstractBindingIter<frontend::TaggedParserAtomIndex>;
1597
1598 public:
1599 explicit AbstractBindingIter(const frontend::ScopeStencilRef& ref);
1600
1601 using Base::Base;
1602};
1603
1604void DumpBindings(JSContext* cx, Scope* scope);
1605JSAtom* FrameSlotName(JSScript* script, jsbytecode* pc);
1606
1607SharedShape* EmptyEnvironmentShape(JSContext* cx, const JSClass* cls,
1608 uint32_t numSlots, ObjectFlags objectFlags);
1609
1610template <class T>
1611SharedShape* EmptyEnvironmentShape(JSContext* cx) {
1612 return EmptyEnvironmentShape(cx, &T::class_, T::RESERVED_SLOTS,
1613 T::OBJECT_FLAGS);
1614}
1615
1616//
1617// PositionalFormalParameterIter is a refinement BindingIter that only iterates
1618// over positional formal parameters of a function.
1619//
1620template <typename NameT>
1621class BasePositionalFormalParamterIter : public AbstractBindingIter<NameT> {
1622 using Base = AbstractBindingIter<NameT>;
1623
1624 protected:
1625 void settle() {
1626 if (this->index_ >= this->nonPositionalFormalStart_) {
1627 this->index_ = this->length_;
1628 }
1629 }
1630
1631 public:
1632 using Base::Base;
1633
1634 void operator++(int) {
1635 Base::operator++(1);
1636 settle();
1637 }
1638
1639 bool isDestructured() const { return !this->name(); }
1640};
1641
1642template <typename NameT>
1643class AbstractPositionalFormalParameterIter;
1644
1645template <>
1646class AbstractPositionalFormalParameterIter<JSAtom>
1647 : public BasePositionalFormalParamterIter<JSAtom> {
1648 using Base = BasePositionalFormalParamterIter<JSAtom>;
1649
1650 public:
1651 explicit AbstractPositionalFormalParameterIter(Scope* scope);
1652 explicit AbstractPositionalFormalParameterIter(JSScript* script);
1653
1654 using Base::Base;
1655};
1656
1657template <>
1658class AbstractPositionalFormalParameterIter<frontend::TaggedParserAtomIndex>
1659 : public BasePositionalFormalParamterIter<frontend::TaggedParserAtomIndex> {
1660 using Base =
1661 BasePositionalFormalParamterIter<frontend::TaggedParserAtomIndex>;
1662
1663 public:
1664 AbstractPositionalFormalParameterIter(
1665 FunctionScope::AbstractData<frontend::TaggedParserAtomIndex>& data,
1666 bool hasParameterExprs)
1667 : Base(data, hasParameterExprs) {
1668 settle();
1669 }
1670
1671 using Base::Base;
1672};
1673
1674using PositionalFormalParameterIter =
1675 AbstractPositionalFormalParameterIter<JSAtom>;
1676
1677//
1678// Iterator for walking the scope chain.
1679//
1680// It may be placed in GC containers; for example:
1681//
1682// for (Rooted<ScopeIter> si(cx, ScopeIter(scope)); si; si++) {
1683// use(si);
1684// SomeMayGCOperation();
1685// use(si);
1686// }
1687//
1688class MOZ_STACK_CLASS ScopeIter {
1689 Scope* scope_;
1690
1691 public:
1692 explicit ScopeIter(Scope* scope) : scope_(scope) {}
1693
1694 explicit ScopeIter(JSScript* script);
1695
1696 explicit ScopeIter(const ScopeIter& si) = default;
1697
1698 bool done() const { return !scope_; }
1699
1700 explicit operator bool() const { return !done(); }
1701
1702 void operator++(int) {
1703 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1703); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1703; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1704 scope_ = scope_->enclosing();
1705 }
1706
1707 Scope* scope() const {
1708 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1708); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1708; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1709 return scope_;
1710 }
1711
1712 ScopeKind kind() const {
1713 MOZ_ASSERT(!done())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!done())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!done()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!done()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1713); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 1713; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1714 return scope_->kind();
1715 }
1716
1717 // Returns the shape of the environment if it is known. It is possible to
1718 // hasSyntacticEnvironment and to have no known shape, e.g., eval.
1719 SharedShape* environmentShape() const { return scope()->environmentShape(); }
1720
1721 // Returns whether this scope has a syntactic environment (i.e., an
1722 // Environment that isn't a non-syntactic With or NonSyntacticVariables)
1723 // on the environment chain.
1724 bool hasSyntacticEnvironment() const;
1725
1726 void trace(JSTracer* trc) {
1727 if (scope_) {
1728 TraceRoot(trc, &scope_, "scope iter scope");
1729 }
1730 }
1731};
1732
1733//
1734// Specializations of Rooted containers for the iterators.
1735//
1736
1737template <typename Wrapper>
1738class WrappedPtrOperations<BindingIter, Wrapper> {
1739 const BindingIter& iter() const {
1740 return static_cast<const Wrapper*>(this)->get();
1741 }
1742
1743 public:
1744 bool done() const { return iter().done(); }
1745 explicit operator bool() const { return !done(); }
1746 bool isLast() const { return iter().isLast(); }
1747 bool canHaveArgumentSlots() const { return iter().canHaveArgumentSlots(); }
1748 bool canHaveFrameSlots() const { return iter().canHaveFrameSlots(); }
1749 bool canHaveEnvironmentSlots() const {
1750 return iter().canHaveEnvironmentSlots();
1751 }
1752 JSAtom* name() const { return iter().name(); }
1753 bool closedOver() const { return iter().closedOver(); }
1754 BindingLocation location() const { return iter().location(); }
1755 BindingKind kind() const { return iter().kind(); }
1756 bool isTopLevelFunction() const { return iter().isTopLevelFunction(); }
1757 bool hasArgumentSlot() const { return iter().hasArgumentSlot(); }
1758 uint16_t argumentSlot() const { return iter().argumentSlot(); }
1759 uint32_t nextFrameSlot() const { return iter().nextFrameSlot(); }
1760 uint32_t nextEnvironmentSlot() const { return iter().nextEnvironmentSlot(); }
1761};
1762
1763template <typename Wrapper>
1764class MutableWrappedPtrOperations<BindingIter, Wrapper>
1765 : public WrappedPtrOperations<BindingIter, Wrapper> {
1766 BindingIter& iter() { return static_cast<Wrapper*>(this)->get(); }
1767
1768 public:
1769 void operator++(int) { iter().operator++(1); }
1770};
1771
1772template <typename Wrapper>
1773class WrappedPtrOperations<ScopeIter, Wrapper> {
1774 const ScopeIter& iter() const {
1775 return static_cast<const Wrapper*>(this)->get();
1776 }
1777
1778 public:
1779 bool done() const { return iter().done(); }
1780 explicit operator bool() const { return !done(); }
1781 Scope* scope() const { return iter().scope(); }
1782 ScopeKind kind() const { return iter().kind(); }
1783 SharedShape* environmentShape() const { return iter().environmentShape(); }
1784 bool hasSyntacticEnvironment() const {
1785 return iter().hasSyntacticEnvironment();
1786 }
1787};
1788
1789template <typename Wrapper>
1790class MutableWrappedPtrOperations<ScopeIter, Wrapper>
1791 : public WrappedPtrOperations<ScopeIter, Wrapper> {
1792 ScopeIter& iter() { return static_cast<Wrapper*>(this)->get(); }
1793
1794 public:
1795 void operator++(int) { iter().operator++(1); }
1796};
1797
1798SharedShape* CreateEnvironmentShape(JSContext* cx, BindingIter& bi,
1799 const JSClass* cls, uint32_t numSlots,
1800 ObjectFlags objectFlags);
1801
1802SharedShape* CreateEnvironmentShapeForSyntheticModule(
1803 JSContext* cx, const JSClass* cls, uint32_t numSlots,
1804 Handle<ModuleObject*> module);
1805
1806SharedShape* EmptyEnvironmentShape(JSContext* cx, const JSClass* cls,
1807 uint32_t numSlots, ObjectFlags objectFlags);
1808
1809static inline size_t GetOffsetOfParserScopeDataTrailingNames(ScopeKind kind) {
1810 switch (kind) {
1811 // FunctionScope
1812 case ScopeKind::Function:
1813 return GetOffsetOfScopeDataTrailingNames<FunctionScope::ParserData>();
1814
1815 // VarScope
1816 case ScopeKind::FunctionBodyVar:
1817 return GetOffsetOfScopeDataTrailingNames<VarScope::ParserData>();
1818
1819 // LexicalScope
1820 case ScopeKind::Lexical:
1821 case ScopeKind::SimpleCatch:
1822 case ScopeKind::Catch:
1823 case ScopeKind::NamedLambda:
1824 case ScopeKind::StrictNamedLambda:
1825 case ScopeKind::FunctionLexical:
1826 return GetOffsetOfScopeDataTrailingNames<LexicalScope::ParserData>();
1827
1828 // ClassBodyScope
1829 case ScopeKind::ClassBody:
1830 return GetOffsetOfScopeDataTrailingNames<ClassBodyScope::ParserData>();
1831
1832 // EvalScope
1833 case ScopeKind::Eval:
1834 case ScopeKind::StrictEval:
1835 return GetOffsetOfScopeDataTrailingNames<EvalScope::ParserData>();
1836
1837 // GlobalScope
1838 case ScopeKind::Global:
1839 case ScopeKind::NonSyntactic:
1840 return GetOffsetOfScopeDataTrailingNames<GlobalScope::ParserData>();
1841
1842 // ModuleScope
1843 case ScopeKind::Module:
1844 return GetOffsetOfScopeDataTrailingNames<ModuleScope::ParserData>();
1845
1846 // WasmInstanceScope
1847 case ScopeKind::WasmInstance:
1848 return GetOffsetOfScopeDataTrailingNames<WasmInstanceScope::ParserData>();
1849
1850 // WasmFunctionScope
1851 case ScopeKind::WasmFunction:
1852 return GetOffsetOfScopeDataTrailingNames<WasmFunctionScope::ParserData>();
1853
1854 // WithScope doesn't have ScopeData.
1855 case ScopeKind::With:
1856 default:
1857 MOZ_CRASH("Unexpected ScopeKind")do { do { } while (false); MOZ_ReportCrash("" "Unexpected ScopeKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/vm/Scope.h"
, 1857); AnnotateMozCrashReason("MOZ_CRASH(" "Unexpected ScopeKind"
")"); do { *((volatile int*)__null) = 1857; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1858 }
1859
1860 return 0;
1861}
1862
1863inline size_t SizeOfParserScopeData(ScopeKind kind, uint32_t length) {
1864 return GetOffsetOfParserScopeDataTrailingNames(kind) +
1865 sizeof(AbstractBindingName<frontend::TaggedParserAtomIndex>) * length;
1866}
1867
1868inline mozilla::Span<AbstractBindingName<frontend::TaggedParserAtomIndex>>
1869GetParserScopeDataTrailingNames(
1870 ScopeKind kind,
1871 AbstractBaseScopeData<frontend::TaggedParserAtomIndex>* data) {
1872 return mozilla::Span(
1873 reinterpret_cast<AbstractBindingName<frontend::TaggedParserAtomIndex>*>(
1874 uintptr_t(data) + GetOffsetOfParserScopeDataTrailingNames(kind)),
1875 data->length);
1876}
1877
1878} // namespace js
1879
1880namespace JS {
1881
1882template <>
1883struct GCPolicy<js::ScopeKind> : public IgnoreGCPolicy<js::ScopeKind> {};
1884
1885template <typename T>
1886struct ScopeDataGCPolicy : public NonGCPointerPolicy<T> {};
1887
1888#define DEFINE_SCOPE_DATA_GCPOLICY(Data) \
1889 template <> \
1890 struct MapTypeToRootKind<Data*> { \
1891 static const RootKind kind = RootKind::Traceable; \
1892 }; \
1893 template <> \
1894 struct GCPolicy<Data*> : public ScopeDataGCPolicy<Data*> {}
1895
1896DEFINE_SCOPE_DATA_GCPOLICY(js::LexicalScope::RuntimeData);
1897DEFINE_SCOPE_DATA_GCPOLICY(js::ClassBodyScope::RuntimeData);
1898DEFINE_SCOPE_DATA_GCPOLICY(js::FunctionScope::RuntimeData);
1899DEFINE_SCOPE_DATA_GCPOLICY(js::VarScope::RuntimeData);
1900DEFINE_SCOPE_DATA_GCPOLICY(js::GlobalScope::RuntimeData);
1901DEFINE_SCOPE_DATA_GCPOLICY(js::EvalScope::RuntimeData);
1902DEFINE_SCOPE_DATA_GCPOLICY(js::ModuleScope::RuntimeData);
1903DEFINE_SCOPE_DATA_GCPOLICY(js::WasmFunctionScope::RuntimeData);
1904
1905#undef DEFINE_SCOPE_DATA_GCPOLICY
1906
1907namespace ubi {
1908
1909template <>
1910class Concrete<js::Scope> : TracerConcrete<js::Scope> {
1911 protected:
1912 explicit Concrete(js::Scope* ptr) : TracerConcrete<js::Scope>(ptr) {}
1913
1914 public:
1915 static void construct(void* storage, js::Scope* ptr) {
1916 new (storage) Concrete(ptr);
1917 }
1918
1919 CoarseType coarseType() const final { return CoarseType::Script; }
1920
1921 Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
1922
1923 const char16_t* typeName() const override { return concreteTypeName; }
1924 static const char16_t concreteTypeName[];
1925};
1926
1927} // namespace ubi
1928} // namespace JS
1929
1930#endif // vm_Scope_h