Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h
Warning:line 348, column 28
1st function call argument is an uninitialized value

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-20/lib/clang/20 -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 _GLIBCXX_ASSERTIONS -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-20/lib/clang/20/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 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -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-2025-01-20-090804-167946-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/StringBuilder.h" // StringBuilder
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 CompilationState& compilationState)
168 : ParserSharedBase(fc, compilationState, ParserSharedBase::Kind::Parser),
169 anyChars(fc, options, this),
170 ss(nullptr),
171#ifdef DEBUG1
172 checkOptionsCalled_(false),
173#endif
174 isUnexpectedEOF_(false),
175 awaitHandling_(AwaitIsName),
176 inParametersOfAsyncFunction_(false) {
177}
178
179bool ParserBase::checkOptions() {
180#ifdef DEBUG1
181 checkOptionsCalled_ = true;
182#endif
183
184 return anyChars.checkOptions();
185}
186
187ParserBase::~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"
, 187); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 187; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; }
188
189JSAtom* ParserBase::liftParserAtomToJSAtom(TaggedParserAtomIndex index) {
190 JSContext* cx = fc_->maybeCurrentJSContext();
191 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"
, 191); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cx" ")"); do
{ *((volatile int*)__null) = 191; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
192 return parserAtoms().toJSAtom(cx, fc_, index,
193 compilationState_.input.atomCache);
194}
195
196template <class ParseHandler>
197PerHandlerParser<ParseHandler>::PerHandlerParser(
198 FrontendContext* fc, const ReadOnlyCompileOptions& options,
199 CompilationState& compilationState, void* internalSyntaxParser)
200 : ParserBase(fc, options, compilationState),
201 handler_(fc, compilationState),
202 internalSyntaxParser_(internalSyntaxParser) {
203 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"
, 204); AnnotateMozCrashReason("MOZ_ASSERT" "(" "compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
")"); do { *((volatile int*)__null) = 204; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
204 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"
, 204); AnnotateMozCrashReason("MOZ_ASSERT" "(" "compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
")"); do { *((volatile int*)__null) = 204; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
205}
206
207template <class ParseHandler, typename Unit>
208GeneralParser<ParseHandler, Unit>::GeneralParser(
209 FrontendContext* fc, const ReadOnlyCompileOptions& options,
210 const Unit* units, size_t length, CompilationState& compilationState,
211 SyntaxParser* syntaxParser)
212 : Base(fc, options, compilationState, syntaxParser),
213 tokenStream(fc, &compilationState.parserAtoms, options, units, length) {}
214
215template <typename Unit>
216void Parser<SyntaxParseHandler, Unit>::setAwaitHandling(
217 AwaitHandling awaitHandling) {
218 this->awaitHandling_ = awaitHandling;
219}
220
221template <typename Unit>
222void Parser<FullParseHandler, Unit>::setAwaitHandling(
223 AwaitHandling awaitHandling) {
224 this->awaitHandling_ = awaitHandling;
225 if (SyntaxParser* syntaxParser = getSyntaxParser()) {
226 syntaxParser->setAwaitHandling(awaitHandling);
227 }
228}
229
230template <class ParseHandler, typename Unit>
231inline void GeneralParser<ParseHandler, Unit>::setAwaitHandling(
232 AwaitHandling awaitHandling) {
233 asFinalParser()->setAwaitHandling(awaitHandling);
234}
235
236template <typename Unit>
237void Parser<SyntaxParseHandler, Unit>::setInParametersOfAsyncFunction(
238 bool inParameters) {
239 this->inParametersOfAsyncFunction_ = inParameters;
240}
241
242template <typename Unit>
243void Parser<FullParseHandler, Unit>::setInParametersOfAsyncFunction(
244 bool inParameters) {
245 this->inParametersOfAsyncFunction_ = inParameters;
246 if (SyntaxParser* syntaxParser = getSyntaxParser()) {
247 syntaxParser->setInParametersOfAsyncFunction(inParameters);
248 }
249}
250
251template <class ParseHandler, typename Unit>
252inline void GeneralParser<ParseHandler, Unit>::setInParametersOfAsyncFunction(
253 bool inParameters) {
254 asFinalParser()->setInParametersOfAsyncFunction(inParameters);
255}
256
257template <class ParseHandler>
258FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
259 FunctionNodeType funNode, TaggedParserAtomIndex explicitName,
260 FunctionFlags flags, uint32_t toStringStart, Directives inheritedDirectives,
261 GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
262 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"
, 262); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funNode" ")"
); do { *((volatile int*)__null) = 262; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
263
264 ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
265 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
266 ReportAllocationOverflow(fc_);
267 return nullptr;
268 }
269 if (!compilationState_.appendScriptStencilAndData(fc_)) {
270 return nullptr;
271 }
272
273 bool isInitialStencil = compilationState_.isInitialStencil();
274
275 // This source extent will be further filled in during the remainder of parse.
276 SourceExtent extent;
277 extent.toStringStart = toStringStart;
278
279 FunctionBox* funbox = alloc_.new_<FunctionBox>(
280 fc_, extent, compilationState_, inheritedDirectives, generatorKind,
281 asyncKind, isInitialStencil, explicitName, flags, index);
282 if (!funbox) {
283 ReportOutOfMemory(fc_);
284 return nullptr;
285 }
286
287 handler_.setFunctionBox(funNode, funbox);
288
289 return funbox;
290}
291
292template <class ParseHandler>
293FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
294 FunctionNodeType funNode, const ScriptStencil& cachedScriptData,
295 const ScriptStencilExtra& cachedScriptExtra) {
296 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"
, 296); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funNode" ")"
); do { *((volatile int*)__null) = 296; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
297
298 ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
299 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
300 ReportAllocationOverflow(fc_);
301 return nullptr;
302 }
303 if (!compilationState_.appendScriptStencilAndData(fc_)) {
304 return nullptr;
305 }
306
307 FunctionBox* funbox = alloc_.new_<FunctionBox>(
308 fc_, cachedScriptExtra.extent, compilationState_,
309 Directives(/* strict = */ false), cachedScriptExtra.generatorKind(),
310 cachedScriptExtra.asyncKind(), compilationState_.isInitialStencil(),
311 cachedScriptData.functionAtom, cachedScriptData.functionFlags, index);
312 if (!funbox) {
313 ReportOutOfMemory(fc_);
314 return nullptr;
315 }
316
317 handler_.setFunctionBox(funNode, funbox);
318 funbox->initFromScriptStencilExtra(cachedScriptExtra);
319
320 return funbox;
321}
322
323bool ParserBase::setSourceMapInfo() {
324 // If support for source pragmas have been fully disabled, we can skip
325 // processing of all of these values.
326 if (!options().sourcePragmas()) {
327 return true;
328 }
329
330 // Not all clients initialize ss. Can't update info to an object that isn't
331 // there.
332 if (!ss) {
333 return true;
334 }
335
336 if (anyChars.hasDisplayURL()) {
337 if (!ss->setDisplayURL(fc_, anyChars.displayURL())) {
338 return false;
339 }
340 }
341
342 if (anyChars.hasSourceMapURL()) {
343 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"
, 343); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!ss->hasSourceMapURL()"
")"); do { *((volatile int*)__null) = 343; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
344 if (!ss->setSourceMapURL(fc_, anyChars.sourceMapURL())) {
345 return false;
346 }
347 }
348
349 /*
350 * Source map URLs passed as a compile option (usually via a HTTP source map
351 * header) override any source map urls passed as comment pragmas.
352 */
353 if (options().sourceMapURL()) {
354 // Warn about the replacement, but use the new one.
355 if (ss->hasSourceMapURL()) {
356 if (!warningNoOffset(JSMSG_ALREADY_HAS_PRAGMA, ss->filename(),
357 "//# sourceMappingURL")) {
358 return false;
359 }
360 }
361
362 if (!ss->setSourceMapURL(fc_, options().sourceMapURL())) {
363 return false;
364 }
365 }
366
367 return true;
368}
369
370/*
371 * Parse a top-level JS script.
372 */
373template <class ParseHandler, typename Unit>
374typename ParseHandler::ListNodeResult
375GeneralParser<ParseHandler, Unit>::parse() {
376 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"
, 376); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 376; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
377
378 SourceExtent extent = SourceExtent::makeGlobalExtent(
379 /* len = */ 0, options().lineno,
380 JS::LimitedColumnNumberOneOrigin::fromUnlimited(
381 JS::ColumnNumberOneOrigin(options().column)));
382 Directives directives(options().forceStrictMode());
383 GlobalSharedContext globalsc(this->fc_, ScopeKind::Global, options(),
384 directives, extent);
385 SourceParseContext globalpc(this, &globalsc, /* newDirectives = */ nullptr);
386 if (!globalpc.init()) {
387 return errorResult();
388 }
389
390 ParseContext::VarScope varScope(this);
391 if (!varScope.init(pc_)) {
392 return errorResult();
393 }
394
395 ListNodeType stmtList;
396 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)
;
397
398 TokenKind tt;
399 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
400 return errorResult();
401 }
402 if (tt != TokenKind::Eof) {
403 error(JSMSG_GARBAGE_AFTER_INPUT, "script", TokenKindToDesc(tt));
404 return errorResult();
405 }
406
407 if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
408 return errorResult();
409 }
410
411 return stmtList;
412}
413
414/*
415 * Strict mode forbids introducing new definitions for 'eval', 'arguments',
416 * 'let', 'static', 'yield', or for any strict mode reserved word.
417 */
418bool ParserBase::isValidStrictBinding(TaggedParserAtomIndex name) {
419 TokenKind tt = ReservedWordTokenKind(name);
420 if (tt == TokenKind::Limit) {
421 return name != TaggedParserAtomIndex::WellKnown::eval() &&
422 name != TaggedParserAtomIndex::WellKnown::arguments();
423 }
424 return tt != TokenKind::Let && tt != TokenKind::Static &&
425 tt != TokenKind::Yield && !TokenKindIsStrictReservedWord(tt);
426}
427
428/*
429 * Returns true if all parameter names are valid strict mode binding names and
430 * no duplicate parameter names are present.
431 */
432bool ParserBase::hasValidSimpleStrictParameterNames() {
433 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"
, 434); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
")"); do { *((volatile int*)__null) = 434; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
434 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"
, 434); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
")"); do { *((volatile int*)__null) = 434; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
435
436 if (pc_->functionBox()->hasDuplicateParameters) {
437 return false;
438 }
439
440 for (auto name : pc_->positionalFormalParameterNames()) {
441 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"
, 441); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name" ")"); do
{ *((volatile int*)__null) = 441; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
442 if (!isValidStrictBinding(name)) {
443 return false;
444 }
445 }
446 return true;
447}
448
449template <class ParseHandler, typename Unit>
450void GeneralParser<ParseHandler, Unit>::reportMissingClosing(
451 unsigned errorNumber, unsigned noteNumber, uint32_t openedPos) {
452 auto notes = MakeUnique<JSErrorNotes>();
453 if (!notes) {
454 ReportOutOfMemory(this->fc_);
455 return;
456 }
457
458 uint32_t line;
459 JS::LimitedColumnNumberOneOrigin column;
460 tokenStream.computeLineAndColumn(openedPos, &line, &column);
461
462 const size_t MaxWidth = sizeof("4294967295");
463 char columnNumber[MaxWidth];
464 SprintfLiteral(columnNumber, "%" PRIu32"u", column.oneOriginValue());
465 char lineNumber[MaxWidth];
466 SprintfLiteral(lineNumber, "%" PRIu32"u", line);
467
468 if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
469 JS::ColumnNumberOneOrigin(column), GetErrorMessage,
470 nullptr, noteNumber, lineNumber, columnNumber)) {
471 return;
472 }
473
474 errorWithNotes(std::move(notes), errorNumber);
475}
476
477template <class ParseHandler, typename Unit>
478void GeneralParser<ParseHandler, Unit>::reportRedeclarationHelper(
479 TaggedParserAtomIndex& name, DeclarationKind& prevKind, TokenPos& pos,
480 uint32_t& prevPos, const unsigned& errorNumber,
481 const unsigned& noteErrorNumber) {
482 UniqueChars bytes = this->parserAtoms().toPrintableString(name);
483 if (!bytes) {
484 ReportOutOfMemory(this->fc_);
485 return;
486 }
487
488 if (prevPos == DeclaredNameInfo::npos) {
489 errorAt(pos.begin, errorNumber, DeclarationKindString(prevKind),
490 bytes.get());
491 return;
492 }
493
494 auto notes = MakeUnique<JSErrorNotes>();
495 if (!notes) {
496 ReportOutOfMemory(this->fc_);
497 return;
498 }
499
500 uint32_t line;
501 JS::LimitedColumnNumberOneOrigin column;
502 tokenStream.computeLineAndColumn(prevPos, &line, &column);
503
504 const size_t MaxWidth = sizeof("4294967295");
505 char columnNumber[MaxWidth];
506 SprintfLiteral(columnNumber, "%" PRIu32"u", column.oneOriginValue());
507 char lineNumber[MaxWidth];
508 SprintfLiteral(lineNumber, "%" PRIu32"u", line);
509
510 if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
511 JS::ColumnNumberOneOrigin(column), GetErrorMessage,
512 nullptr, noteErrorNumber, lineNumber,
513 columnNumber)) {
514 return;
515 }
516
517 errorWithNotesAt(std::move(notes), pos.begin, errorNumber,
518 DeclarationKindString(prevKind), bytes.get());
519}
520
521template <class ParseHandler, typename Unit>
522void GeneralParser<ParseHandler, Unit>::reportRedeclaration(
523 TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
524 uint32_t prevPos) {
525 reportRedeclarationHelper(name, prevKind, pos, prevPos, JSMSG_REDECLARED_VAR,
526 JSMSG_PREV_DECLARATION);
527}
528
529template <class ParseHandler, typename Unit>
530void GeneralParser<ParseHandler, Unit>::reportMismatchedPlacement(
531 TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
532 uint32_t prevPos) {
533 reportRedeclarationHelper(name, prevKind, pos, prevPos,
534 JSMSG_MISMATCHED_PLACEMENT, JSMSG_PREV_DECLARATION);
535}
536
537// notePositionalFormalParameter is called for both the arguments of a regular
538// function definition and the arguments specified by the Function
539// constructor.
540//
541// The 'disallowDuplicateParams' bool indicates whether the use of another
542// feature (destructuring or default arguments) disables duplicate arguments.
543// (ECMA-262 requires us to support duplicate parameter names, but, for newer
544// features, we consider the code to have "opted in" to higher standards and
545// forbid duplicates.)
546template <class ParseHandler, typename Unit>
547bool GeneralParser<ParseHandler, Unit>::notePositionalFormalParameter(
548 FunctionNodeType funNode, TaggedParserAtomIndex name, uint32_t beginPos,
549 bool disallowDuplicateParams, bool* duplicatedParam) {
550 if (AddDeclaredNamePtr p =
551 pc_->functionScope().lookupDeclaredNameForAdd(name)) {
552 if (disallowDuplicateParams) {
553 error(JSMSG_BAD_DUP_ARGS);
554 return false;
555 }
556
557 // Strict-mode disallows duplicate args. We may not know whether we are
558 // in strict mode or not (since the function body hasn't been parsed).
559 // In such cases, report will queue up the potential error and return
560 // 'true'.
561 if (pc_->sc()->strict()) {
562 UniqueChars bytes = this->parserAtoms().toPrintableString(name);
563 if (!bytes) {
564 ReportOutOfMemory(this->fc_);
565 return false;
566 }
567 if (!strictModeError(JSMSG_DUPLICATE_FORMAL, bytes.get())) {
568 return false;
569 }
570 }
571
572 *duplicatedParam = true;
573 } else {
574 DeclarationKind kind = DeclarationKind::PositionalFormalParameter;
575 if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, beginPos)) {
576 return false;
577 }
578 }
579
580 if (!pc_->positionalFormalParameterNames().append(
581 TrivialTaggedParserAtomIndex::from(name))) {
582 ReportOutOfMemory(this->fc_);
583 return false;
584 }
585
586 NameNodeType paramNode;
587 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)
;
588
589 handler_.addFunctionFormalParameter(funNode, paramNode);
590 return true;
591}
592
593template <class ParseHandler>
594bool PerHandlerParser<ParseHandler>::noteDestructuredPositionalFormalParameter(
595 FunctionNodeType funNode, Node destruct) {
596 // Append an empty name to the positional formals vector to keep track of
597 // argument slots when making FunctionScope::ParserData.
598 if (!pc_->positionalFormalParameterNames().append(
599 TrivialTaggedParserAtomIndex::null())) {
600 ReportOutOfMemory(fc_);
601 return false;
602 }
603
604 handler_.addFunctionFormalParameter(funNode, destruct);
605 return true;
606}
607
608template <class ParseHandler, typename Unit>
609bool GeneralParser<ParseHandler, Unit>::noteDeclaredName(
610 TaggedParserAtomIndex name, DeclarationKind kind, TokenPos pos,
611 ClosedOver isClosedOver) {
612 // The asm.js validator does all its own symbol-table management so, as an
613 // optimization, avoid doing any work here.
614 if (pc_->useAsmOrInsideUseAsm()) {
615 return true;
616 }
617
618 switch (kind) {
619 case DeclarationKind::Var:
620 case DeclarationKind::BodyLevelFunction: {
621 Maybe<DeclarationKind> redeclaredKind;
622 uint32_t prevPos;
623 if (!pc_->tryDeclareVar(name, this, kind, pos.begin, &redeclaredKind,
624 &prevPos)) {
625 return false;
626 }
627
628 if (redeclaredKind) {
629 reportRedeclaration(name, *redeclaredKind, pos, prevPos);
630 return false;
631 }
632
633 break;
634 }
635
636 case DeclarationKind::ModuleBodyLevelFunction: {
637 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"
, 637); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->atModuleLevel()"
")"); do { *((volatile int*)__null) = 637; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
638
639 AddDeclaredNamePtr p = pc_->varScope().lookupDeclaredNameForAdd(name);
640 if (p) {
641 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
642 return false;
643 }
644
645 if (!pc_->varScope().addDeclaredName(pc_, p, name, kind, pos.begin,
646 isClosedOver)) {
647 return false;
648 }
649
650 // Body-level functions in modules are always closed over.
651 pc_->varScope().lookupDeclaredName(name)->value()->setClosedOver();
652
653 break;
654 }
655
656 case DeclarationKind::FormalParameter: {
657 // It is an early error if any non-positional formal parameter name
658 // (e.g., destructuring formal parameter) is duplicated.
659
660 AddDeclaredNamePtr p =
661 pc_->functionScope().lookupDeclaredNameForAdd(name);
662 if (p) {
663 error(JSMSG_BAD_DUP_ARGS);
664 return false;
665 }
666
667 if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, pos.begin,
668 isClosedOver)) {
669 return false;
670 }
671
672 break;
673 }
674
675 case DeclarationKind::LexicalFunction:
676 case DeclarationKind::PrivateName:
677 case DeclarationKind::Synthetic:
678 case DeclarationKind::PrivateMethod: {
679 ParseContext::Scope* scope = pc_->innermostScope();
680 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
681 if (p) {
682 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
683 return false;
684 }
685
686 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
687 isClosedOver)) {
688 return false;
689 }
690
691 break;
692 }
693
694 case DeclarationKind::SloppyLexicalFunction: {
695 // Functions in block have complex allowances in sloppy mode for being
696 // labelled that other lexical declarations do not have. Those checks
697 // are done in functionStmt.
698
699 ParseContext::Scope* scope = pc_->innermostScope();
700 if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
701 // It is usually an early error if there is another declaration
702 // with the same name in the same scope.
703 //
704 // Sloppy lexical functions may redeclare other sloppy lexical
705 // functions for web compatibility reasons.
706 if (p->value()->kind() != DeclarationKind::SloppyLexicalFunction) {
707 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
708 return false;
709 }
710 } else {
711 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
712 isClosedOver)) {
713 return false;
714 }
715 }
716
717 break;
718 }
719
720 case DeclarationKind::Let:
721 case DeclarationKind::Const:
722#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
723 case DeclarationKind::Using:
724 case DeclarationKind::AwaitUsing:
725#endif
726 case DeclarationKind::Class:
727 // The BoundNames of LexicalDeclaration and ForDeclaration must not
728 // contain 'let'. (CatchParameter is the only lexical binding form
729 // without this restriction.)
730 if (name == TaggedParserAtomIndex::WellKnown::let()) {
731 errorAt(pos.begin, JSMSG_LEXICAL_DECL_DEFINES_LET);
732 return false;
733 }
734
735 // For body-level lexically declared names in a function, it is an
736 // early error if there is a formal parameter of the same name. This
737 // needs a special check if there is an extra var scope due to
738 // parameter expressions.
739 if (pc_->isFunctionExtraBodyVarScopeInnermost()) {
740 DeclaredNamePtr p = pc_->functionScope().lookupDeclaredName(name);
741 if (p && DeclarationKindIsParameter(p->value()->kind())) {
742 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
743 return false;
744 }
745 }
746
747 [[fallthrough]];
748
749 case DeclarationKind::Import:
750 // Module code is always strict, so 'let' is always a keyword and never a
751 // name.
752 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"
, 752); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name != TaggedParserAtomIndex::WellKnown::let()"
")"); do { *((volatile int*)__null) = 752; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
753 [[fallthrough]];
754
755 case DeclarationKind::SimpleCatchParameter:
756 case DeclarationKind::CatchParameter: {
757 ParseContext::Scope* scope = pc_->innermostScope();
758
759 // It is an early error if there is another declaration with the same
760 // name in the same scope.
761 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
762 if (p) {
763 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
764 return false;
765 }
766
767 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
768 isClosedOver)) {
769 return false;
770 }
771
772 break;
773 }
774
775 case DeclarationKind::CoverArrowParameter:
776 // CoverArrowParameter is only used as a placeholder declaration kind.
777 break;
778
779 case DeclarationKind::PositionalFormalParameter:
780 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"
, 782); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 782; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
781 "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"
, 782); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 782; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
782 "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"
, 782); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 782; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
;
783 break;
784
785 case DeclarationKind::VarForAnnexBLexicalFunction:
786 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"
, 789); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 789; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
787 "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"
, 789); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 789; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
788 "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"
, 789); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 789; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
789 "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"
, 789); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 789; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
790 break;
791 }
792
793 return true;
794}
795
796template <class ParseHandler, typename Unit>
797bool GeneralParser<ParseHandler, Unit>::noteDeclaredPrivateName(
798 Node nameNode, TaggedParserAtomIndex name, PropertyType propType,
799 FieldPlacement placement, TokenPos pos) {
800 ParseContext::Scope* scope = pc_->innermostScope();
801 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
802
803 DeclarationKind declKind = DeclarationKind::PrivateName;
804
805 // Our strategy for enabling debugger functionality is to mark names as closed
806 // over, even if they don't necessarily need to be, to ensure that they are
807 // included in the environment object. This allows us to easily look them up
808 // by name when needed, even if there is no corresponding property on an
809 // object, as is the case with getter, setters and private methods.
810 ClosedOver closedOver = ClosedOver::Yes;
811 PrivateNameKind kind;
812 switch (propType) {
813 case PropertyType::Field:
814 kind = PrivateNameKind::Field;
815 closedOver = ClosedOver::No;
816 break;
817 case PropertyType::FieldWithAccessor:
818 // In this case, we create a new private field for the underlying storage,
819 // and use the current name for the getter and setter.
820 kind = PrivateNameKind::GetterSetter;
821 break;
822 case PropertyType::Method:
823 case PropertyType::GeneratorMethod:
824 case PropertyType::AsyncMethod:
825 case PropertyType::AsyncGeneratorMethod:
826 if (placement == FieldPlacement::Instance) {
827 // Optimized private method. Non-optimized paths still get
828 // DeclarationKind::Synthetic.
829 declKind = DeclarationKind::PrivateMethod;
830 }
831 kind = PrivateNameKind::Method;
832 break;
833 case PropertyType::Getter:
834 kind = PrivateNameKind::Getter;
835 break;
836 case PropertyType::Setter:
837 kind = PrivateNameKind::Setter;
838 break;
839 default:
840 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"
, 840); AnnotateMozCrashReason("MOZ_CRASH(" "Invalid Property Type for noteDeclarePrivateName"
")"); do { *((volatile int*)__null) = 840; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
841 }
842
843 if (p) {
844 PrivateNameKind prevKind = p->value()->privateNameKind();
845 if ((prevKind == PrivateNameKind::Getter &&
846 kind == PrivateNameKind::Setter) ||
847 (prevKind == PrivateNameKind::Setter &&
848 kind == PrivateNameKind::Getter)) {
849 // Private methods demands that
850 //
851 // class A {
852 // static set #x(_) {}
853 // get #x() { }
854 // }
855 //
856 // Report a SyntaxError.
857 if (placement == p->value()->placement()) {
858 p->value()->setPrivateNameKind(PrivateNameKind::GetterSetter);
859 handler_.setPrivateNameKind(nameNode, PrivateNameKind::GetterSetter);
860 return true;
861 }
862 }
863
864 reportMismatchedPlacement(name, p->value()->kind(), pos, p->value()->pos());
865 return false;
866 }
867
868 if (!scope->addDeclaredName(pc_, p, name, declKind, pos.begin, closedOver)) {
869 return false;
870 }
871
872 DeclaredNamePtr declared = scope->lookupDeclaredName(name);
873 declared->value()->setPrivateNameKind(kind);
874 declared->value()->setFieldPlacement(placement);
875 handler_.setPrivateNameKind(nameNode, kind);
876
877 return true;
878}
879
880bool ParserBase::noteUsedNameInternal(TaggedParserAtomIndex name,
881 NameVisibility visibility,
882 mozilla::Maybe<TokenPos> tokenPosition) {
883 // The asm.js validator does all its own symbol-table management so, as an
884 // optimization, avoid doing any work here.
885 if (pc_->useAsmOrInsideUseAsm()) {
886 return true;
887 }
888
889 // Global bindings are properties and not actual bindings; we don't need
890 // to know if they are closed over. So no need to track used name at the
891 // global scope. It is not incorrect to track them, this is an
892 // optimization.
893 //
894 // Exceptions:
895 // (a) Track private name references, as the used names tracker is used to
896 // provide early errors for undeclared private name references
897 // (b) If the script has extra bindings, track all references to detect
898 // references to extra bindings
899 ParseContext::Scope* scope = pc_->innermostScope();
900 if (pc_->sc()->isGlobalContext() && scope == &pc_->varScope() &&
901 visibility == NameVisibility::Public &&
902 !this->compilationState_.input.hasExtraBindings()) {
903 return true;
904 }
905
906 return usedNames_.noteUse(fc_, name, visibility, pc_->scriptId(), scope->id(),
907 tokenPosition);
908}
909
910template <class ParseHandler>
911bool PerHandlerParser<ParseHandler>::
912 propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope) {
913 // Now that we have all the declared names in the scope, check which
914 // functions should exhibit Annex B semantics.
915 if (!scope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
916 return false;
917 }
918
919 if (handler_.reuseClosedOverBindings()) {
920 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"
, 920); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isOutermostOfCurrentCompile()"
")"); do { *((volatile int*)__null) = 920; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
921
922 // Closed over bindings for all scopes are stored in a contiguous array, in
923 // the same order as the order in which scopes are visited, and seprated by
924 // TaggedParserAtomIndex::null().
925 uint32_t slotCount = scope.declaredCount();
926 while (auto parserAtom = handler_.nextLazyClosedOverBinding()) {
927 scope.lookupDeclaredName(parserAtom)->value()->setClosedOver();
928 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"
, 928); AnnotateMozCrashReason("MOZ_ASSERT" "(" "slotCount > 0"
")"); do { *((volatile int*)__null) = 928; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
929 slotCount--;
930 }
931
932 if (pc_->isGeneratorOrAsync()) {
933 scope.setOwnStackSlotCount(slotCount);
934 }
935 return true;
936 }
937
938 constexpr bool isSyntaxParser =
939 std::is_same_v<ParseHandler, SyntaxParseHandler>;
940 uint32_t scriptId = pc_->scriptId();
941 uint32_t scopeId = scope.id();
942
943 uint32_t slotCount = 0;
944 for (BindingIter bi = scope.bindings(pc_); bi; bi++) {
945 bool closedOver = false;
946 if (UsedNamePtr p = usedNames_.lookup(bi.name())) {
947 p->value().noteBoundInScope(scriptId, scopeId, &closedOver);
948 if (closedOver) {
949 bi.setClosedOver();
950
951 if constexpr (isSyntaxParser) {
952 if (!pc_->closedOverBindingsForLazy().append(
953 TrivialTaggedParserAtomIndex::from(bi.name()))) {
954 ReportOutOfMemory(fc_);
955 return false;
956 }
957 }
958 }
959 }
960
961 if constexpr (!isSyntaxParser) {
962 if (!closedOver) {
963 slotCount++;
964 }
965 }
966 }
967 if constexpr (!isSyntaxParser) {
968 if (pc_->isGeneratorOrAsync()) {
969 scope.setOwnStackSlotCount(slotCount);
970 }
971 }
972
973 // Append a nullptr to denote end-of-scope.
974 if constexpr (isSyntaxParser) {
975 if (!pc_->closedOverBindingsForLazy().append(
976 TrivialTaggedParserAtomIndex::null())) {
977 ReportOutOfMemory(fc_);
978 return false;
979 }
980 }
981
982 return true;
983}
984
985template <typename Unit>
986bool Parser<FullParseHandler, Unit>::checkStatementsEOF() {
987 // This is designed to be paired with parsing a statement list at the top
988 // level.
989 //
990 // The statementList() call breaks on TokenKind::RightCurly, so make sure
991 // we've reached EOF here.
992 TokenKind tt;
993 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
994 return false;
995 }
996 if (tt != TokenKind::Eof) {
997 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
998 return false;
999 }
1000 return true;
1001}
1002
1003template <typename ScopeT>
1004typename ScopeT::ParserData* NewEmptyBindingData(FrontendContext* fc,
1005 LifoAlloc& alloc,
1006 uint32_t numBindings) {
1007 using Data = typename ScopeT::ParserData;
1008 size_t allocSize = SizeOfScopeData<Data>(numBindings);
1009 auto* bindings = alloc.newWithSize<Data>(allocSize, numBindings);
1010 if (!bindings) {
1011 ReportOutOfMemory(fc);
1012 }
1013 return bindings;
1014}
1015
1016GlobalScope::ParserData* NewEmptyGlobalScopeData(FrontendContext* fc,
1017 LifoAlloc& alloc,
1018 uint32_t numBindings) {
1019 return NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
1020}
1021
1022LexicalScope::ParserData* NewEmptyLexicalScopeData(FrontendContext* fc,
1023 LifoAlloc& alloc,
1024 uint32_t numBindings) {
1025 return NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
1026}
1027
1028FunctionScope::ParserData* NewEmptyFunctionScopeData(FrontendContext* fc,
1029 LifoAlloc& alloc,
1030 uint32_t numBindings) {
1031 return NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
1032}
1033
1034namespace detail {
1035
1036template <class SlotInfo>
1037static MOZ_ALWAYS_INLINEinline ParserBindingName* InitializeIndexedBindings(
1038 SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor) {
1039 return cursor;
1040}
1041
1042template <class SlotInfo, typename UnsignedInteger, typename... Step>
1043static MOZ_ALWAYS_INLINEinline ParserBindingName* InitializeIndexedBindings(
1044 SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor,
1045 UnsignedInteger SlotInfo::* field, const ParserBindingNameVector& bindings,
1046 Step&&... step) {
1047 slotInfo.*field =
1048 AssertedCast<UnsignedInteger>(PointerRangeSize(start, cursor));
1049
1050 ParserBindingName* newCursor =
1051 std::uninitialized_copy(bindings.begin(), bindings.end(), cursor);
1052
1053 return InitializeIndexedBindings(slotInfo, start, newCursor,
1054 std::forward<Step>(step)...);
1055}
1056
1057} // namespace detail
1058
1059// Initialize the trailing name bindings of |data|, then set |data->length| to
1060// the count of bindings added (which must equal |count|).
1061//
1062// First, |firstBindings| are added to the trailing names. Then any
1063// "steps" present are performed first to last. Each step is 1) a pointer to a
1064// member of |data| to be set to the current number of bindings added, and 2) a
1065// vector of |ParserBindingName|s to then copy into |data->trailingNames|.
1066// (Thus each |data| member field indicates where the corresponding vector's
1067// names start.)
1068template <class Data, typename... Step>
1069static MOZ_ALWAYS_INLINEinline void InitializeBindingData(
1070 Data* data, uint32_t count, const ParserBindingNameVector& firstBindings,
1071 Step&&... step) {
1072 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"
, 1072); AnnotateMozCrashReason("MOZ_ASSERT" "(" "data->length == 0"
") (" "data shouldn't be filled yet" ")"); do { *((volatile int
*)__null) = 1072; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1073
1074 ParserBindingName* start = GetScopeDataTrailingNamesPointer(data);
1075 ParserBindingName* cursor = std::uninitialized_copy(
1076 firstBindings.begin(), firstBindings.end(), start);
1077
1078#ifdef DEBUG1
1079 ParserBindingName* end =
1080#endif
1081 detail::InitializeIndexedBindings(data->slotInfo, start, cursor,
1082 std::forward<Step>(step)...);
1083
1084 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"
, 1084); AnnotateMozCrashReason("MOZ_ASSERT" "(" "PointerRangeSize(start, end) == count"
")"); do { *((volatile int*)__null) = 1084; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1085 data->length = count;
1086}
1087
1088static Maybe<GlobalScope::ParserData*> NewGlobalScopeData(
1089 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1090 ParseContext* pc) {
1091 ParserBindingNameVector vars(fc);
1092 ParserBindingNameVector lets(fc);
1093 ParserBindingNameVector consts(fc);
1094
1095 bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
1096 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1097 bool closedOver = allBindingsClosedOver || bi.closedOver();
1098
1099 switch (bi.kind()) {
1100 case BindingKind::Var: {
1101 bool isTopLevelFunction =
1102 bi.declarationKind() == DeclarationKind::BodyLevelFunction;
1103
1104 ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
1105 if (!vars.append(binding)) {
1106 return Nothing();
1107 }
1108 break;
1109 }
1110 case BindingKind::Let: {
1111 ParserBindingName binding(bi.name(), closedOver);
1112 if (!lets.append(binding)) {
1113 return Nothing();
1114 }
1115 break;
1116 }
1117 case BindingKind::Const: {
1118 ParserBindingName binding(bi.name(), closedOver);
1119 if (!consts.append(binding)) {
1120 return Nothing();
1121 }
1122 break;
1123 }
1124 default:
1125 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"
, 1125); AnnotateMozCrashReason("MOZ_CRASH(" "Bad global scope BindingKind"
")"); do { *((volatile int*)__null) = 1125; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1126 }
1127 }
1128
1129 GlobalScope::ParserData* bindings = nullptr;
1130 uint32_t numBindings = vars.length() + lets.length() + consts.length();
1131
1132 if (numBindings > 0) {
1133 bindings = NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
1134 if (!bindings) {
1135 return Nothing();
1136 }
1137
1138 // The ordering here is important. See comments in GlobalScope.
1139 InitializeBindingData(bindings, numBindings, vars,
1140 &ParserGlobalScopeSlotInfo::letStart, lets,
1141 &ParserGlobalScopeSlotInfo::constStart, consts);
1142 }
1143
1144 return Some(bindings);
1145}
1146
1147Maybe<GlobalScope::ParserData*> ParserBase::newGlobalScopeData(
1148 ParseContext::Scope& scope) {
1149 return NewGlobalScopeData(fc_, scope, stencilAlloc(), pc_);
1150}
1151
1152static Maybe<ModuleScope::ParserData*> NewModuleScopeData(
1153 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1154 ParseContext* pc) {
1155 ParserBindingNameVector imports(fc);
1156 ParserBindingNameVector vars(fc);
1157 ParserBindingNameVector lets(fc);
1158 ParserBindingNameVector consts(fc);
1159#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1160 ParserBindingNameVector usings(fc);
1161#endif
1162
1163 bool allBindingsClosedOver =
1164 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1165
1166 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1167 // Imports are indirect bindings and must not be given known slots.
1168 ParserBindingName binding(bi.name(),
1169 (allBindingsClosedOver || bi.closedOver()) &&
1170 bi.kind() != BindingKind::Import);
1171 switch (bi.kind()) {
1172 case BindingKind::Import:
1173 if (!imports.append(binding)) {
1174 return Nothing();
1175 }
1176 break;
1177 case BindingKind::Var:
1178 if (!vars.append(binding)) {
1179 return Nothing();
1180 }
1181 break;
1182 case BindingKind::Let:
1183 if (!lets.append(binding)) {
1184 return Nothing();
1185 }
1186 break;
1187 case BindingKind::Const:
1188 if (!consts.append(binding)) {
1189 return Nothing();
1190 }
1191 break;
1192#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1193 case BindingKind::Using:
1194 if (!usings.append(binding)) {
1195 return Nothing();
1196 }
1197 break;
1198#endif
1199 default:
1200 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"
, 1200); AnnotateMozCrashReason("MOZ_CRASH(" "Bad module scope BindingKind"
")"); do { *((volatile int*)__null) = 1200; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1201 }
1202 }
1203
1204 ModuleScope::ParserData* bindings = nullptr;
1205 uint32_t numBindings = imports.length() + vars.length() + lets.length() +
1206 consts.length()
1207#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1208 + usings.length()
1209#endif
1210 ;
1211
1212 if (numBindings > 0) {
1213 bindings = NewEmptyBindingData<ModuleScope>(fc, alloc, numBindings);
1214 if (!bindings) {
1215 return Nothing();
1216 }
1217
1218 // The ordering here is important. See comments in ModuleScope.
1219 InitializeBindingData(bindings, numBindings, imports,
1220 &ParserModuleScopeSlotInfo::varStart, vars,
1221 &ParserModuleScopeSlotInfo::letStart, lets,
1222 &ParserModuleScopeSlotInfo::constStart, consts
1223#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1224 ,
1225 &ParserModuleScopeSlotInfo::usingStart, usings
1226#endif
1227 );
1228 }
1229
1230 return Some(bindings);
1231}
1232
1233Maybe<ModuleScope::ParserData*> ParserBase::newModuleScopeData(
1234 ParseContext::Scope& scope) {
1235 return NewModuleScopeData(fc_, scope, stencilAlloc(), pc_);
1236}
1237
1238static Maybe<EvalScope::ParserData*> NewEvalScopeData(
1239 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1240 ParseContext* pc) {
1241 ParserBindingNameVector vars(fc);
1242
1243 // Treat all bindings as closed over in non-strict eval.
1244 bool allBindingsClosedOver =
1245 !pc->sc()->strict() || pc->sc()->allBindingsClosedOver();
1246 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1247 // Eval scopes only contain 'var' bindings.
1248 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"
, 1248); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Var"
")"); do { *((volatile int*)__null) = 1248; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1249 bool isTopLevelFunction =
1250 bi.declarationKind() == DeclarationKind::BodyLevelFunction;
1251 bool closedOver = allBindingsClosedOver || bi.closedOver();
1252
1253 ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
1254 if (!vars.append(binding)) {
1255 return Nothing();
1256 }
1257 }
1258
1259 EvalScope::ParserData* bindings = nullptr;
1260 uint32_t numBindings = vars.length();
1261
1262 if (numBindings > 0) {
1263 bindings = NewEmptyBindingData<EvalScope>(fc, alloc, numBindings);
1264 if (!bindings) {
1265 return Nothing();
1266 }
1267
1268 InitializeBindingData(bindings, numBindings, vars);
1269 }
1270
1271 return Some(bindings);
1272}
1273
1274Maybe<EvalScope::ParserData*> ParserBase::newEvalScopeData(
1275 ParseContext::Scope& scope) {
1276 return NewEvalScopeData(fc_, scope, stencilAlloc(), pc_);
1277}
1278
1279static Maybe<FunctionScope::ParserData*> NewFunctionScopeData(
1280 FrontendContext* fc, ParseContext::Scope& scope, bool hasParameterExprs,
1281 LifoAlloc& alloc, ParseContext* pc) {
1282 ParserBindingNameVector positionalFormals(fc);
1283 ParserBindingNameVector formals(fc);
1284 ParserBindingNameVector vars(fc);
1285
1286 bool allBindingsClosedOver =
1287 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1288 bool argumentBindingsClosedOver =
1289 allBindingsClosedOver || pc->isGeneratorOrAsync();
1290 bool hasDuplicateParams = pc->functionBox()->hasDuplicateParameters;
1291
1292 // Positional parameter names must be added in order of appearance as they are
1293 // referenced using argument slots.
1294 for (size_t i = 0; i < pc->positionalFormalParameterNames().length(); i++) {
1295 TaggedParserAtomIndex name = pc->positionalFormalParameterNames()[i];
1296
1297 ParserBindingName bindName;
1298 if (name) {
1299 DeclaredNamePtr p = scope.lookupDeclaredName(name);
1300
1301 // Do not consider any positional formal parameters closed over if
1302 // there are parameter defaults. It is the binding in the defaults
1303 // scope that is closed over instead.
1304 bool closedOver =
1305 argumentBindingsClosedOver || (p && p->value()->closedOver());
1306
1307 // If the parameter name has duplicates, only the final parameter
1308 // name should be on the environment, as otherwise the environment
1309 // object would have multiple, same-named properties.
1310 if (hasDuplicateParams) {
1311 for (size_t j = pc->positionalFormalParameterNames().length() - 1;
1312 j > i; j--) {
1313 if (TaggedParserAtomIndex(pc->positionalFormalParameterNames()[j]) ==
1314 name) {
1315 closedOver = false;
1316 break;
1317 }
1318 }
1319 }
1320
1321 bindName = ParserBindingName(name, closedOver);
1322 }
1323
1324 if (!positionalFormals.append(bindName)) {
1325 return Nothing();
1326 }
1327 }
1328
1329 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1330 ParserBindingName binding(bi.name(),
1331 allBindingsClosedOver || bi.closedOver());
1332 switch (bi.kind()) {
1333 case BindingKind::FormalParameter:
1334 // Positional parameter names are already handled above.
1335 if (bi.declarationKind() == DeclarationKind::FormalParameter) {
1336 if (!formals.append(binding)) {
1337 return Nothing();
1338 }
1339 }
1340 break;
1341 case BindingKind::Var:
1342 // The only vars in the function scope when there are parameter
1343 // exprs, which induces a separate var environment, should be the
1344 // special bindings.
1345 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"
, 1346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "FunctionScope::isSpecialName(bi.name())"
")"); do { *((volatile int*)__null) = 1346; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1346 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"
, 1346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "FunctionScope::isSpecialName(bi.name())"
")"); do { *((volatile int*)__null) = 1346; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1347 if (!vars.append(binding)) {
1348 return Nothing();
1349 }
1350 break;
1351 case BindingKind::Let:
1352 case BindingKind::Const:
1353#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1354 case BindingKind::Using:
1355#endif
1356 break;
1357 default:
1358 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"
, 1358); AnnotateMozCrashReason("MOZ_CRASH(" "bad function scope BindingKind"
")"); do { *((volatile int*)__null) = 1358; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1359 break;
1360 }
1361 }
1362
1363 FunctionScope::ParserData* bindings = nullptr;
1364 uint32_t numBindings =
1365 positionalFormals.length() + formals.length() + vars.length();
1366
1367 if (numBindings > 0) {
1368 bindings = NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
1369 if (!bindings) {
1370 return Nothing();
1371 }
1372
1373 // The ordering here is important. See comments in FunctionScope.
1374 InitializeBindingData(
1375 bindings, numBindings, positionalFormals,
1376 &ParserFunctionScopeSlotInfo::nonPositionalFormalStart, formals,
1377 &ParserFunctionScopeSlotInfo::varStart, vars);
1378 }
1379
1380 return Some(bindings);
1381}
1382
1383// Compute if `NewFunctionScopeData` would return any binding list with any
1384// entry marked as closed-over. This is done without the need to allocate the
1385// binding list. If true, an EnvironmentObject will be needed at runtime.
1386bool FunctionScopeHasClosedOverBindings(ParseContext* pc) {
1387 bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver() ||
1388 pc->functionScope().tooBigToOptimize();
1389
1390 for (BindingIter bi = pc->functionScope().bindings(pc); bi; bi++) {
1391 switch (bi.kind()) {
1392 case BindingKind::FormalParameter:
1393 case BindingKind::Var:
1394 if (allBindingsClosedOver || bi.closedOver()) {
1395 return true;
1396 }
1397 break;
1398
1399 default:
1400 break;
1401 }
1402 }
1403
1404 return false;
1405}
1406
1407Maybe<FunctionScope::ParserData*> ParserBase::newFunctionScopeData(
1408 ParseContext::Scope& scope, bool hasParameterExprs) {
1409 return NewFunctionScopeData(fc_, scope, hasParameterExprs, stencilAlloc(),
1410 pc_);
1411}
1412
1413VarScope::ParserData* NewEmptyVarScopeData(FrontendContext* fc,
1414 LifoAlloc& alloc,
1415 uint32_t numBindings) {
1416 return NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
1417}
1418
1419static Maybe<VarScope::ParserData*> NewVarScopeData(FrontendContext* fc,
1420 ParseContext::Scope& scope,
1421 LifoAlloc& alloc,
1422 ParseContext* pc) {
1423 ParserBindingNameVector vars(fc);
1424
1425 bool allBindingsClosedOver =
1426 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1427
1428 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1429 if (bi.kind() == BindingKind::Var) {
1430 ParserBindingName binding(bi.name(),
1431 allBindingsClosedOver || bi.closedOver());
1432 if (!vars.append(binding)) {
1433 return Nothing();
1434 }
1435 } else {
1436 MOZ_ASSERT(bi.kind() == BindingKind::Let ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1437 bi.kind() == BindingKind::Constdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1438#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENTdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1439 || bi.kind() == BindingKind::Usingdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1440#endifdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1441 ,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1442 "bad var scope BindingKind")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1443 }
1444 }
1445
1446 VarScope::ParserData* bindings = nullptr;
1447 uint32_t numBindings = vars.length();
1448
1449 if (numBindings > 0) {
1450 bindings = NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
1451 if (!bindings) {
1452 return Nothing();
1453 }
1454
1455 InitializeBindingData(bindings, numBindings, vars);
1456 }
1457
1458 return Some(bindings);
1459}
1460
1461// Compute if `NewVarScopeData` would return any binding list. This is done
1462// without allocate the binding list.
1463static bool VarScopeHasBindings(ParseContext* pc) {
1464 for (BindingIter bi = pc->varScope().bindings(pc); bi; bi++) {
1465 if (bi.kind() == BindingKind::Var) {
1466 return true;
1467 }
1468 }
1469
1470 return false;
1471}
1472
1473Maybe<VarScope::ParserData*> ParserBase::newVarScopeData(
1474 ParseContext::Scope& scope) {
1475 return NewVarScopeData(fc_, scope, stencilAlloc(), pc_);
1476}
1477
1478static Maybe<LexicalScope::ParserData*> NewLexicalScopeData(
1479 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1480 ParseContext* pc) {
1481 ParserBindingNameVector lets(fc);
1482 ParserBindingNameVector consts(fc);
1483#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1484 ParserBindingNameVector usings(fc);
1485#endif
1486
1487 bool allBindingsClosedOver =
1488 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1489
1490 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1491 ParserBindingName binding(bi.name(),
1492 allBindingsClosedOver || bi.closedOver());
1493 switch (bi.kind()) {
1494 case BindingKind::Let:
1495 if (!lets.append(binding)) {
1496 return Nothing();
1497 }
1498 break;
1499 case BindingKind::Const:
1500 if (!consts.append(binding)) {
1501 return Nothing();
1502 }
1503 break;
1504#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1505 case BindingKind::Using:
1506 if (!usings.append(binding)) {
1507 return Nothing();
1508 }
1509 break;
1510#endif
1511 case BindingKind::Var:
1512 case BindingKind::FormalParameter:
1513 break;
1514 default:
1515 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"
, 1515); AnnotateMozCrashReason("MOZ_CRASH(" "Bad lexical scope BindingKind"
")"); do { *((volatile int*)__null) = 1515; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1516 break;
1517 }
1518 }
1519
1520 LexicalScope::ParserData* bindings = nullptr;
1521 uint32_t numBindings = lets.length() + consts.length()
1522#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1523 + usings.length()
1524#endif
1525 ;
1526
1527 if (numBindings > 0) {
1528 bindings = NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
1529 if (!bindings) {
1530 return Nothing();
1531 }
1532
1533 // The ordering here is important. See comments in LexicalScope.
1534 InitializeBindingData(bindings, numBindings, lets,
1535 &ParserLexicalScopeSlotInfo::constStart, consts
1536#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1537 ,
1538 &ParserLexicalScopeSlotInfo::usingStart, usings
1539#endif
1540 );
1541 }
1542
1543 return Some(bindings);
1544}
1545
1546// Compute if `NewLexicalScopeData` would return any binding list with any entry
1547// marked as closed-over. This is done without the need to allocate the binding
1548// list. If true, an EnvironmentObject will be needed at runtime.
1549bool LexicalScopeHasClosedOverBindings(ParseContext* pc,
1550 ParseContext::Scope& scope) {
1551 bool allBindingsClosedOver =
1552 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1553
1554 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1555 switch (bi.kind()) {
1556 case BindingKind::Let:
1557 case BindingKind::Const:
1558 if (allBindingsClosedOver || bi.closedOver()) {
1559 return true;
1560 }
1561 break;
1562
1563 default:
1564 break;
1565 }
1566 }
1567
1568 return false;
1569}
1570
1571Maybe<LexicalScope::ParserData*> ParserBase::newLexicalScopeData(
1572 ParseContext::Scope& scope) {
1573 return NewLexicalScopeData(fc_, scope, stencilAlloc(), pc_);
1574}
1575
1576static Maybe<ClassBodyScope::ParserData*> NewClassBodyScopeData(
1577 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1578 ParseContext* pc) {
1579 ParserBindingNameVector privateBrand(fc);
1580 ParserBindingNameVector synthetics(fc);
1581 ParserBindingNameVector privateMethods(fc);
1582
1583 bool allBindingsClosedOver =
1584 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1585
1586 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1587 ParserBindingName binding(bi.name(),
1588 allBindingsClosedOver || bi.closedOver());
1589 switch (bi.kind()) {
1590 case BindingKind::Synthetic:
1591 if (bi.name() ==
1592 TaggedParserAtomIndex::WellKnown::dot_privateBrand_()) {
1593 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"
, 1593); AnnotateMozCrashReason("MOZ_ASSERT" "(" "privateBrand.empty()"
")"); do { *((volatile int*)__null) = 1593; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1594 if (!privateBrand.append(binding)) {
1595 return Nothing();
1596 }
1597 } else {
1598 if (!synthetics.append(binding)) {
1599 return Nothing();
1600 }
1601 }
1602 break;
1603
1604 case BindingKind::PrivateMethod:
1605 if (!privateMethods.append(binding)) {
1606 return Nothing();
1607 }
1608 break;
1609
1610 default:
1611 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"
, 1611); AnnotateMozCrashReason("MOZ_CRASH(" "bad class body scope BindingKind"
")"); do { *((volatile int*)__null) = 1611; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1612 break;
1613 }
1614 }
1615
1616 // We should have zero or one private brands.
1617 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"
, 1617); AnnotateMozCrashReason("MOZ_ASSERT" "(" "privateBrand.length() == 0 || privateBrand.length() == 1"
")"); do { *((volatile int*)__null) = 1617; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1618
1619 ClassBodyScope::ParserData* bindings = nullptr;
1620 uint32_t numBindings =
1621 privateBrand.length() + synthetics.length() + privateMethods.length();
1622
1623 if (numBindings > 0) {
1624 bindings = NewEmptyBindingData<ClassBodyScope>(fc, alloc, numBindings);
1625 if (!bindings) {
1626 return Nothing();
1627 }
1628 // To simplify initialization of the bindings, we concatenate the
1629 // synthetics+privateBrand vector such that the private brand is always the
1630 // first element, as ordering is important. See comments in ClassBodyScope.
1631 ParserBindingNameVector brandAndSynthetics(fc);
1632 if (!brandAndSynthetics.appendAll(privateBrand)) {
1633 return Nothing();
1634 }
1635 if (!brandAndSynthetics.appendAll(synthetics)) {
1636 return Nothing();
1637 }
1638
1639 // The ordering here is important. See comments in ClassBodyScope.
1640 InitializeBindingData(bindings, numBindings, brandAndSynthetics,
1641 &ParserClassBodyScopeSlotInfo::privateMethodStart,
1642 privateMethods);
1643 }
1644
1645 // `EmitterScope::lookupPrivate()` requires `.privateBrand` to be stored in a
1646 // predictable slot: the first slot available in the environment object,
1647 // `ClassBodyLexicalEnvironmentObject::privateBrandSlot()`. We assume that
1648 // if `.privateBrand` is first in the scope, it will be stored there.
1649 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"
, 1651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1650 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"
, 1651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1651 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"
, 1651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1652
1653 return Some(bindings);
1654}
1655
1656Maybe<ClassBodyScope::ParserData*> ParserBase::newClassBodyScopeData(
1657 ParseContext::Scope& scope) {
1658 return NewClassBodyScopeData(fc_, scope, stencilAlloc(), pc_);
1659}
1660
1661template <>
1662SyntaxParseHandler::LexicalScopeNodeResult
1663PerHandlerParser<SyntaxParseHandler>::finishLexicalScope(
1664 ParseContext::Scope& scope, Node body, ScopeKind kind) {
1665 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1666 return errorResult();
1667 }
1668
1669 return handler_.newLexicalScope(body);
1670}
1671
1672template <>
1673FullParseHandler::LexicalScopeNodeResult
1674PerHandlerParser<FullParseHandler>::finishLexicalScope(
1675 ParseContext::Scope& scope, ParseNode* body, ScopeKind kind) {
1676 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1677 return errorResult();
1678 }
1679
1680 Maybe<LexicalScope::ParserData*> bindings = newLexicalScopeData(scope);
1681 if (!bindings) {
1682 return errorResult();
1683 }
1684
1685 return handler_.newLexicalScope(*bindings, body, kind);
1686}
1687
1688template <>
1689SyntaxParseHandler::ClassBodyScopeNodeResult
1690PerHandlerParser<SyntaxParseHandler>::finishClassBodyScope(
1691 ParseContext::Scope& scope, ListNodeType body) {
1692 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1693 return errorResult();
1694 }
1695
1696 return handler_.newClassBodyScope(body);
1697}
1698
1699template <>
1700FullParseHandler::ClassBodyScopeNodeResult
1701PerHandlerParser<FullParseHandler>::finishClassBodyScope(
1702 ParseContext::Scope& scope, ListNode* body) {
1703 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1704 return errorResult();
1705 }
1706
1707 Maybe<ClassBodyScope::ParserData*> bindings = newClassBodyScopeData(scope);
1708 if (!bindings) {
1709 return errorResult();
1710 }
1711
1712 return handler_.newClassBodyScope(*bindings, body);
1713}
1714
1715template <class ParseHandler>
1716bool PerHandlerParser<ParseHandler>::checkForUndefinedPrivateFields(
1717 EvalSharedContext* evalSc) {
1718 if (!this->compilationState_.isInitialStencil()) {
1719 // We're delazifying -- so we already checked private names during first
1720 // parse.
1721 return true;
1722 }
1723
1724 Vector<UnboundPrivateName, 8> unboundPrivateNames(fc_);
1725 if (!usedNames_.getUnboundPrivateNames(unboundPrivateNames)) {
1726 return false;
1727 }
1728
1729 // No unbound names, let's get out of here!
1730 if (unboundPrivateNames.empty()) {
1731 return true;
1732 }
1733
1734 // It is an early error if there's private name references unbound,
1735 // unless it's an eval, in which case we need to check the scope
1736 // chain.
1737 if (!evalSc) {
1738 // The unbound private names are sorted, so just grab the first one.
1739 UnboundPrivateName minimum = unboundPrivateNames[0];
1740 UniqueChars str = this->parserAtoms().toPrintableString(minimum.atom);
1741 if (!str) {
1742 ReportOutOfMemory(this->fc_);
1743 return false;
1744 }
1745
1746 errorAt(minimum.position.begin, JSMSG_MISSING_PRIVATE_DECL, str.get());
1747 return false;
1748 }
1749
1750 // It's important that the unbound private names are sorted, as we
1751 // want our errors to always be issued to the first textually.
1752 for (UnboundPrivateName unboundName : unboundPrivateNames) {
1753 // If the enclosingScope is non-syntactic, then we are in a
1754 // Debugger.Frame.prototype.eval call. In order to find the declared private
1755 // names, we must use the effective scope that was determined when creating
1756 // the scopeContext.
1757 if (!this->compilationState_.scopeContext
1758 .effectiveScopePrivateFieldCacheHas(unboundName.atom)) {
1759 UniqueChars str = this->parserAtoms().toPrintableString(unboundName.atom);
1760 if (!str) {
1761 ReportOutOfMemory(this->fc_);
1762 return false;
1763 }
1764 errorAt(unboundName.position.begin, JSMSG_MISSING_PRIVATE_DECL,
1765 str.get());
1766 return false;
1767 }
1768 }
1769
1770 return true;
1771}
1772
1773template <typename Unit>
1774FullParseHandler::LexicalScopeNodeResult
1775Parser<FullParseHandler, Unit>::evalBody(EvalSharedContext* evalsc) {
1776 SourceParseContext evalpc(this, evalsc, /* newDirectives = */ nullptr);
1777 if (!evalpc.init()) {
1778 return errorResult();
1779 }
1780
1781 ParseContext::VarScope varScope(this);
1782 if (!varScope.init(pc_)) {
1783 return errorResult();
1784 }
1785
1786 LexicalScopeNode* body;
1787 {
1788 // All evals have an implicit non-extensible lexical scope.
1789 ParseContext::Scope lexicalScope(this);
1790 if (!lexicalScope.init(pc_)) {
1791 return errorResult();
1792 }
1793
1794 ListNode* list;
1795 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)
;
1796
1797 if (!checkStatementsEOF()) {
1798 return errorResult();
1799 }
1800
1801 // Private names not lexically defined must trigger a syntax error.
1802 if (!checkForUndefinedPrivateFields(evalsc)) {
1803 return errorResult();
1804 }
1805
1806 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)
;
1807 }
1808
1809#ifdef DEBUG1
1810 if (evalpc.superScopeNeedsHomeObject() &&
1811 !this->compilationState_.input.enclosingScope.isNull()) {
1812 // If superScopeNeedsHomeObject_ is set and we are an entry-point
1813 // ParseContext, then we must be emitting an eval script, and the
1814 // outer function must already be marked as needing a home object
1815 // since it contains an eval.
1816 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"
, 1819); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1819; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1817 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"
, 1819); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1819; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1818 "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"
, 1819); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1819; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1819 "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"
, 1819); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1819; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
1820 }
1821#endif
1822
1823 if (!CheckParseTree(this->fc_, alloc_, body)) {
1824 return errorResult();
1825 }
1826
1827 ParseNode* node = body;
1828 // Don't constant-fold inside "use asm" code, as this could create a parse
1829 // tree that doesn't type-check as asm.js.
1830 if (!pc_->useAsmOrInsideUseAsm()) {
1831 if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
1832 &handler_)) {
1833 return errorResult();
1834 }
1835 }
1836 body = handler_.asLexicalScopeNode(node);
1837
1838 if (!this->setSourceMapInfo()) {
1839 return errorResult();
1840 }
1841
1842 if (pc_->sc()->strict()) {
1843 if (!propagateFreeNamesAndMarkClosedOverBindings(varScope)) {
1844 return errorResult();
1845 }
1846 } else {
1847 // For non-strict eval scripts, since all bindings are automatically
1848 // considered closed over, we don't need to call propagateFreeNames-
1849 // AndMarkClosedOverBindings. However, Annex B.3.3 functions still need to
1850 // be marked.
1851 if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
1852 return errorResult();
1853 }
1854 }
1855
1856 Maybe<EvalScope::ParserData*> bindings = newEvalScopeData(pc_->varScope());
1857 if (!bindings) {
1858 return errorResult();
1859 }
1860 evalsc->bindings = *bindings;
1861
1862 return body;
1863}
1864
1865template <typename Unit>
1866FullParseHandler::ListNodeResult Parser<FullParseHandler, Unit>::globalBody(
1867 GlobalSharedContext* globalsc) {
1868 SourceParseContext globalpc(this, globalsc, /* newDirectives = */ nullptr);
1869 if (!globalpc.init()) {
1870 return errorResult();
1871 }
1872
1873 ParseContext::VarScope varScope(this);
1874 if (!varScope.init(pc_)) {
1875 return errorResult();
1876 }
1877
1878 ListNode* body;
1879 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)
;
1880
1881 if (!checkStatementsEOF()) {
1882 return errorResult();
1883 }
1884
1885 if (!CheckParseTree(this->fc_, alloc_, body)) {
1886 return errorResult();
1887 }
1888
1889 if (!checkForUndefinedPrivateFields()) {
1890 return errorResult();
1891 }
1892
1893 ParseNode* node = body;
1894 // Don't constant-fold inside "use asm" code, as this could create a parse
1895 // tree that doesn't type-check as asm.js.
1896 if (!pc_->useAsmOrInsideUseAsm()) {
1897 if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
1898 &handler_)) {
1899 return errorResult();
1900 }
1901 }
1902 body = &node->as<ListNode>();
1903
1904 if (!this->setSourceMapInfo()) {
1905 return errorResult();
1906 }
1907
1908 // For global scripts, whether bindings are closed over or not doesn't
1909 // matter, so no need to call propagateFreeNamesAndMarkClosedOver-
1910 // Bindings. However, Annex B.3.3 functions still need to be marked.
1911 if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
1912 return errorResult();
1913 }
1914
1915 Maybe<GlobalScope::ParserData*> bindings =
1916 newGlobalScopeData(pc_->varScope());
1917 if (!bindings) {
1918 return errorResult();
1919 }
1920 globalsc->bindings = *bindings;
1921
1922 return body;
1923}
1924
1925template <typename Unit>
1926FullParseHandler::ModuleNodeResult Parser<FullParseHandler, Unit>::moduleBody(
1927 ModuleSharedContext* modulesc) {
1928 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"
, 1928); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 1928; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1929
1930 this->compilationState_.moduleMetadata =
1931 fc_->getAllocator()->template new_<StencilModuleMetadata>();
1932 if (!this->compilationState_.moduleMetadata) {
1933 return errorResult();
1934 }
1935
1936 SourceParseContext modulepc(this, modulesc, nullptr);
1937 if (!modulepc.init()) {
1938 return errorResult();
1939 }
1940
1941 ParseContext::VarScope varScope(this);
1942 if (!varScope.init(pc_)) {
1943 return errorResult();
1944 }
1945
1946 ModuleNodeType moduleNode;
1947 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)
;
1948
1949 AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(
1950 this, AwaitIsModuleKeyword);
1951 ListNode* stmtList;
1952 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)
;
1953
1954 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"
, 1954); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stmtList->isKind(ParseNodeKind::StatementList)"
")"); do { *((volatile int*)__null) = 1954; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1955 moduleNode->setBody(&stmtList->template as<ListNode>());
1956
1957 if (pc_->isAsync()) {
1958 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_generator_())) {
1959 return errorResult();
1960 }
1961
1962 if (!pc_->declareTopLevelDotGeneratorName()) {
1963 return errorResult();
1964 }
1965 }
1966
1967 TokenKind tt;
1968 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
1969 return errorResult();
1970 }
1971 if (tt != TokenKind::Eof) {
1972 error(JSMSG_GARBAGE_AFTER_INPUT, "module", TokenKindToDesc(tt));
1973 return errorResult();
1974 }
1975
1976 // Set the module to async if an await keyword was found at the top level.
1977 if (pc_->isAsync()) {
1978 pc_->sc()->asModuleContext()->builder.noteAsync(
1979 *this->compilationState_.moduleMetadata);
1980 }
1981
1982 // Generate the Import/Export tables and store in CompilationState.
1983 if (!modulesc->builder.buildTables(*this->compilationState_.moduleMetadata)) {
1984 return errorResult();
1985 }
1986
1987 // Check exported local bindings exist and mark them as closed over.
1988 StencilModuleMetadata& moduleMetadata =
1989 *this->compilationState_.moduleMetadata;
1990 for (auto entry : moduleMetadata.localExportEntries) {
1991 DeclaredNamePtr p = modulepc.varScope().lookupDeclaredName(entry.localName);
1992 if (!p) {
1993 UniqueChars str = this->parserAtoms().toPrintableString(entry.localName);
1994 if (!str) {
1995 ReportOutOfMemory(this->fc_);
1996 return errorResult();
1997 }
1998
1999 errorNoOffset(JSMSG_MISSING_EXPORT, str.get());
2000 return errorResult();
2001 }
2002
2003 p->value()->setClosedOver();
2004 }
2005
2006 // Reserve an environment slot for a "*namespace*" psuedo-binding and mark as
2007 // closed-over. We do not know until module linking if this will be used.
2008 if (!noteDeclaredName(
2009 TaggedParserAtomIndex::WellKnown::star_namespace_star_(),
2010 DeclarationKind::Const, pos())) {
2011 return errorResult();
2012 }
2013 modulepc.varScope()
2014 .lookupDeclaredName(
2015 TaggedParserAtomIndex::WellKnown::star_namespace_star_())
2016 ->value()
2017 ->setClosedOver();
2018
2019 if (options().deoptimizeModuleGlobalVars) {
2020 for (BindingIter bi = modulepc.varScope().bindings(pc_); bi; bi++) {
2021 bi.setClosedOver();
2022 }
2023 }
2024
2025 if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
2026 return errorResult();
2027 }
2028
2029 ParseNode* node = stmtList;
2030 // Don't constant-fold inside "use asm" code, as this could create a parse
2031 // tree that doesn't type-check as asm.js.
2032 if (!pc_->useAsmOrInsideUseAsm()) {
2033 if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
2034 &handler_)) {
2035 return errorResult();
2036 }
2037 }
2038 stmtList = &node->as<ListNode>();
2039
2040 if (!this->setSourceMapInfo()) {
2041 return errorResult();
2042 }
2043
2044 // Private names not lexically defined must trigger a syntax error.
2045 if (!checkForUndefinedPrivateFields()) {
2046 return errorResult();
2047 }
2048
2049 if (!propagateFreeNamesAndMarkClosedOverBindings(modulepc.varScope())) {
2050 return errorResult();
2051 }
2052
2053 Maybe<ModuleScope::ParserData*> bindings =
2054 newModuleScopeData(modulepc.varScope());
2055 if (!bindings) {
2056 return errorResult();
2057 }
2058
2059 modulesc->bindings = *bindings;
2060 return moduleNode;
2061}
2062
2063template <typename Unit>
2064SyntaxParseHandler::ModuleNodeResult
2065Parser<SyntaxParseHandler, Unit>::moduleBody(ModuleSharedContext* modulesc) {
2066 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2066); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 2066; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
2067 return errorResult();
2068}
2069
2070template <class ParseHandler>
2071typename ParseHandler::NameNodeResult
2072PerHandlerParser<ParseHandler>::newInternalDotName(TaggedParserAtomIndex name) {
2073 NameNodeType nameNode;
2074 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)
;
2075 if (!noteUsedName(name)) {
2076 return errorResult();
2077 }
2078 return nameNode;
2079}
2080
2081template <class ParseHandler>
2082typename ParseHandler::NameNodeResult
2083PerHandlerParser<ParseHandler>::newThisName() {
2084 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_this_());
2085}
2086
2087template <class ParseHandler>
2088typename ParseHandler::NameNodeResult
2089PerHandlerParser<ParseHandler>::newNewTargetName() {
2090 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_newTarget_());
2091}
2092
2093template <class ParseHandler>
2094typename ParseHandler::NameNodeResult
2095PerHandlerParser<ParseHandler>::newDotGeneratorName() {
2096 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_generator_());
2097}
2098
2099template <class ParseHandler>
2100bool PerHandlerParser<ParseHandler>::finishFunctionScopes(
2101 bool isStandaloneFunction) {
2102 FunctionBox* funbox = pc_->functionBox();
2103
2104 if (funbox->hasParameterExprs) {
2105 if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->functionScope())) {
2106 return false;
2107 }
2108
2109 // Functions with parameter expressions utilize the FunctionScope for vars
2110 // generated by sloppy-direct-evals, as well as arguments (which are
2111 // lexicals bindings). If the function body has var bindings (or has a
2112 // sloppy-direct-eval that might), then an extra VarScope must be created
2113 // for them.
2114 if (VarScopeHasBindings(pc_) ||
2115 funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings()) {
2116 funbox->setFunctionHasExtraBodyVarScope();
2117 }
2118 }
2119
2120 // See: JSFunction::needsCallObject()
2121 if (FunctionScopeHasClosedOverBindings(pc_) ||
2122 funbox->needsCallObjectRegardlessOfBindings()) {
2123 funbox->setNeedsFunctionEnvironmentObjects();
2124 }
2125
2126 if (funbox->isNamedLambda() && !isStandaloneFunction) {
2127 if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->namedLambdaScope())) {
2128 return false;
2129 }
2130
2131 // See: JSFunction::needsNamedLambdaEnvironment()
2132 if (LexicalScopeHasClosedOverBindings(pc_, pc_->namedLambdaScope())) {
2133 funbox->setNeedsFunctionEnvironmentObjects();
2134 }
2135 }
2136
2137 return true;
2138}
2139
2140template <>
2141bool PerHandlerParser<FullParseHandler>::finishFunction(
2142 bool isStandaloneFunction /* = false */) {
2143 if (!finishFunctionScopes(isStandaloneFunction)) {
2144 return false;
2145 }
2146
2147 FunctionBox* funbox = pc_->functionBox();
2148 ScriptStencil& script = funbox->functionStencil();
2149
2150 if (funbox->isInterpreted()) {
2151 // BCE will need to generate bytecode for this.
2152 funbox->emitBytecode = true;
2153 this->compilationState_.nonLazyFunctionCount++;
2154 }
2155
2156 bool hasParameterExprs = funbox->hasParameterExprs;
2157
2158 if (hasParameterExprs) {
2159 Maybe<VarScope::ParserData*> bindings = newVarScopeData(pc_->varScope());
2160 if (!bindings) {
2161 return false;
2162 }
2163 funbox->setExtraVarScopeBindings(*bindings);
2164
2165 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"
, 2165); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == VarScopeHasBindings(pc_)"
")"); do { *((volatile int*)__null) = 2165; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2166 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"
, 2167); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
")"); do { *((volatile int*)__null) = 2167; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2167 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"
, 2167); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
")"); do { *((volatile int*)__null) = 2167; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2168 }
2169
2170 {
2171 Maybe<FunctionScope::ParserData*> bindings =
2172 newFunctionScopeData(pc_->functionScope(), hasParameterExprs);
2173 if (!bindings) {
2174 return false;
2175 }
2176 funbox->setFunctionScopeBindings(*bindings);
2177 }
2178
2179 if (funbox->isNamedLambda() && !isStandaloneFunction) {
2180 Maybe<LexicalScope::ParserData*> bindings =
2181 newLexicalScopeData(pc_->namedLambdaScope());
2182 if (!bindings) {
2183 return false;
2184 }
2185 funbox->setNamedLambdaBindings(*bindings);
2186 }
2187
2188 funbox->finishScriptFlags();
2189 funbox->copyFunctionFields(script);
2190
2191 if (this->compilationState_.isInitialStencil()) {
2192 ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
2193 funbox->copyFunctionExtraFields(scriptExtra);
2194 funbox->copyScriptExtraFields(scriptExtra);
2195 }
2196
2197 return true;
2198}
2199
2200template <>
2201bool PerHandlerParser<SyntaxParseHandler>::finishFunction(
2202 bool isStandaloneFunction /* = false */) {
2203 // The BaseScript for a lazily parsed function needs to know its set of
2204 // free variables and inner functions so that when it is fully parsed, we
2205 // can skip over any already syntax parsed inner functions and still
2206 // retain correct scope information.
2207
2208 if (!finishFunctionScopes(isStandaloneFunction)) {
2209 return false;
2210 }
2211
2212 FunctionBox* funbox = pc_->functionBox();
2213 ScriptStencil& script = funbox->functionStencil();
2214
2215 funbox->finishScriptFlags();
2216 funbox->copyFunctionFields(script);
2217
2218 ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
2219 funbox->copyFunctionExtraFields(scriptExtra);
2220 funbox->copyScriptExtraFields(scriptExtra);
2221
2222 // Elide nullptr sentinels from end of binding list. These are inserted for
2223 // each scope regardless of if any bindings are actually closed over.
2224 {
2225 AtomVector& closedOver = pc_->closedOverBindingsForLazy();
2226 while (!closedOver.empty() && !closedOver.back()) {
2227 closedOver.popBack();
2228 }
2229 }
2230
2231 // Check if we will overflow the `ngcthings` field later.
2232 mozilla::CheckedUint32 ngcthings =
2233 mozilla::CheckedUint32(pc_->innerFunctionIndexesForLazy.length()) +
2234 mozilla::CheckedUint32(pc_->closedOverBindingsForLazy().length());
2235 if (!ngcthings.isValid()) {
2236 ReportAllocationOverflow(fc_);
2237 return false;
2238 }
2239
2240 // If there are no script-things, we can return early without allocating.
2241 if (ngcthings.value() == 0) {
2242 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"
, 2242); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!script.hasGCThings()"
")"); do { *((volatile int*)__null) = 2242; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2243 return true;
2244 }
2245
2246 TaggedScriptThingIndex* cursor = nullptr;
2247 if (!this->compilationState_.allocateGCThingsUninitialized(
2248 fc_, funbox->index(), ngcthings.value(), &cursor)) {
2249 return false;
2250 }
2251
2252 // Copy inner-function and closed-over-binding info for the stencil. The order
2253 // is important here. We emit functions first, followed by the bindings info.
2254 // The bindings list uses nullptr as delimiter to separates the bindings per
2255 // scope.
2256 //
2257 // See: FullParseHandler::nextLazyInnerFunction(),
2258 // FullParseHandler::nextLazyClosedOverBinding()
2259 for (const ScriptIndex& index : pc_->innerFunctionIndexesForLazy) {
2260 void* raw = &(*cursor++);
2261 new (raw) TaggedScriptThingIndex(index);
2262 }
2263 for (auto binding : pc_->closedOverBindingsForLazy()) {
2264 void* raw = &(*cursor++);
2265 if (binding) {
2266 this->parserAtoms().markUsedByStencil(binding, ParserAtom::Atomize::Yes);
2267 new (raw) TaggedScriptThingIndex(binding);
2268 } else {
2269 new (raw) TaggedScriptThingIndex();
2270 }
2271 }
2272
2273 return true;
2274}
2275
2276static YieldHandling GetYieldHandling(GeneratorKind generatorKind) {
2277 if (generatorKind == GeneratorKind::NotGenerator) {
2278 return YieldIsName;
2279 }
2280 return YieldIsKeyword;
2281}
2282
2283static AwaitHandling GetAwaitHandling(FunctionAsyncKind asyncKind) {
2284 if (asyncKind == FunctionAsyncKind::SyncFunction) {
2285 return AwaitIsName;
2286 }
2287 return AwaitIsKeyword;
2288}
2289
2290static FunctionFlags InitialFunctionFlags(FunctionSyntaxKind kind,
2291 GeneratorKind generatorKind,
2292 FunctionAsyncKind asyncKind,
2293 bool isSelfHosting) {
2294 FunctionFlags flags = {};
2295
2296 switch (kind) {
2297 case FunctionSyntaxKind::Expression:
2298 flags = (generatorKind == GeneratorKind::NotGenerator &&
2299 asyncKind == FunctionAsyncKind::SyncFunction
2300 ? FunctionFlags::INTERPRETED_LAMBDA
2301 : FunctionFlags::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC);
2302 break;
2303 case FunctionSyntaxKind::Arrow:
2304 flags = FunctionFlags::INTERPRETED_LAMBDA_ARROW;
2305 break;
2306 case FunctionSyntaxKind::Method:
2307 case FunctionSyntaxKind::FieldInitializer:
2308 case FunctionSyntaxKind::StaticClassBlock:
2309 flags = FunctionFlags::INTERPRETED_METHOD;
2310 break;
2311 case FunctionSyntaxKind::ClassConstructor:
2312 case FunctionSyntaxKind::DerivedClassConstructor:
2313 flags = FunctionFlags::INTERPRETED_CLASS_CTOR;
2314 break;
2315 case FunctionSyntaxKind::Getter:
2316 flags = FunctionFlags::INTERPRETED_GETTER;
2317 break;
2318 case FunctionSyntaxKind::Setter:
2319 flags = FunctionFlags::INTERPRETED_SETTER;
2320 break;
2321 default:
2322 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"
, 2322); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == FunctionSyntaxKind::Statement"
")"); do { *((volatile int*)__null) = 2322; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2323 flags = (generatorKind == GeneratorKind::NotGenerator &&
2324 asyncKind == FunctionAsyncKind::SyncFunction
2325 ? FunctionFlags::INTERPRETED_NORMAL
2326 : FunctionFlags::INTERPRETED_GENERATOR_OR_ASYNC);
2327 }
2328
2329 if (isSelfHosting) {
2330 flags.setIsSelfHostedBuiltin();
2331 }
2332
2333 return flags;
2334}
2335
2336template <typename Unit>
2337FullParseHandler::FunctionNodeResult
2338Parser<FullParseHandler, Unit>::standaloneFunction(
2339 const Maybe<uint32_t>& parameterListEnd, FunctionSyntaxKind syntaxKind,
2340 GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
2341 Directives inheritedDirectives, Directives* newDirectives) {
2342 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"
, 2342); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 2342; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2343 // Skip prelude.
2344 TokenKind tt;
2345 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2346 return errorResult();
2347 }
2348 if (asyncKind == FunctionAsyncKind::AsyncFunction) {
2349 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"
, 2349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Async"
")"); do { *((volatile int*)__null) = 2349; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2350 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2351 return errorResult();
2352 }
2353 }
2354 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"
, 2354); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Function"
")"); do { *((volatile int*)__null) = 2354; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2355
2356 if (!tokenStream.getToken(&tt)) {
2357 return errorResult();
2358 }
2359 if (generatorKind == GeneratorKind::Generator) {
2360 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"
, 2360); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Mul"
")"); do { *((volatile int*)__null) = 2360; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2361 if (!tokenStream.getToken(&tt)) {
2362 return errorResult();
2363 }
2364 }
2365
2366 // Skip function name, if present.
2367 TaggedParserAtomIndex explicitName;
2368 if (TokenKindIsPossibleIdentifierName(tt)) {
2369 explicitName = anyChars.currentName();
2370 } else {
2371 anyChars.ungetToken();
2372 }
2373
2374 FunctionNodeType funNode;
2375 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)
;
2376
2377 ParamsBodyNodeType argsbody;
2378 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)
;
2379 funNode->setBody(argsbody);
2380
2381 bool isSelfHosting = options().selfHostingMode;
2382 FunctionFlags flags =
2383 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
2384 FunctionBox* funbox =
2385 newFunctionBox(funNode, explicitName, flags, /* toStringStart = */ 0,
2386 inheritedDirectives, generatorKind, asyncKind);
2387 if (!funbox) {
2388 return errorResult();
2389 }
2390
2391 // Function is not syntactically part of another script.
2392 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"
, 2392); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->index() == CompilationStencil::TopLevelIndex"
")"); do { *((volatile int*)__null) = 2392; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2393
2394 funbox->initStandalone(this->compilationState_.scopeContext, syntaxKind);
2395
2396 SourceParseContext funpc(this, funbox, newDirectives);
2397 if (!funpc.init()) {
2398 return errorResult();
2399 }
2400
2401 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
2402 AwaitHandling awaitHandling = GetAwaitHandling(asyncKind);
2403 AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(this,
2404 awaitHandling);
2405 if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
2406 syntaxKind, parameterListEnd,
2407 /* isStandaloneFunction = */ true)) {
2408 return errorResult();
2409 }
2410
2411 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2412 return errorResult();
2413 }
2414 if (tt != TokenKind::Eof) {
2415 error(JSMSG_GARBAGE_AFTER_INPUT, "function body", TokenKindToDesc(tt));
2416 return errorResult();
2417 }
2418
2419 if (!CheckParseTree(this->fc_, alloc_, funNode)) {
2420 return errorResult();
2421 }
2422
2423 ParseNode* node = funNode;
2424 // Don't constant-fold inside "use asm" code, as this could create a parse
2425 // tree that doesn't type-check as asm.js.
2426 if (!pc_->useAsmOrInsideUseAsm()) {
2427 if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
2428 &handler_)) {
2429 return errorResult();
2430 }
2431 }
2432 funNode = &node->as<FunctionNode>();
2433
2434 if (!checkForUndefinedPrivateFields(nullptr)) {
2435 return errorResult();
2436 }
2437
2438 if (!this->setSourceMapInfo()) {
2439 return errorResult();
2440 }
2441
2442 return funNode;
2443}
2444
2445template <class ParseHandler, typename Unit>
2446typename ParseHandler::LexicalScopeNodeResult
2447GeneralParser<ParseHandler, Unit>::functionBody(InHandling inHandling,
2448 YieldHandling yieldHandling,
2449 FunctionSyntaxKind kind,
2450 FunctionBodyType type) {
2451 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"
, 2451); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 2451; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2452
2453#ifdef DEBUG1
2454 uint32_t startYieldOffset = pc_->lastYieldOffset;
2455#endif
2456
2457 Node body;
2458 if (type == StatementListBody) {
2459 bool inheritedStrict = pc_->sc()->strict();
2460 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)
;
2461
2462 // When we transitioned from non-strict to strict mode, we need to
2463 // validate that all parameter names are valid strict mode names.
2464 if (!inheritedStrict && pc_->sc()->strict()) {
2465 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"
, 2467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2467; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2466 "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"
, 2467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2467; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2467 "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"
, 2467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2467; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
2468 if (!hasValidSimpleStrictParameterNames()) {
2469 // Request that this function be reparsed as strict to report
2470 // the invalid parameter name at the correct source location.
2471 pc_->newDirectives->setStrict();
2472 return errorResult();
2473 }
2474 }
2475 } else {
2476 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"
, 2476); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == ExpressionBody"
")"); do { *((volatile int*)__null) = 2476; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2477
2478 // Async functions are implemented as generators, and generators are
2479 // assumed to be statement lists, to prepend initial `yield`.
2480 ListNodeType stmtList = null();
2481 if (pc_->isAsync()) {
2482 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)
;
2483 }
2484
2485 Node kid;
2486 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)
2487 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)
;
2488
2489 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)
;
2490
2491 if (pc_->isAsync()) {
2492 handler_.addStatementToList(stmtList, body);
2493 body = stmtList;
2494 }
2495 }
2496
2497 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"
, 2498); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->lastYieldOffset == startYieldOffset"
")"); do { *((volatile int*)__null) = 2498; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2498 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"
, 2498); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->lastYieldOffset == startYieldOffset"
")"); do { *((volatile int*)__null) = 2498; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2499 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"
, 2499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind != FunctionSyntaxKind::Arrow"
")"); do { *((volatile int*)__null) = 2499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2500 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"
, 2500); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == StatementListBody"
")"); do { *((volatile int*)__null) = 2500; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2501
2502 if (pc_->needsDotGeneratorName()) {
2503 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"
, 2503); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == StatementListBody"
")"); do { *((volatile int*)__null) = 2503; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2504 if (!pc_->declareDotGeneratorName()) {
2505 return errorResult();
2506 }
2507 if (pc_->isGenerator()) {
2508 NameNodeType generator;
2509 MOZ_TRY_VAR(generator, newDotGeneratorName())do { auto mozTryVarTempResult_ = (newDotGeneratorName()); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (generator) = mozTryVarTempResult_
.unwrap(); } while (0)
;
2510 if (!handler_.prependInitialYield(handler_.asListNode(body), generator)) {
2511 return errorResult();
2512 }
2513 }
2514 }
2515
2516 if (pc_->numberOfArgumentsNames > 0 || kind == FunctionSyntaxKind::Arrow) {
2517 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"
, 2517); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 2517; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2518 pc_->sc()->setIneligibleForArgumentsLength();
2519 }
2520
2521 // Declare the 'arguments', 'this', and 'new.target' bindings if necessary
2522 // before finishing up the scope so these special bindings get marked as
2523 // closed over if necessary. Arrow functions don't have these bindings.
2524 if (kind != FunctionSyntaxKind::Arrow) {
2525 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
2526 if (!pc_->declareFunctionArgumentsObject(usedNames_,
2527 canSkipLazyClosedOverBindings)) {
2528 return errorResult();
2529 }
2530 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
2531 return errorResult();
2532 }
2533 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
2534 return errorResult();
2535 }
2536 }
2537
2538 return finishLexicalScope(pc_->varScope(), body, ScopeKind::FunctionLexical);
2539}
2540
2541template <class ParseHandler, typename Unit>
2542bool GeneralParser<ParseHandler, Unit>::matchOrInsertSemicolon(
2543 Modifier modifier /* = TokenStream::SlashIsRegExp */) {
2544 TokenKind tt = TokenKind::Eof;
2545 if (!tokenStream.peekTokenSameLine(&tt, modifier)) {
2546 return false;
2547 }
2548 if (tt != TokenKind::Eof && tt != TokenKind::Eol && tt != TokenKind::Semi &&
2549 tt != TokenKind::RightCurly) {
2550 /*
2551 * When current token is `await` and it's outside of async function,
2552 * it's possibly intended to be an await expression.
2553 *
2554 * await f();
2555 * ^
2556 * |
2557 * tried to insert semicolon here
2558 *
2559 * Detect this situation and throw an understandable error. Otherwise
2560 * we'd throw a confusing "unexpected token: (unexpected token)" error.
2561 */
2562 if (!pc_->isAsync() && anyChars.currentToken().type == TokenKind::Await) {
2563 error(JSMSG_AWAIT_OUTSIDE_ASYNC_OR_MODULE);
2564 return false;
2565 }
2566 if (!yieldExpressionsSupported() &&
2567 anyChars.currentToken().type == TokenKind::Yield) {
2568 error(JSMSG_YIELD_OUTSIDE_GENERATOR);
2569 return false;
2570 }
2571
2572#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
2573 if (options().explicitResourceManagement() &&
2574 !this->pc_->isUsingSyntaxAllowed() &&
2575 anyChars.currentToken().type == TokenKind::Using) {
2576 error(JSMSG_USING_OUTSIDE_BLOCK_OR_MODULE);
2577 return false;
2578 }
2579#endif
2580
2581 /* Advance the scanner for proper error location reporting. */
2582 tokenStream.consumeKnownToken(tt, modifier);
2583 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(tt));
2584 return false;
2585 }
2586 bool matched;
2587 return tokenStream.matchToken(&matched, TokenKind::Semi, modifier);
2588}
2589
2590bool ParserBase::leaveInnerFunction(ParseContext* outerpc) {
2591 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"
, 2591); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_ != outerpc"
")"); do { *((volatile int*)__null) = 2591; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2592
2593 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"
, 2594); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outerpc->functionBox()->index() < pc_->functionBox()->index()"
")"); do { *((volatile int*)__null) = 2594; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2594 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"
, 2594); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outerpc->functionBox()->index() < pc_->functionBox()->index()"
")"); do { *((volatile int*)__null) = 2594; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2595
2596 // If the current function allows super.property but cannot have a home
2597 // object, i.e., it is an arrow function, we need to propagate the flag to
2598 // the outer ParseContext.
2599 if (pc_->superScopeNeedsHomeObject()) {
2600 if (!pc_->isArrowFunction()) {
2601 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"
, 2601); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->needsHomeObject()"
")"); do { *((volatile int*)__null) = 2601; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2602 } else {
2603 outerpc->setSuperScopeNeedsHomeObject();
2604 }
2605 }
2606
2607 // Lazy functions inner to another lazy function need to be remembered by
2608 // the inner function so that if the outer function is eventually parsed
2609 // we do not need any further parsing or processing of the inner function.
2610 //
2611 // Append the inner function index here unconditionally; the vector is only
2612 // used if the Parser using outerpc is a syntax parsing. See
2613 // GeneralParser<SyntaxParseHandler>::finishFunction.
2614 if (!outerpc->innerFunctionIndexesForLazy.append(
2615 pc_->functionBox()->index())) {
2616 return false;
2617 }
2618
2619 PropagateTransitiveParseFlags(pc_->functionBox(), outerpc->sc());
2620
2621 return true;
2622}
2623
2624TaggedParserAtomIndex ParserBase::prefixAccessorName(
2625 PropertyType propType, TaggedParserAtomIndex propAtom) {
2626 StringBuilder prefixed(fc_);
2627 if (propType == PropertyType::Setter) {
2628 if (!prefixed.append("set ")) {
2629 return TaggedParserAtomIndex::null();
2630 }
2631 } else {
2632 if (!prefixed.append("get ")) {
2633 return TaggedParserAtomIndex::null();
2634 }
2635 }
2636 if (!prefixed.append(this->parserAtoms(), propAtom)) {
2637 return TaggedParserAtomIndex::null();
2638 }
2639 return prefixed.finishParserAtom(this->parserAtoms(), fc_);
2640}
2641
2642template <class ParseHandler, typename Unit>
2643void GeneralParser<ParseHandler, Unit>::setFunctionStartAtPosition(
2644 FunctionBox* funbox, TokenPos pos) const {
2645 uint32_t startLine;
2646 JS::LimitedColumnNumberOneOrigin startColumn;
2647 tokenStream.computeLineAndColumn(pos.begin, &startLine, &startColumn);
2648
2649 // NOTE: `Debugger::CallData::findScripts` relies on sourceStart and
2650 // lineno/column referring to the same location.
2651 funbox->setStart(pos.begin, startLine, startColumn);
2652}
2653
2654template <class ParseHandler, typename Unit>
2655void GeneralParser<ParseHandler, Unit>::setFunctionStartAtCurrentToken(
2656 FunctionBox* funbox) const {
2657 setFunctionStartAtPosition(funbox, anyChars.currentToken().pos);
2658}
2659
2660template <class ParseHandler, typename Unit>
2661bool GeneralParser<ParseHandler, Unit>::functionArguments(
2662 YieldHandling yieldHandling, FunctionSyntaxKind kind,
2663 FunctionNodeType funNode) {
2664 FunctionBox* funbox = pc_->functionBox();
2665
2666 // Modifier for the following tokens.
2667 // TokenStream::SlashIsDiv for the following cases:
2668 // async a => 1
2669 // ^
2670 //
2671 // (a) => 1
2672 // ^
2673 //
2674 // async (a) => 1
2675 // ^
2676 //
2677 // function f(a) {}
2678 // ^
2679 //
2680 // TokenStream::SlashIsRegExp for the following case:
2681 // a => 1
2682 // ^
2683 Modifier firstTokenModifier =
2684 kind != FunctionSyntaxKind::Arrow || funbox->isAsync()
2685 ? TokenStream::SlashIsDiv
2686 : TokenStream::SlashIsRegExp;
2687 TokenKind tt;
2688 if (!tokenStream.getToken(&tt, firstTokenModifier)) {
2689 return false;
2690 }
2691
2692 if (kind == FunctionSyntaxKind::Arrow && TokenKindIsPossibleIdentifier(tt)) {
2693 // Record the start of function source (for FunctionToString).
2694 setFunctionStartAtCurrentToken(funbox);
2695
2696 ParamsBodyNodeType argsbody;
2697 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)
;
2698 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
2699
2700 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
2701 if (!name) {
2702 return false;
2703 }
2704
2705 constexpr bool disallowDuplicateParams = true;
2706 bool duplicatedParam = false;
2707 if (!notePositionalFormalParameter(funNode, name, pos().begin,
2708 disallowDuplicateParams,
2709 &duplicatedParam)) {
2710 return false;
2711 }
2712 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"
, 2712); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!duplicatedParam"
")"); do { *((volatile int*)__null) = 2712; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2713 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"
, 2713); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->positionalFormalParameterNames().length() == 1"
")"); do { *((volatile int*)__null) = 2713; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2714
2715 funbox->setLength(1);
2716 funbox->setArgCount(1);
2717 return true;
2718 }
2719
2720 if (tt != TokenKind::LeftParen) {
2721 error(kind == FunctionSyntaxKind::Arrow ? JSMSG_BAD_ARROW_ARGS
2722 : JSMSG_PAREN_BEFORE_FORMAL);
2723 return false;
2724 }
2725
2726 // Record the start of function source (for FunctionToString).
2727 setFunctionStartAtCurrentToken(funbox);
2728
2729 ParamsBodyNodeType argsbody;
2730 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)
;
2731 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
2732
2733 bool matched;
2734 if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
2735 TokenStream::SlashIsRegExp)) {
2736 return false;
2737 }
2738 if (!matched) {
2739 bool hasRest = false;
2740 bool hasDefault = false;
2741 bool duplicatedParam = false;
2742 bool disallowDuplicateParams =
2743 kind == FunctionSyntaxKind::Arrow ||
2744 kind == FunctionSyntaxKind::Method ||
2745 kind == FunctionSyntaxKind::FieldInitializer ||
2746 kind == FunctionSyntaxKind::ClassConstructor;
2747 AtomVector& positionalFormals = pc_->positionalFormalParameterNames();
2748
2749 if (kind == FunctionSyntaxKind::Getter) {
2750 error(JSMSG_ACCESSOR_WRONG_ARGS, "getter", "no", "s");
2751 return false;
2752 }
2753
2754 while (true) {
2755 if (hasRest) {
2756 error(JSMSG_PARAMETER_AFTER_REST);
2757 return false;
2758 }
2759
2760 TokenKind tt;
2761 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2762 return false;
2763 }
2764
2765 if (tt == TokenKind::TripleDot) {
2766 if (kind == FunctionSyntaxKind::Setter) {
2767 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2768 return false;
2769 }
2770
2771 disallowDuplicateParams = true;
2772 if (duplicatedParam) {
2773 // Has duplicated args before the rest parameter.
2774 error(JSMSG_BAD_DUP_ARGS);
2775 return false;
2776 }
2777
2778 hasRest = true;
2779 funbox->setHasRest();
2780
2781 if (!tokenStream.getToken(&tt)) {
2782 return false;
2783 }
2784
2785 if (!TokenKindIsPossibleIdentifier(tt) &&
2786 tt != TokenKind::LeftBracket && tt != TokenKind::LeftCurly) {
2787 error(JSMSG_NO_REST_NAME);
2788 return false;
2789 }
2790 }
2791
2792 switch (tt) {
2793 case TokenKind::LeftBracket:
2794 case TokenKind::LeftCurly: {
2795 disallowDuplicateParams = true;
2796 if (duplicatedParam) {
2797 // Has duplicated args before the destructuring parameter.
2798 error(JSMSG_BAD_DUP_ARGS);
2799 return false;
2800 }
2801
2802 funbox->hasDestructuringArgs = true;
2803
2804 Node destruct;
2805 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)
2806 destruct,do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2807 destructuringDeclarationWithoutYieldOrAwait(do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2808 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)
2809 false)do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
;
2810
2811 if (!noteDestructuredPositionalFormalParameter(funNode, destruct)) {
2812 return false;
2813 }
2814
2815 break;
2816 }
2817
2818 default: {
2819 if (!TokenKindIsPossibleIdentifier(tt)) {
2820 error(JSMSG_MISSING_FORMAL);
2821 return false;
2822 }
2823
2824 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
2825 if (!name) {
2826 return false;
2827 }
2828
2829 if (!notePositionalFormalParameter(funNode, name, pos().begin,
2830 disallowDuplicateParams,
2831 &duplicatedParam)) {
2832 return false;
2833 }
2834 if (duplicatedParam) {
2835 funbox->hasDuplicateParameters = true;
2836 }
2837
2838 break;
2839 }
2840 }
2841
2842 if (positionalFormals.length() >= ARGNO_LIMIT) {
2843 error(JSMSG_TOO_MANY_FUN_ARGS);
2844 return false;
2845 }
2846
2847 bool matched;
2848 if (!tokenStream.matchToken(&matched, TokenKind::Assign,
2849 TokenStream::SlashIsRegExp)) {
2850 return false;
2851 }
2852 if (matched) {
2853 if (hasRest) {
2854 error(JSMSG_REST_WITH_DEFAULT);
2855 return false;
2856 }
2857 disallowDuplicateParams = true;
2858 if (duplicatedParam) {
2859 error(JSMSG_BAD_DUP_ARGS);
2860 return false;
2861 }
2862
2863 if (!hasDefault) {
2864 hasDefault = true;
2865
2866 // The Function.length property is the number of formals
2867 // before the first default argument.
2868 funbox->setLength(positionalFormals.length() - 1);
2869 }
2870 funbox->hasParameterExprs = true;
2871
2872 Node def_expr;
2873 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (assignExprWithoutYieldOrAwait
(yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (def_expr) = parserTryVarTempResult_
.unwrap(); } while (0)
2874 def_expr, assignExprWithoutYieldOrAwait(yieldHandling), false)do { auto parserTryVarTempResult_ = (assignExprWithoutYieldOrAwait
(yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (def_expr) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2875 if (!handler_.setLastFunctionFormalParameterDefault(funNode,
2876 def_expr)) {
2877 return false;
2878 }
2879 }
2880
2881 // Setter syntax uniquely requires exactly one argument.
2882 if (kind == FunctionSyntaxKind::Setter) {
2883 break;
2884 }
2885
2886 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
2887 TokenStream::SlashIsRegExp)) {
2888 return false;
2889 }
2890 if (!matched) {
2891 break;
2892 }
2893
2894 if (!hasRest) {
2895 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
2896 return false;
2897 }
2898 if (tt == TokenKind::RightParen) {
2899 break;
2900 }
2901 }
2902 }
2903
2904 TokenKind tt;
2905 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2906 return false;
2907 }
2908 if (tt != TokenKind::RightParen) {
2909 if (kind == FunctionSyntaxKind::Setter) {
2910 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2911 return false;
2912 }
2913
2914 error(JSMSG_PAREN_AFTER_FORMAL);
2915 return false;
2916 }
2917
2918 if (!hasDefault) {
2919 funbox->setLength(positionalFormals.length() - hasRest);
2920 }
2921
2922 funbox->setArgCount(positionalFormals.length());
2923 } else if (kind == FunctionSyntaxKind::Setter) {
2924 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2925 return false;
2926 }
2927
2928 return true;
2929}
2930
2931template <typename Unit>
2932bool Parser<FullParseHandler, Unit>::skipLazyInnerFunction(
2933 FunctionNode* funNode, uint32_t toStringStart, bool tryAnnexB) {
2934 // When a lazily-parsed function is called, we only fully parse (and emit)
2935 // that function, not any of its nested children. The initial syntax-only
2936 // parse recorded the free variables of nested functions and their extents,
2937 // so we can skip over them after accounting for their free variables.
2938
2939 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"
, 2939); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isOutermostOfCurrentCompile()"
")"); do { *((volatile int*)__null) = 2939; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2940 handler_.nextLazyInnerFunction();
2941 const ScriptStencil& cachedData = handler_.cachedScriptData();
2942 const ScriptStencilExtra& cachedExtra = handler_.cachedScriptExtra();
2943 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"
, 2943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "toStringStart == cachedExtra.extent.toStringStart"
")"); do { *((volatile int*)__null) = 2943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2944
2945 FunctionBox* funbox = newFunctionBox(funNode, cachedData, cachedExtra);
2946 if (!funbox) {
2947 return false;
2948 }
2949
2950 ScriptStencil& script = funbox->functionStencil();
2951 funbox->copyFunctionFields(script);
2952
2953 // If the inner lazy function is class constructor, connect it to the class
2954 // statement/expression we are parsing.
2955 if (funbox->isClassConstructor()) {
2956 auto classStmt =
2957 pc_->template findInnermostStatement<ParseContext::ClassStatement>();
2958 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"
, 2958); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!classStmt->constructorBox"
")"); do { *((volatile int*)__null) = 2958; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2959 classStmt->constructorBox = funbox;
2960 }
2961
2962 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"
, 2963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->index() < funbox->index()"
")"); do { *((volatile int*)__null) = 2963; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2963 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"
, 2963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->index() < funbox->index()"
")"); do { *((volatile int*)__null) = 2963; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2964
2965 PropagateTransitiveParseFlags(funbox, pc_->sc());
2966
2967 if (!tokenStream.advance(funbox->extent().sourceEnd)) {
2968 return false;
2969 }
2970
2971 // Append possible Annex B function box only upon successfully parsing.
2972 if (tryAnnexB &&
2973 !pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
2974 return false;
2975 }
2976
2977 return true;
2978}
2979
2980template <typename Unit>
2981bool Parser<SyntaxParseHandler, Unit>::skipLazyInnerFunction(
2982 FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
2983 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"
, 2983); AnnotateMozCrashReason("MOZ_CRASH(" "Cannot skip lazy inner functions when syntax parsing"
")"); do { *((volatile int*)__null) = 2983; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
2984}
2985
2986template <class ParseHandler, typename Unit>
2987bool GeneralParser<ParseHandler, Unit>::skipLazyInnerFunction(
2988 FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
2989 return asFinalParser()->skipLazyInnerFunction(funNode, toStringStart,
2990 tryAnnexB);
2991}
2992
2993template <class ParseHandler, typename Unit>
2994bool GeneralParser<ParseHandler, Unit>::addExprAndGetNextTemplStrToken(
2995 YieldHandling yieldHandling, ListNodeType nodeList, TokenKind* ttp) {
2996 Node pn;
2997 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)
2998 false)do { auto parserTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (pn) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2999 handler_.addList(nodeList, pn);
3000
3001 TokenKind tt;
3002 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
3003 return false;
3004 }
3005 if (tt != TokenKind::RightCurly) {
3006 error(JSMSG_TEMPLSTR_UNTERM_EXPR);
3007 return false;
3008 }
3009
3010 return tokenStream.getTemplateToken(ttp);
3011}
3012
3013template <class ParseHandler, typename Unit>
3014bool GeneralParser<ParseHandler, Unit>::taggedTemplate(
3015 YieldHandling yieldHandling, ListNodeType tagArgsList, TokenKind tt) {
3016 CallSiteNodeType callSiteObjNode;
3017 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)
3018 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)
;
3019 handler_.addList(tagArgsList, callSiteObjNode);
3020
3021 pc_->sc()->setHasCallSiteObj();
3022
3023 while (true) {
3024 if (!appendToCallSiteObj(callSiteObjNode)) {
3025 return false;
3026 }
3027 if (tt != TokenKind::TemplateHead) {
3028 break;
3029 }
3030
3031 if (!addExprAndGetNextTemplStrToken(yieldHandling, tagArgsList, &tt)) {
3032 return false;
3033 }
3034 }
3035 handler_.setEndPosition(tagArgsList, callSiteObjNode);
3036 return true;
3037}
3038
3039template <class ParseHandler, typename Unit>
3040typename ParseHandler::ListNodeResult
3041GeneralParser<ParseHandler, Unit>::templateLiteral(
3042 YieldHandling yieldHandling) {
3043 NameNodeType literal;
3044 MOZ_TRY_VAR(literal, noSubstitutionUntaggedTemplate())do { auto mozTryVarTempResult_ = (noSubstitutionUntaggedTemplate
()); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
3045
3046 ListNodeType nodeList;
3047 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)
3048 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)
;
3049
3050 TokenKind tt;
3051 do {
3052 if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt)) {
3053 return errorResult();
3054 }
3055
3056 MOZ_TRY_VAR(literal, noSubstitutionUntaggedTemplate())do { auto mozTryVarTempResult_ = (noSubstitutionUntaggedTemplate
()); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
3057
3058 handler_.addList(nodeList, literal);
3059 } while (tt == TokenKind::TemplateHead);
3060 return nodeList;
3061}
3062
3063template <class ParseHandler, typename Unit>
3064typename ParseHandler::FunctionNodeResult
3065GeneralParser<ParseHandler, Unit>::functionDefinition(
3066 FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
3067 YieldHandling yieldHandling, TaggedParserAtomIndex funName,
3068 FunctionSyntaxKind kind, GeneratorKind generatorKind,
3069 FunctionAsyncKind asyncKind, bool tryAnnexB /* = false */) {
3070 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"
, 3070); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funName" ")"
); do { *((volatile int*)__null) = 3070; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3071
3072 // If we see any inner function, note it on our current context. The bytecode
3073 // emitter may eliminate the function later, but we use a conservative
3074 // definition for consistency between lazy and full parsing.
3075 pc_->sc()->setHasInnerFunctions();
3076
3077 // When fully parsing a lazy script, we do not fully reparse its inner
3078 // functions, which are also lazy. Instead, their free variables and source
3079 // extents are recorded and may be skipped.
3080 if (handler_.reuseLazyInnerFunctions()) {
3081 if (!skipLazyInnerFunction(funNode, toStringStart, tryAnnexB)) {
3082 return errorResult();
3083 }
3084
3085 return funNode;
3086 }
3087
3088 bool isSelfHosting = options().selfHostingMode;
3089 FunctionFlags flags =
3090 InitialFunctionFlags(kind, generatorKind, asyncKind, isSelfHosting);
3091
3092 // Self-hosted functions with special function names require extended slots
3093 // for various purposes.
3094 bool forceExtended =
3095 isSelfHosting && funName &&
3096 this->parserAtoms().isExtendedUnclonedSelfHostedFunctionName(funName);
3097 if (forceExtended) {
3098 flags.setIsExtended();
3099 }
3100
3101 // Speculatively parse using the directives of the parent parsing context.
3102 // If a directive is encountered (e.g., "use strict") that changes how the
3103 // function should have been parsed, we backup and reparse with the new set
3104 // of directives.
3105 Directives directives(pc_);
3106 Directives newDirectives = directives;
3107
3108 Position start(tokenStream);
3109 auto startObj = this->compilationState_.getPosition();
3110
3111 // Parse the inner function. The following is a loop as we may attempt to
3112 // reparse a function due to failed syntax parsing and encountering new
3113 // "use foo" directives.
3114 while (true) {
3115 if (trySyntaxParseInnerFunction(&funNode, funName, flags, toStringStart,
3116 inHandling, yieldHandling, kind,
3117 generatorKind, asyncKind, tryAnnexB,
3118 directives, &newDirectives)) {
3119 break;
3120 }
3121
3122 // Return on error.
3123 if (anyChars.hadError() || directives == newDirectives) {
3124 return errorResult();
3125 }
3126
3127 // Assignment must be monotonic to prevent infinitely attempting to
3128 // reparse.
3129 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"
, 3129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newDirectives.strict()"
")"); do { *((volatile int*)__null) = 3129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3130 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"
, 3130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newDirectives.asmJS()"
")"); do { *((volatile int*)__null) = 3130; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3131 directives = newDirectives;
3132
3133 // Rewind to retry parsing with new directives applied.
3134 tokenStream.rewind(start);
3135 this->compilationState_.rewind(startObj);
3136
3137 // functionFormalParametersAndBody may have already set body before failing.
3138 handler_.setFunctionFormalParametersAndBody(funNode, null());
3139 }
3140
3141 return funNode;
3142}
3143
3144template <typename Unit>
3145bool Parser<FullParseHandler, Unit>::advancePastSyntaxParsedFunction(
3146 SyntaxParser* syntaxParser) {
3147 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"
, 3147); AnnotateMozCrashReason("MOZ_ASSERT" "(" "getSyntaxParser() == syntaxParser"
")"); do { *((volatile int*)__null) = 3147; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3148
3149 // Advance this parser over tokens processed by the syntax parser.
3150 Position currentSyntaxPosition(syntaxParser->tokenStream);
3151 if (!tokenStream.fastForward(currentSyntaxPosition, syntaxParser->anyChars)) {
3152 return false;
3153 }
3154
3155 anyChars.adoptState(syntaxParser->anyChars);
3156 tokenStream.adoptState(syntaxParser->tokenStream);
3157 return true;
3158}
3159
3160template <typename Unit>
3161bool Parser<FullParseHandler, Unit>::trySyntaxParseInnerFunction(
3162 FunctionNode** funNode, TaggedParserAtomIndex explicitName,
3163 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3164 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3165 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3166 Directives inheritedDirectives, Directives* newDirectives) {
3167 // Try a syntax parse for this inner function.
3168 do {
3169 // If we're assuming this function is an IIFE, always perform a full
3170 // parse to avoid the overhead of a lazy syntax-only parse. Although
3171 // the prediction may be incorrect, IIFEs are common enough that it
3172 // pays off for lots of code.
3173 if ((*funNode)->isLikelyIIFE() &&
3174 generatorKind == GeneratorKind::NotGenerator &&
3175 asyncKind == FunctionAsyncKind::SyncFunction) {
3176 break;
3177 }
3178
3179 SyntaxParser* syntaxParser = getSyntaxParser();
3180 if (!syntaxParser) {
3181 break;
3182 }
3183
3184 UsedNameTracker::RewindToken token = usedNames_.getRewindToken();
3185 auto statePosition = this->compilationState_.getPosition();
3186
3187 // Move the syntax parser to the current position in the stream. In the
3188 // common case this seeks forward, but it'll also seek backward *at least*
3189 // when arrow functions appear inside arrow function argument defaults
3190 // (because we rewind to reparse arrow functions once we're certain they're
3191 // arrow functions):
3192 //
3193 // var x = (y = z => 2) => q;
3194 // // ^ we first seek to here to syntax-parse this function
3195 // // ^ then we seek back to here to syntax-parse the outer function
3196 Position currentPosition(tokenStream);
3197 if (!syntaxParser->tokenStream.seekTo(currentPosition, anyChars)) {
3198 return false;
3199 }
3200
3201 // Make a FunctionBox before we enter the syntax parser, because |pn|
3202 // still expects a FunctionBox to be attached to it during BCE, and
3203 // the syntax parser cannot attach one to it.
3204 FunctionBox* funbox =
3205 newFunctionBox(*funNode, explicitName, flags, toStringStart,
3206 inheritedDirectives, generatorKind, asyncKind);
3207 if (!funbox) {
3208 return false;
3209 }
3210 funbox->initWithEnclosingParseContext(pc_, kind);
3211
3212 auto syntaxNodeResult = syntaxParser->innerFunctionForFunctionBox(
3213 SyntaxParseHandler::Node::NodeGeneric, pc_, funbox, inHandling,
3214 yieldHandling, kind, newDirectives);
3215 if (syntaxNodeResult.isErr()) {
3216 if (syntaxParser->hadAbortedSyntaxParse()) {
3217 // Try again with a full parse. UsedNameTracker needs to be
3218 // rewound to just before we tried the syntax parse for
3219 // correctness.
3220 syntaxParser->clearAbortedSyntaxParse();
3221 usedNames_.rewind(token);
3222 this->compilationState_.rewind(statePosition);
3223 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"
, 3223); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!fc_->hadErrors()"
")"); do { *((volatile int*)__null) = 3223; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3224 break;
3225 }
3226 return false;
3227 }
3228
3229 if (!advancePastSyntaxParsedFunction(syntaxParser)) {
3230 return false;
3231 }
3232
3233 // Update the end position of the parse node.
3234 (*funNode)->pn_pos.end = anyChars.currentToken().pos.end;
3235
3236 // Append possible Annex B function box only upon successfully parsing.
3237 if (tryAnnexB) {
3238 if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
3239 return false;
3240 }
3241 }
3242
3243 return true;
3244 } while (false);
3245
3246 // We failed to do a syntax parse above, so do the full parse.
3247 FunctionNodeType innerFunc;
3248 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)
3249 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)
3250 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)
3251 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)
3252 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)
3253 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)
;
3254
3255 *funNode = innerFunc;
3256 return true;
3257}
3258
3259template <typename Unit>
3260bool Parser<SyntaxParseHandler, Unit>::trySyntaxParseInnerFunction(
3261 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
3262 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3263 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3264 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3265 Directives inheritedDirectives, Directives* newDirectives) {
3266 // This is already a syntax parser, so just parse the inner function.
3267 FunctionNodeType innerFunc;
3268 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)
3269 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)
3270 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)
3271 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)
3272 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)
3273 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)
;
3274
3275 *funNode = innerFunc;
3276 return true;
3277}
3278
3279template <class ParseHandler, typename Unit>
3280inline bool GeneralParser<ParseHandler, Unit>::trySyntaxParseInnerFunction(
3281 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
3282 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3283 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3284 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3285 Directives inheritedDirectives, Directives* newDirectives) {
3286 return asFinalParser()->trySyntaxParseInnerFunction(
3287 funNode, explicitName, flags, toStringStart, inHandling, yieldHandling,
3288 kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives,
3289 newDirectives);
3290}
3291
3292template <class ParseHandler, typename Unit>
3293typename ParseHandler::FunctionNodeResult
3294GeneralParser<ParseHandler, Unit>::innerFunctionForFunctionBox(
3295 FunctionNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
3296 InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
3297 Directives* newDirectives) {
3298 // Note that it is possible for outerpc != this->pc_, as we may be
3299 // attempting to syntax parse an inner function from an outer full
3300 // parser. In that case, outerpc is a SourceParseContext from the full parser
3301 // instead of the current top of the stack of the syntax parser.
3302
3303 // Push a new ParseContext.
3304 SourceParseContext funpc(this, funbox, newDirectives);
3305 if (!funpc.init()) {
3306 return errorResult();
3307 }
3308
3309 if (!functionFormalParametersAndBody(inHandling, yieldHandling, &funNode,
3310 kind)) {
3311 return errorResult();
3312 }
3313
3314 if (!leaveInnerFunction(outerpc)) {
3315 return errorResult();
3316 }
3317
3318 return funNode;
3319}
3320
3321template <class ParseHandler, typename Unit>
3322typename ParseHandler::FunctionNodeResult
3323GeneralParser<ParseHandler, Unit>::innerFunction(
3324 FunctionNodeType funNode, ParseContext* outerpc,
3325 TaggedParserAtomIndex explicitName, FunctionFlags flags,
3326 uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
3327 FunctionSyntaxKind kind, GeneratorKind generatorKind,
3328 FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
3329 Directives* newDirectives) {
3330 // Note that it is possible for outerpc != this->pc_, as we may be
3331 // attempting to syntax parse an inner function from an outer full
3332 // parser. In that case, outerpc is a SourceParseContext from the full parser
3333 // instead of the current top of the stack of the syntax parser.
3334
3335 FunctionBox* funbox =
3336 newFunctionBox(funNode, explicitName, flags, toStringStart,
3337 inheritedDirectives, generatorKind, asyncKind);
3338 if (!funbox) {
3339 return errorResult();
3340 }
3341 funbox->initWithEnclosingParseContext(outerpc, kind);
3342
3343 FunctionNodeType innerFunc;
3344 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)
3345 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)
3346 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)
;
3347
3348 // Append possible Annex B function box only upon successfully parsing.
3349 if (tryAnnexB) {
3350 if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
3351 return errorResult();
3352 }
3353 }
3354
3355 return innerFunc;
3356}
3357
3358template <class ParseHandler, typename Unit>
3359bool GeneralParser<ParseHandler, Unit>::appendToCallSiteObj(
3360 CallSiteNodeType callSiteObj) {
3361 Node cookedNode;
3362 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)
;
3363
3364 auto atom = tokenStream.getRawTemplateStringAtom();
3365 if (!atom) {
3366 return false;
3367 }
3368 NameNodeType rawNode;
3369 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)
3370 false)do { auto parserTryVarTempResult_ = (handler_.newTemplateStringLiteral
(atom, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (rawNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3371
3372 handler_.addToCallSiteObject(callSiteObj, rawNode, cookedNode);
3373 return true;
3374}
3375
3376template <typename Unit>
3377FullParseHandler::FunctionNodeResult
3378Parser<FullParseHandler, Unit>::standaloneLazyFunction(
3379 CompilationInput& input, uint32_t toStringStart, bool strict,
3380 GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
3381 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"
, 3381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 3381; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3382
3383 FunctionSyntaxKind syntaxKind = input.functionSyntaxKind();
3384 FunctionNodeType funNode;
3385 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)
;
3386
3387 TaggedParserAtomIndex displayAtom =
3388 this->getCompilationState().previousParseCache.displayAtom();
3389
3390 Directives directives(strict);
3391 FunctionBox* funbox =
3392 newFunctionBox(funNode, displayAtom, input.functionFlags(), toStringStart,
3393 directives, generatorKind, asyncKind);
3394 if (!funbox) {
3395 return errorResult();
3396 }
3397 const ScriptStencilExtra& funExtra =
3398 this->getCompilationState().previousParseCache.funExtra();
3399 funbox->initFromLazyFunction(
3400 funExtra, this->getCompilationState().scopeContext, syntaxKind);
3401 if (funbox->useMemberInitializers()) {
3402 funbox->setMemberInitializers(funExtra.memberInitializers());
3403 }
3404
3405 Directives newDirectives = directives;
3406 SourceParseContext funpc(this, funbox, &newDirectives);
3407 if (!funpc.init()) {
3408 return errorResult();
3409 }
3410
3411 // Our tokenStream has no current token, so funNode's position is garbage.
3412 // Substitute the position of the first token in our source. If the
3413 // function is a not-async arrow, use TokenStream::SlashIsRegExp to keep
3414 // verifyConsistentModifier from complaining (we will use
3415 // TokenStream::SlashIsRegExp in functionArguments).
3416 Modifier modifier = (input.functionFlags().isArrow() &&
3417 asyncKind == FunctionAsyncKind::SyncFunction)
3418 ? TokenStream::SlashIsRegExp
3419 : TokenStream::SlashIsDiv;
3420 if (!tokenStream.peekTokenPos(&funNode->pn_pos, modifier)) {
3421 return errorResult();
3422 }
3423
3424 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
3425
3426 if (funbox->isSyntheticFunction()) {
3427 // Currently default class constructors are the only synthetic function that
3428 // supports delazification.
3429 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"
, 3429); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isClassConstructor()"
")"); do { *((volatile int*)__null) = 3429; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3430 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"
, 3430); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->extent().toStringStart == funbox->extent().sourceStart"
")"); do { *((volatile int*)__null) = 3430; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3431
3432 HasHeritage hasHeritage = funbox->isDerivedClassConstructor()
3433 ? HasHeritage::Yes
3434 : HasHeritage::No;
3435 TokenPos synthesizedBodyPos(funbox->extent().toStringStart,
3436 funbox->extent().toStringEnd);
3437
3438 // Reset pos() to the `class` keyword for predictable results.
3439 tokenStream.consumeKnownToken(TokenKind::Class);
3440
3441 if (!this->synthesizeConstructorBody(synthesizedBodyPos, hasHeritage,
3442 funNode, funbox)) {
3443 return errorResult();
3444 }
3445 } else {
3446 if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
3447 syntaxKind)) {
3448 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"
, 3448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "directives == newDirectives"
")"); do { *((volatile int*)__null) = 3448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3449 return errorResult();
3450 }
3451 }
3452
3453 if (!CheckParseTree(this->fc_, alloc_, funNode)) {
3454 return errorResult();
3455 }
3456
3457 ParseNode* node = funNode;
3458 // Don't constant-fold inside "use asm" code, as this could create a parse
3459 // tree that doesn't type-check as asm.js.
3460 if (!pc_->useAsmOrInsideUseAsm()) {
3461 if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
3462 &handler_)) {
3463 return errorResult();
3464 }
3465 }
3466 funNode = &node->as<FunctionNode>();
3467
3468 return funNode;
3469}
3470
3471void ParserBase::setFunctionEndFromCurrentToken(FunctionBox* funbox) const {
3472 if (compilationState_.isInitialStencil()) {
3473 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"
, 3473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type != TokenKind::Eof"
")"); do { *((volatile int*)__null) = 3473; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3474 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"
, 3474); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type < TokenKind::Limit"
")"); do { *((volatile int*)__null) = 3474; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3475 funbox->setEnd(anyChars.currentToken().pos.end);
3476 } else {
3477 // If we're delazifying an arrow function with expression body and
3478 // the expression is also a function, we arrive here immediately after
3479 // skipping the function by Parser::skipLazyInnerFunction.
3480 //
3481 // a => b => c
3482 // ^
3483 // |
3484 // we're here
3485 //
3486 // In that case, the current token's type field is either Limit or
3487 // poisoned.
3488 // We shouldn't read the value if it's poisoned.
3489 // See TokenStreamSpecific<Unit, AnyCharsAccess>::advance and
3490 // mfbt/MemoryChecking.h for more details.
3491 //
3492 // Also, in delazification, the FunctionBox should already have the
3493 // correct extent, and we shouldn't overwrite it here.
3494 // See ScriptStencil variant of PerHandlerParser::newFunctionBox.
3495#if !defined(MOZ_ASAN) && !defined(MOZ_MSAN) && !defined(MOZ_VALGRIND)
3496 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"
, 3496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type != TokenKind::Eof"
")"); do { *((volatile int*)__null) = 3496; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3497#endif
3498 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"
, 3498); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->extent().sourceEnd == anyChars.currentToken().pos.end"
")"); do { *((volatile int*)__null) = 3498; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3499 }
3500}
3501
3502template <class ParseHandler, typename Unit>
3503bool GeneralParser<ParseHandler, Unit>::functionFormalParametersAndBody(
3504 InHandling inHandling, YieldHandling yieldHandling,
3505 FunctionNodeType* funNode, FunctionSyntaxKind kind,
3506 const Maybe<uint32_t>& parameterListEnd /* = Nothing() */,
3507 bool isStandaloneFunction /* = false */) {
3508 // Given a properly initialized parse context, try to parse an actual
3509 // function without concern for conversion to strict mode, use of lazy
3510 // parsing and such.
3511
3512 FunctionBox* funbox = pc_->functionBox();
3513
3514 if (kind == FunctionSyntaxKind::ClassConstructor ||
3515 kind == FunctionSyntaxKind::DerivedClassConstructor) {
3516 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
3517 return false;
3518 }
3519#ifdef ENABLE_DECORATORS
3520 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
3521 dot_instanceExtraInitializers_())) {
3522 return false;
3523 }
3524#endif
3525 }
3526
3527 // See below for an explanation why arrow function parameters and arrow
3528 // function bodies are parsed with different yield/await settings.
3529 {
3530 AwaitHandling awaitHandling =
3531 kind == FunctionSyntaxKind::StaticClassBlock ? AwaitIsDisallowed
3532 : (funbox->isAsync() ||
3533 (kind == FunctionSyntaxKind::Arrow && awaitIsKeyword()))
3534 ? AwaitIsKeyword
3535 : AwaitIsName;
3536 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this, awaitHandling);
3537 AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(
3538 this, funbox->isAsync());
3539 if (!functionArguments(yieldHandling, kind, *funNode)) {
3540 return false;
3541 }
3542 }
3543
3544 Maybe<ParseContext::VarScope> varScope;
3545 if (funbox->hasParameterExprs) {
3546 varScope.emplace(this);
3547 if (!varScope->init(pc_)) {
3548 return false;
3549 }
3550 } else {
3551 pc_->functionScope().useAsVarScope(pc_);
3552 }
3553
3554 if (kind == FunctionSyntaxKind::Arrow) {
3555 TokenKind tt;
3556 if (!tokenStream.peekTokenSameLine(&tt)) {
3557 return false;
3558 }
3559
3560 if (tt == TokenKind::Eol) {
3561 error(JSMSG_UNEXPECTED_TOKEN,
3562 "'=>' on the same line after an argument list",
3563 TokenKindToDesc(tt));
3564 return false;
3565 }
3566 if (tt != TokenKind::Arrow) {
3567 error(JSMSG_BAD_ARROW_ARGS);
3568 return false;
3569 }
3570 tokenStream.consumeKnownToken(TokenKind::Arrow);
3571 }
3572
3573 // When parsing something for new Function() we have to make sure to
3574 // only treat a certain part of the source as a parameter list.
3575 if (parameterListEnd.isSome() && parameterListEnd.value() != pos().begin) {
3576 error(JSMSG_UNEXPECTED_PARAMLIST_END);
3577 return false;
3578 }
3579
3580 // Parse the function body.
3581 FunctionBodyType bodyType = StatementListBody;
3582 TokenKind tt;
3583 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
3584 return false;
3585 }
3586 uint32_t openedPos = 0;
3587 if (tt != TokenKind::LeftCurly) {
3588 if (kind != FunctionSyntaxKind::Arrow) {
3589 error(JSMSG_CURLY_BEFORE_BODY);
3590 return false;
3591 }
3592
3593 anyChars.ungetToken();
3594 bodyType = ExpressionBody;
3595 funbox->setHasExprBody();
3596 } else {
3597 openedPos = pos().begin;
3598 }
3599
3600 // Arrow function parameters inherit yieldHandling from the enclosing
3601 // context, but the arrow body doesn't. E.g. in |(a = yield) => yield|,
3602 // |yield| in the parameters is either a name or keyword, depending on
3603 // whether the arrow function is enclosed in a generator function or not.
3604 // Whereas the |yield| in the function body is always parsed as a name.
3605 // The same goes when parsing |await| in arrow functions.
3606 YieldHandling bodyYieldHandling = GetYieldHandling(pc_->generatorKind());
3607 AwaitHandling bodyAwaitHandling = GetAwaitHandling(pc_->asyncKind());
3608 bool inheritedStrict = pc_->sc()->strict();
3609 LexicalScopeNodeType body;
3610 {
3611 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this,
3612 bodyAwaitHandling);
3613 AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(this,
3614 false);
3615 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)
3616 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)
3617 false)do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
;
3618 }
3619
3620 // Revalidate the function name when we transitioned to strict mode.
3621 if ((kind == FunctionSyntaxKind::Statement ||
3622 kind == FunctionSyntaxKind::Expression) &&
3623 funbox->explicitName() && !inheritedStrict && pc_->sc()->strict()) {
3624 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"
, 3626); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3626; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
3625 "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"
, 3626); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3626; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
3626 "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"
, 3626); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3626; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
3627
3628 auto propertyName = funbox->explicitName();
3629 YieldHandling nameYieldHandling;
3630 if (kind == FunctionSyntaxKind::Expression) {
3631 // Named lambda has binding inside it.
3632 nameYieldHandling = bodyYieldHandling;
3633 } else {
3634 // Otherwise YieldHandling cannot be checked at this point
3635 // because of different context.
3636 // It should already be checked before this point.
3637 nameYieldHandling = YieldIsName;
3638 }
3639
3640 // We already use the correct await-handling at this point, therefore
3641 // we don't need call AutoAwaitIsKeyword here.
3642
3643 uint32_t nameOffset = handler_.getFunctionNameOffset(*funNode, anyChars);
3644 if (!checkBindingIdentifier(propertyName, nameOffset, nameYieldHandling)) {
3645 return false;
3646 }
3647 }
3648
3649 if (bodyType == StatementListBody) {
3650 // Cannot use mustMatchToken here because of internal compiler error on
3651 // gcc 6.4.0, with linux 64 SM hazard build.
3652 TokenKind actual;
3653 if (!tokenStream.getToken(&actual, TokenStream::SlashIsRegExp)) {
3654 return false;
3655 }
3656 if (actual != TokenKind::RightCurly) {
3657 reportMissingClosing(JSMSG_CURLY_AFTER_BODY, JSMSG_CURLY_OPENED,
3658 openedPos);
3659 return false;
3660 }
3661
3662 setFunctionEndFromCurrentToken(funbox);
3663 } else {
3664 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"
, 3664); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == FunctionSyntaxKind::Arrow"
")"); do { *((volatile int*)__null) = 3664; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3665
3666 if (anyChars.hadError()) {
3667 return false;
3668 }
3669
3670 setFunctionEndFromCurrentToken(funbox);
3671
3672 if (kind == FunctionSyntaxKind::Statement) {
3673 if (!matchOrInsertSemicolon()) {
3674 return false;
3675 }
3676 }
3677 }
3678
3679 if (IsMethodDefinitionKind(kind) && pc_->superScopeNeedsHomeObject()) {
3680 funbox->setNeedsHomeObject();
3681 }
3682
3683 if (!finishFunction(isStandaloneFunction)) {
3684 return false;
3685 }
3686
3687 handler_.setEndPosition(body, pos().begin);
3688 handler_.setEndPosition(*funNode, pos().end);
3689 handler_.setFunctionBody(*funNode, body);
3690
3691 return true;
3692}
3693
3694template <class ParseHandler, typename Unit>
3695typename ParseHandler::FunctionNodeResult
3696GeneralParser<ParseHandler, Unit>::functionStmt(uint32_t toStringStart,
3697 YieldHandling yieldHandling,
3698 DefaultHandling defaultHandling,
3699 FunctionAsyncKind asyncKind) {
3700 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"
, 3700); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 3700; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3701
3702 // In sloppy mode, Annex B.3.2 allows labelled function declarations.
3703 // Otherwise it's a parse error.
3704 ParseContext::Statement* declaredInStmt = pc_->innermostStatement();
3705 if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
3706 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"
, 3707); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc_->sc()->strict()"
") (" "labeled functions shouldn't be parsed in strict mode"
")"); do { *((volatile int*)__null) = 3707; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3707 "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"
, 3707); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc_->sc()->strict()"
") (" "labeled functions shouldn't be parsed in strict mode"
")"); do { *((volatile int*)__null) = 3707; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3708
3709 // Find the innermost non-label statement. Report an error if it's
3710 // unbraced: functions can't appear in it. Otherwise the statement
3711 // (or its absence) determines the scope the function's bound in.
3712 while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
3713 declaredInStmt = declaredInStmt->enclosing();
3714 }
3715
3716 if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
3717 error(JSMSG_SLOPPY_FUNCTION_LABEL);
3718 return errorResult();
3719 }
3720 }
3721
3722 TokenKind tt;
3723 if (!tokenStream.getToken(&tt)) {
3724 return errorResult();
3725 }
3726
3727 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
3728 if (tt == TokenKind::Mul) {
3729 generatorKind = GeneratorKind::Generator;
3730 if (!tokenStream.getToken(&tt)) {
3731 return errorResult();
3732 }
3733 }
3734
3735 TaggedParserAtomIndex name;
3736 if (TokenKindIsPossibleIdentifier(tt)) {
3737 name = bindingIdentifier(yieldHandling);
3738 if (!name) {
3739 return errorResult();
3740 }
3741 } else if (defaultHandling == AllowDefaultName) {
3742 name = TaggedParserAtomIndex::WellKnown::default_();
3743 anyChars.ungetToken();
3744 } else {
3745 /* Unnamed function expressions are forbidden in statement context. */
3746 error(JSMSG_UNNAMED_FUNCTION_STMT);
3747 return errorResult();
3748 }
3749
3750 // Note the declared name and check for early errors.
3751 DeclarationKind kind;
3752 if (declaredInStmt) {
3753 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"
, 3753); AnnotateMozCrashReason("MOZ_ASSERT" "(" "declaredInStmt->kind() != StatementKind::Label"
")"); do { *((volatile int*)__null) = 3753; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3754 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"
, 3754); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StatementKindIsBraced(declaredInStmt->kind())"
")"); do { *((volatile int*)__null) = 3754; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3755
3756 kind =
3757 (!pc_->sc()->strict() && generatorKind == GeneratorKind::NotGenerator &&
3758 asyncKind == FunctionAsyncKind::SyncFunction)
3759 ? DeclarationKind::SloppyLexicalFunction
3760 : DeclarationKind::LexicalFunction;
3761 } else {
3762 kind = pc_->atModuleLevel() ? DeclarationKind::ModuleBodyLevelFunction
3763 : DeclarationKind::BodyLevelFunction;
3764 }
3765
3766 if (!noteDeclaredName(name, kind, pos())) {
3767 return errorResult();
3768 }
3769
3770 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
3771 FunctionNodeType funNode;
3772 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)
;
3773
3774 // Under sloppy mode, try Annex B.3.3 semantics. If making an additional
3775 // 'var' binding of the same name does not throw an early error, do so.
3776 // This 'var' binding would be assigned the function object when its
3777 // declaration is reached, not at the start of the block.
3778 //
3779 // This semantics is implemented upon Scope exit in
3780 // Scope::propagateAndMarkAnnexBFunctionBoxes.
3781 bool tryAnnexB = kind == DeclarationKind::SloppyLexicalFunction;
3782
3783 YieldHandling newYieldHandling = GetYieldHandling(generatorKind);
3784 return functionDefinition(funNode, toStringStart, InAllowed, newYieldHandling,
3785 name, syntaxKind, generatorKind, asyncKind,
3786 tryAnnexB);
3787}
3788
3789template <class ParseHandler, typename Unit>
3790typename ParseHandler::FunctionNodeResult
3791GeneralParser<ParseHandler, Unit>::functionExpr(uint32_t toStringStart,
3792 InvokedPrediction invoked,
3793 FunctionAsyncKind asyncKind) {
3794 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"
, 3794); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 3794; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3795
3796 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(
3797 this, GetAwaitHandling(asyncKind));
3798 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
3799 TokenKind tt;
3800 if (!tokenStream.getToken(&tt)) {
3801 return errorResult();
3802 }
3803
3804 if (tt == TokenKind::Mul) {
3805 generatorKind = GeneratorKind::Generator;
3806 if (!tokenStream.getToken(&tt)) {
3807 return errorResult();
3808 }
3809 }
3810
3811 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
3812
3813 TaggedParserAtomIndex name;
3814 if (TokenKindIsPossibleIdentifier(tt)) {
3815 name = bindingIdentifier(yieldHandling);
3816 if (!name) {
3817 return errorResult();
3818 }
3819 } else {
3820 anyChars.ungetToken();
3821 }
3822
3823 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Expression;
3824 FunctionNodeType funNode;
3825 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)
;
3826
3827 if (invoked) {
3828 funNode = handler_.setLikelyIIFE(funNode);
3829 }
3830
3831 return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
3832 name, syntaxKind, generatorKind, asyncKind);
3833}
3834
3835/*
3836 * Return true if this node, known to be an unparenthesized string literal
3837 * that never contain escape sequences, could be the string of a directive in a
3838 * Directive Prologue. Directive strings never contain escape sequences or line
3839 * continuations.
3840 */
3841static inline bool IsUseStrictDirective(const TokenPos& pos,
3842 TaggedParserAtomIndex atom) {
3843 // the length of "use strict", including quotation.
3844 static constexpr size_t useStrictLength = 12;
3845 return atom == TaggedParserAtomIndex::WellKnown::use_strict_() &&
3846 pos.begin + useStrictLength == pos.end;
3847}
3848static inline bool IsUseAsmDirective(const TokenPos& pos,
3849 TaggedParserAtomIndex atom) {
3850 // the length of "use asm", including quotation.
3851 static constexpr size_t useAsmLength = 9;
3852 return atom == TaggedParserAtomIndex::WellKnown::use_asm_() &&
3853 pos.begin + useAsmLength == pos.end;
3854}
3855
3856template <typename Unit>
3857bool Parser<SyntaxParseHandler, Unit>::asmJS(ListNodeType list) {
3858 // While asm.js could technically be validated and compiled during syntax
3859 // parsing, we have no guarantee that some later JS wouldn't abort the
3860 // syntax parse and cause us to re-parse (and re-compile) the asm.js module.
3861 // For simplicity, unconditionally abort the syntax parse when "use asm" is
3862 // encountered so that asm.js is always validated/compiled exactly once
3863 // during a full parse.
3864 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3864); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 3864; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
3865 return false;
3866}
3867
3868template <typename Unit>
3869bool Parser<FullParseHandler, Unit>::asmJS(ListNodeType list) {
3870 // Disable syntax parsing in anything nested inside the asm.js module.
3871 disableSyntaxParser();
3872
3873 // We should be encountering the "use asm" directive for the first time; if
3874 // the directive is already, we must have failed asm.js validation and we're
3875 // reparsing. In that case, don't try to validate again. A non-null
3876 // newDirectives means we're not in a normal function.
3877 if (!pc_->newDirectives || pc_->newDirectives->asmJS()) {
3878 return true;
3879 }
3880
3881 // If there is no ScriptSource, then we are doing a non-compiling parse and
3882 // so we shouldn't (and can't, without a ScriptSource) compile.
3883 if (ss == nullptr) {
3884 return true;
3885 }
3886
3887 pc_->functionBox()->useAsm = true;
3888
3889 // Attempt to validate and compile this asm.js module. On success, the
3890 // tokenStream has been advanced to the closing }. On failure, the
3891 // tokenStream is in an indeterminate state and we must reparse the
3892 // function from the beginning. Reparsing is triggered by marking that a
3893 // new directive has been encountered and returning 'false'.
3894 bool validated;
3895 if (!CompileAsmJS(this->fc_, this->parserAtoms(), *this, list, &validated)) {
3896 return false;
3897 }
3898 if (!validated) {
3899 pc_->newDirectives->setAsmJS();
3900 return false;
3901 }
3902
3903 return true;
3904}
3905
3906template <class ParseHandler, typename Unit>
3907inline bool GeneralParser<ParseHandler, Unit>::asmJS(ListNodeType list) {
3908 return asFinalParser()->asmJS(list);
3909}
3910
3911/*
3912 * Recognize Directive Prologue members and directives. Assuming |pn| is a
3913 * candidate for membership in a directive prologue, recognize directives and
3914 * set |pc_|'s flags accordingly. If |pn| is indeed part of a prologue, set its
3915 * |prologue| flag.
3916 *
3917 * Note that the following is a strict mode function:
3918 *
3919 * function foo() {
3920 * "blah" // inserted semi colon
3921 * "blurgh"
3922 * "use\x20loose"
3923 * "use strict"
3924 * }
3925 *
3926 * That is, even though "use\x20loose" can never be a directive, now or in the
3927 * future (because of the hex escape), the Directive Prologue extends through it
3928 * to the "use strict" statement, which is indeed a directive.
3929 */
3930template <class ParseHandler, typename Unit>
3931bool GeneralParser<ParseHandler, Unit>::maybeParseDirective(
3932 ListNodeType list, Node possibleDirective, bool* cont) {
3933 TokenPos directivePos;
3934 TaggedParserAtomIndex directive =
3935 handler_.isStringExprStatement(possibleDirective, &directivePos);
3936
3937 *cont = !!directive;
3938 if (!*cont) {
3939 return true;
3940 }
3941
3942 if (IsUseStrictDirective(directivePos, directive)) {
3943 // Functions with non-simple parameter lists (destructuring,
3944 // default or rest parameters) must not contain a "use strict"
3945 // directive.
3946 if (pc_->isFunctionBox()) {
3947 FunctionBox* funbox = pc_->functionBox();
3948 if (!funbox->hasSimpleParameterList()) {
3949 const char* parameterKind = funbox->hasDestructuringArgs
3950 ? "destructuring"
3951 : funbox->hasParameterExprs ? "default"
3952 : "rest";
3953 errorAt(directivePos.begin, JSMSG_STRICT_NON_SIMPLE_PARAMS,
3954 parameterKind);
3955 return false;
3956 }
3957 }
3958
3959 // We're going to be in strict mode. Note that this scope explicitly
3960 // had "use strict";
3961 pc_->sc()->setExplicitUseStrict();
3962 if (!pc_->sc()->strict()) {
3963 // Some strict mode violations can appear before a Use Strict Directive
3964 // is applied. (See the |DeprecatedContent| enum initializers.) These
3965 // violations can manifest in two ways.
3966 //
3967 // First, the violation can appear *before* the Use Strict Directive.
3968 // Numeric literals (and therefore octal literals) can only precede a
3969 // Use Strict Directive if this function's parameter list is not simple,
3970 // but we reported an error for non-simple parameter lists above, so
3971 // octal literals present no issue. But octal escapes and \8 and \9 can
3972 // appear in the directive prologue before a Use Strict Directive:
3973 //
3974 // function f()
3975 // {
3976 // "hell\157 world"; // octal escape
3977 // "\8"; "\9"; // NonOctalDecimalEscape
3978 // "use strict"; // retroactively makes all the above errors
3979 // }
3980 //
3981 // Second, the violation can appear *after* the Use Strict Directive but
3982 // *before* the directive is recognized as terminated. This only
3983 // happens when a directive is terminated by ASI, and the next token
3984 // contains a violation:
3985 //
3986 // function a()
3987 // {
3988 // "use strict" // ASI
3989 // 0755;
3990 // }
3991 // function b()
3992 // {
3993 // "use strict" // ASI
3994 // "hell\157 world";
3995 // }
3996 // function c()
3997 // {
3998 // "use strict" // ASI
3999 // "\8";
4000 // }
4001 //
4002 // We note such violations when tokenizing. Then, if a violation has
4003 // been observed at the time a "use strict" is applied, we report the
4004 // error.
4005 switch (anyChars.sawDeprecatedContent()) {
4006 case DeprecatedContent::None:
4007 break;
4008 case DeprecatedContent::OctalLiteral:
4009 error(JSMSG_DEPRECATED_OCTAL_LITERAL);
4010 return false;
4011 case DeprecatedContent::OctalEscape:
4012 error(JSMSG_DEPRECATED_OCTAL_ESCAPE);
4013 return false;
4014 case DeprecatedContent::EightOrNineEscape:
4015 error(JSMSG_DEPRECATED_EIGHT_OR_NINE_ESCAPE);
4016 return false;
4017 }
4018
4019 pc_->sc()->setStrictScript();
4020 }
4021 } else if (IsUseAsmDirective(directivePos, directive)) {
4022 if (pc_->isFunctionBox()) {
4023 return asmJS(list);
4024 }
4025 return warningAt(directivePos.begin, JSMSG_USE_ASM_DIRECTIVE_FAIL);
4026 }
4027 return true;
4028}
4029
4030template <class ParseHandler, typename Unit>
4031typename ParseHandler::ListNodeResult
4032GeneralParser<ParseHandler, Unit>::statementList(YieldHandling yieldHandling) {
4033 AutoCheckRecursionLimit recursion(this->fc_);
4034 if (!recursion.check(this->fc_)) {
4035 return errorResult();
4036 }
4037
4038 ListNodeType stmtList;
4039 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)
;
4040
4041 bool canHaveDirectives = pc_->atBodyLevel();
4042 if (canHaveDirectives) {
4043 // Clear flags for deprecated content that might have been seen in an
4044 // enclosing context.
4045 anyChars.clearSawDeprecatedContent();
4046 }
4047
4048 bool canHaveHashbangComment = pc_->atTopLevel();
4049 if (canHaveHashbangComment) {
4050 tokenStream.consumeOptionalHashbangComment();
4051 }
4052
4053 bool afterReturn = false;
4054 bool warnedAboutStatementsAfterReturn = false;
4055 uint32_t statementBegin = 0;
4056 for (;;) {
4057 TokenKind tt = TokenKind::Eof;
4058 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
4059 if (anyChars.isEOF()) {
4060 isUnexpectedEOF_ = true;
4061 }
4062 return errorResult();
4063 }
4064 if (tt == TokenKind::Eof || tt == TokenKind::RightCurly) {
4065 TokenPos pos;
4066 if (!tokenStream.peekTokenPos(&pos, TokenStream::SlashIsRegExp)) {
4067 return errorResult();
4068 }
4069 handler_.setListEndPosition(stmtList, pos);
4070 break;
4071 }
4072 if (afterReturn) {
4073 if (!tokenStream.peekOffset(&statementBegin,
4074 TokenStream::SlashIsRegExp)) {
4075 return errorResult();
4076 }
4077 }
4078 auto nextResult = statementListItem(yieldHandling, canHaveDirectives);
4079 if (nextResult.isErr()) {
4080 if (anyChars.isEOF()) {
4081 isUnexpectedEOF_ = true;
4082 }
4083 return errorResult();
4084 }
4085 Node next = nextResult.unwrap();
4086 if (!warnedAboutStatementsAfterReturn) {
4087 if (afterReturn) {
4088 if (!handler_.isStatementPermittedAfterReturnStatement(next)) {
4089 if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
4090 return errorResult();
4091 }
4092
4093 warnedAboutStatementsAfterReturn = true;
4094 }
4095 } else if (handler_.isReturnStatement(next)) {
4096 afterReturn = true;
4097 }
4098 }
4099
4100 if (canHaveDirectives) {
4101 if (!maybeParseDirective(stmtList, next, &canHaveDirectives)) {
4102 return errorResult();
4103 }
4104 }
4105
4106 handler_.addStatementToList(stmtList, next);
4107 }
4108
4109 return stmtList;
4110}
4111
4112template <class ParseHandler, typename Unit>
4113typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::condition(
4114 InHandling inHandling, YieldHandling yieldHandling) {
4115 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_COND)) {
4116 return errorResult();
4117 }
4118
4119 Node pn;
4120 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)
;
4121
4122 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_COND)) {
4123 return errorResult();
4124 }
4125
4126 return pn;
4127}
4128
4129template <class ParseHandler, typename Unit>
4130bool GeneralParser<ParseHandler, Unit>::matchLabel(
4131 YieldHandling yieldHandling, TaggedParserAtomIndex* labelOut) {
4132 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"
, 4132); AnnotateMozCrashReason("MOZ_ASSERT" "(" "labelOut != nullptr"
")"); do { *((volatile int*)__null) = 4132; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4133 TokenKind tt = TokenKind::Eof;
4134 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
4135 return false;
4136 }
4137
4138 if (TokenKindIsPossibleIdentifier(tt)) {
4139 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
4140
4141 *labelOut = labelIdentifier(yieldHandling);
4142 if (!*labelOut) {
4143 return false;
4144 }
4145 } else {
4146 *labelOut = TaggedParserAtomIndex::null();
4147 }
4148 return true;
4149}
4150
4151template <class ParseHandler, typename Unit>
4152GeneralParser<ParseHandler, Unit>::PossibleError::PossibleError(
4153 GeneralParser<ParseHandler, Unit>& parser)
4154 : parser_(parser) {}
4155
4156template <class ParseHandler, typename Unit>
4157typename GeneralParser<ParseHandler, Unit>::PossibleError::Error&
4158GeneralParser<ParseHandler, Unit>::PossibleError::error(ErrorKind kind) {
4159 if (kind == ErrorKind::Expression) {
4160 return exprError_;
4161 }
4162 if (kind == ErrorKind::Destructuring) {
4163 return destructuringError_;
4164 }
4165 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"
, 4165); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ErrorKind::DestructuringWarning"
")"); do { *((volatile int*)__null) = 4165; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4166 return destructuringWarning_;
4167}
4168
4169template <class ParseHandler, typename Unit>
4170void GeneralParser<ParseHandler, Unit>::PossibleError::setResolved(
4171 ErrorKind kind) {
4172 error(kind).state_ = ErrorState::None;
4173}
4174
4175template <class ParseHandler, typename Unit>
4176bool GeneralParser<ParseHandler, Unit>::PossibleError::hasError(
4177 ErrorKind kind) {
4178 return error(kind).state_ == ErrorState::Pending;
4179}
4180
4181template <class ParseHandler, typename Unit>
4182bool GeneralParser<ParseHandler,
4183 Unit>::PossibleError::hasPendingDestructuringError() {
4184 return hasError(ErrorKind::Destructuring);
4185}
4186
4187template <class ParseHandler, typename Unit>
4188void GeneralParser<ParseHandler, Unit>::PossibleError::setPending(
4189 ErrorKind kind, const TokenPos& pos, unsigned errorNumber) {
4190 // Don't overwrite a previously recorded error.
4191 if (hasError(kind)) {
4192 return;
4193 }
4194
4195 // If we report an error later, we'll do it from the position where we set
4196 // the state to pending.
4197 Error& err = error(kind);
4198 err.offset_ = pos.begin;
4199 err.errorNumber_ = errorNumber;
4200 err.state_ = ErrorState::Pending;
4201}
4202
4203template <class ParseHandler, typename Unit>
4204void GeneralParser<ParseHandler, Unit>::PossibleError::
4205 setPendingDestructuringErrorAt(const TokenPos& pos, unsigned errorNumber) {
4206 setPending(ErrorKind::Destructuring, pos, errorNumber);
4207}
4208
4209template <class ParseHandler, typename Unit>
4210void GeneralParser<ParseHandler, Unit>::PossibleError::
4211 setPendingDestructuringWarningAt(const TokenPos& pos,
4212 unsigned errorNumber) {
4213 setPending(ErrorKind::DestructuringWarning, pos, errorNumber);
4214}
4215
4216template <class ParseHandler, typename Unit>
4217void GeneralParser<ParseHandler, Unit>::PossibleError::
4218 setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber) {
4219 setPending(ErrorKind::Expression, pos, errorNumber);
4220}
4221
4222template <class ParseHandler, typename Unit>
4223bool GeneralParser<ParseHandler, Unit>::PossibleError::checkForError(
4224 ErrorKind kind) {
4225 if (!hasError(kind)) {
4226 return true;
4227 }
4228
4229 Error& err = error(kind);
4230 parser_.errorAt(err.offset_, err.errorNumber_);
4231 return false;
4232}
4233
4234template <class ParseHandler, typename Unit>
4235bool GeneralParser<ParseHandler,
4236 Unit>::PossibleError::checkForDestructuringErrorOrWarning() {
4237 // Clear pending expression error, because we're definitely not in an
4238 // expression context.
4239 setResolved(ErrorKind::Expression);
4240
4241 // Report any pending destructuring error.
4242 return checkForError(ErrorKind::Destructuring);
4243}
4244
4245template <class ParseHandler, typename Unit>
4246bool GeneralParser<ParseHandler,
4247 Unit>::PossibleError::checkForExpressionError() {
4248 // Clear pending destructuring error, because we're definitely not
4249 // in a destructuring context.
4250 setResolved(ErrorKind::Destructuring);
4251 setResolved(ErrorKind::DestructuringWarning);
4252
4253 // Report any pending expression error.
4254 return checkForError(ErrorKind::Expression);
4255}
4256
4257template <class ParseHandler, typename Unit>
4258void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorTo(
4259 ErrorKind kind, PossibleError* other) {
4260 if (hasError(kind) && !other->hasError(kind)) {
4261 Error& err = error(kind);
4262 Error& otherErr = other->error(kind);
4263 otherErr.offset_ = err.offset_;
4264 otherErr.errorNumber_ = err.errorNumber_;
4265 otherErr.state_ = err.state_;
4266 }
4267}
4268
4269template <class ParseHandler, typename Unit>
4270void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorsTo(
4271 PossibleError* other) {
4272 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"
, 4272); AnnotateMozCrashReason("MOZ_ASSERT" "(" "other" ")")
; do { *((volatile int*)__null) = 4272; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4273 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"
, 4273); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this != other"
")"); do { *((volatile int*)__null) = 4273; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4274 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"
, 4276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4276
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
4275 "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"
, 4276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4276
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
4276 "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"
, 4276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4276
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
4277
4278 transferErrorTo(ErrorKind::Destructuring, other);
4279 transferErrorTo(ErrorKind::Expression, other);
4280}
4281
4282template <class ParseHandler, typename Unit>
4283typename ParseHandler::BinaryNodeResult
4284GeneralParser<ParseHandler, Unit>::bindingInitializer(
4285 Node lhs, DeclarationKind kind, YieldHandling yieldHandling) {
4286 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"
, 4286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assign)"
")"); do { *((volatile int*)__null) = 4286; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4287
4288 if (kind == DeclarationKind::FormalParameter) {
4289 pc_->functionBox()->hasParameterExprs = true;
4290 }
4291
4292 Node rhs;
4293 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)
;
4294
4295 BinaryNodeType assign;
4296 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)
4297 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)
;
4298
4299 return assign;
4300}
4301
4302template <class ParseHandler, typename Unit>
4303typename ParseHandler::NameNodeResult
4304GeneralParser<ParseHandler, Unit>::bindingIdentifier(
4305 DeclarationKind kind, YieldHandling yieldHandling) {
4306 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
4307 if (!name) {
4308 return errorResult();
4309 }
4310
4311 NameNodeType binding;
4312 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)
;
4313 if (!noteDeclaredName(name, kind, pos())) {
4314 return errorResult();
4315 }
4316
4317 return binding;
4318}
4319
4320template <class ParseHandler, typename Unit>
4321typename ParseHandler::NodeResult
4322GeneralParser<ParseHandler, Unit>::bindingIdentifierOrPattern(
4323 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4324 if (tt == TokenKind::LeftBracket) {
4325 return arrayBindingPattern(kind, yieldHandling);
4326 }
4327
4328 if (tt == TokenKind::LeftCurly) {
4329 return objectBindingPattern(kind, yieldHandling);
4330 }
4331
4332 if (!TokenKindIsPossibleIdentifierName(tt)) {
4333 error(JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
4334 return errorResult();
4335 }
4336
4337 return bindingIdentifier(kind, yieldHandling);
4338}
4339
4340template <class ParseHandler, typename Unit>
4341typename ParseHandler::ListNodeResult
4342GeneralParser<ParseHandler, Unit>::objectBindingPattern(
4343 DeclarationKind kind, YieldHandling yieldHandling) {
4344 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"
, 4344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4344; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4345
4346 AutoCheckRecursionLimit recursion(this->fc_);
4347 if (!recursion.check(this->fc_)) {
4348 return errorResult();
4349 }
4350
4351 uint32_t begin = pos().begin;
4352 ListNodeType literal;
4353 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)
;
4354
4355 Maybe<DeclarationKind> declKind = Some(kind);
4356 TaggedParserAtomIndex propAtom;
4357 for (;;) {
4358 TokenKind tt;
4359 if (!tokenStream.peekToken(&tt)) {
4360 return errorResult();
4361 }
4362 if (tt == TokenKind::RightCurly) {
4363 break;
4364 }
4365
4366 if (tt == TokenKind::TripleDot) {
4367 tokenStream.consumeKnownToken(TokenKind::TripleDot);
4368 uint32_t begin = pos().begin;
4369
4370 TokenKind tt;
4371 if (!tokenStream.getToken(&tt)) {
4372 return errorResult();
4373 }
4374
4375 if (!TokenKindIsPossibleIdentifierName(tt)) {
4376 error(JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
4377 return errorResult();
4378 }
4379
4380 NameNodeType inner;
4381 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)
;
4382
4383 if (!handler_.addSpreadProperty(literal, begin, inner)) {
4384 return errorResult();
4385 }
4386 } else {
4387 TokenPos namePos = anyChars.nextToken().pos;
4388
4389 PropertyType propType;
4390 Node propName;
4391 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)
4392 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)
4393 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)
;
4394
4395 if (propType == PropertyType::Normal) {
4396 // Handle e.g., |var {p: x} = o| and |var {p: x=0} = o|.
4397
4398 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
4399 return errorResult();
4400 }
4401
4402 Node binding;
4403 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)
4404 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)
;
4405
4406 bool hasInitializer;
4407 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
4408 TokenStream::SlashIsRegExp)) {
4409 return errorResult();
4410 }
4411
4412 Node bindingExpr;
4413 if (hasInitializer) {
4414 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)
4415 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)
;
4416 } else {
4417 bindingExpr = binding;
4418 }
4419
4420 if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
4421 return errorResult();
4422 }
4423 } else if (propType == PropertyType::Shorthand) {
4424 // Handle e.g., |var {x, y} = o| as destructuring shorthand
4425 // for |var {x: x, y: y} = o|.
4426 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"
, 4426); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(tt)"
")"); do { *((volatile int*)__null) = 4426; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4427
4428 NameNodeType binding;
4429 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)
;
4430
4431 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
4432 binding)) {
4433 return errorResult();
4434 }
4435 } else if (propType == PropertyType::CoverInitializedName) {
4436 // Handle e.g., |var {x=1, y=2} = o| as destructuring
4437 // shorthand with default values.
4438 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"
, 4438); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(tt)"
")"); do { *((volatile int*)__null) = 4438; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4439
4440 NameNodeType binding;
4441 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)
;
4442
4443 tokenStream.consumeKnownToken(TokenKind::Assign);
4444
4445 BinaryNodeType bindingExpr;
4446 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)
4447 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)
;
4448
4449 if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
4450 return errorResult();
4451 }
4452 } else {
4453 errorAt(namePos.begin, JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
4454 return errorResult();
4455 }
4456 }
4457
4458 bool matched;
4459 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
4460 TokenStream::SlashIsInvalid)) {
4461 return errorResult();
4462 }
4463 if (!matched) {
4464 break;
4465 }
4466 if (tt == TokenKind::TripleDot) {
4467 error(JSMSG_REST_WITH_COMMA);
4468 return errorResult();
4469 }
4470 }
4471
4472 if (!mustMatchToken(TokenKind::RightCurly, [this, begin](TokenKind actual) {
4473 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST, JSMSG_CURLY_OPENED,
4474 begin);
4475 })) {
4476 return errorResult();
4477 }
4478
4479 handler_.setEndPosition(literal, pos().end);
4480 return literal;
4481}
4482
4483template <class ParseHandler, typename Unit>
4484typename ParseHandler::ListNodeResult
4485GeneralParser<ParseHandler, Unit>::arrayBindingPattern(
4486 DeclarationKind kind, YieldHandling yieldHandling) {
4487 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"
, 4487); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 4487; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4488
4489 AutoCheckRecursionLimit recursion(this->fc_);
4490 if (!recursion.check(this->fc_)) {
4491 return errorResult();
4492 }
4493
4494 uint32_t begin = pos().begin;
4495 ListNodeType literal;
4496 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)
;
4497
4498 uint32_t index = 0;
4499 for (;; index++) {
4500 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
4501 error(JSMSG_ARRAY_INIT_TOO_BIG);
4502 return errorResult();
4503 }
4504
4505 TokenKind tt;
4506 if (!tokenStream.getToken(&tt)) {
4507 return errorResult();
4508 }
4509
4510 if (tt == TokenKind::RightBracket) {
4511 anyChars.ungetToken();
4512 break;
4513 }
4514
4515 if (tt == TokenKind::Comma) {
4516 if (!handler_.addElision(literal, pos())) {
4517 return errorResult();
4518 }
4519 } else if (tt == TokenKind::TripleDot) {
4520 uint32_t begin = pos().begin;
4521
4522 TokenKind tt;
4523 if (!tokenStream.getToken(&tt)) {
4524 return errorResult();
4525 }
4526
4527 Node inner;
4528 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)
;
4529
4530 if (!handler_.addSpreadElement(literal, begin, inner)) {
4531 return errorResult();
4532 }
4533 } else {
4534 Node binding;
4535 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)
;
4536
4537 bool hasInitializer;
4538 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
4539 TokenStream::SlashIsRegExp)) {
4540 return errorResult();
4541 }
4542
4543 Node element;
4544 if (hasInitializer) {
4545 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)
;
4546 } else {
4547 element = binding;
4548 }
4549
4550 handler_.addArrayElement(literal, element);
4551 }
4552
4553 if (tt != TokenKind::Comma) {
4554 // If we didn't already match TokenKind::Comma in above case.
4555 bool matched;
4556 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
4557 TokenStream::SlashIsRegExp)) {
4558 return errorResult();
4559 }
4560 if (!matched) {
4561 break;
4562 }
4563
4564 if (tt == TokenKind::TripleDot) {
4565 error(JSMSG_REST_WITH_COMMA);
4566 return errorResult();
4567 }
4568 }
4569 }
4570
4571 if (!mustMatchToken(TokenKind::RightBracket, [this, begin](TokenKind actual) {
4572 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
4573 JSMSG_BRACKET_OPENED, begin);
4574 })) {
4575 return errorResult();
4576 }
4577
4578 handler_.setEndPosition(literal, pos().end);
4579 return literal;
4580}
4581
4582template <class ParseHandler, typename Unit>
4583typename ParseHandler::NodeResult
4584GeneralParser<ParseHandler, Unit>::destructuringDeclaration(
4585 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4586 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"
, 4586); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 4586; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4587 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"
, 4587); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly"
")"); do { *((volatile int*)__null) = 4587; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4588
4589 if (tt == TokenKind::LeftBracket) {
4590 return arrayBindingPattern(kind, yieldHandling);
4591 }
4592 return objectBindingPattern(kind, yieldHandling);
4593}
4594
4595template <class ParseHandler, typename Unit>
4596typename ParseHandler::NodeResult
4597GeneralParser<ParseHandler, Unit>::destructuringDeclarationWithoutYieldOrAwait(
4598 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4599 uint32_t startYieldOffset = pc_->lastYieldOffset;
4600 uint32_t startAwaitOffset = pc_->lastAwaitOffset;
4601
4602 Node res;
4603 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)
;
4604
4605 if (pc_->lastYieldOffset != startYieldOffset) {
4606 errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
4607 return errorResult();
4608 }
4609 if (pc_->lastAwaitOffset != startAwaitOffset) {
4610 errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
4611 return errorResult();
4612 }
4613 return res;
4614}
4615
4616template <class ParseHandler, typename Unit>
4617typename ParseHandler::LexicalScopeNodeResult
4618GeneralParser<ParseHandler, Unit>::blockStatement(YieldHandling yieldHandling,
4619 unsigned errorNumber) {
4620 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"
, 4620); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4620; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4621 uint32_t openedPos = pos().begin;
4622
4623 ParseContext::Statement stmt(pc_, StatementKind::Block);
4624 ParseContext::Scope scope(this);
4625 if (!scope.init(pc_)) {
4626 return errorResult();
4627 }
4628
4629 ListNodeType list;
4630 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)
;
4631
4632 if (!mustMatchToken(TokenKind::RightCurly, [this, errorNumber,
4633 openedPos](TokenKind actual) {
4634 this->reportMissingClosing(errorNumber, JSMSG_CURLY_OPENED, openedPos);
4635 })) {
4636 return errorResult();
4637 }
4638
4639 return finishLexicalScope(scope, list);
4640}
4641
4642template <class ParseHandler, typename Unit>
4643typename ParseHandler::NodeResult
4644GeneralParser<ParseHandler, Unit>::expressionAfterForInOrOf(
4645 ParseNodeKind forHeadKind, YieldHandling yieldHandling) {
4646 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"
, 4647); AnnotateMozCrashReason("MOZ_ASSERT" "(" "forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 4647; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4647 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"
, 4647); AnnotateMozCrashReason("MOZ_ASSERT" "(" "forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 4647; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4648 if (forHeadKind == ParseNodeKind::ForOf) {
4649 return assignExpr(InAllowed, yieldHandling, TripledotProhibited);
4650 }
4651
4652 return expr(InAllowed, yieldHandling, TripledotProhibited);
4653}
4654
4655template <class ParseHandler, typename Unit>
4656typename ParseHandler::NodeResult
4657GeneralParser<ParseHandler, Unit>::declarationPattern(
4658 DeclarationKind declKind, TokenKind tt, bool initialDeclaration,
4659 YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
4660 Node* forInOrOfExpression) {
4661 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"
, 4662); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4662; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4662 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"
, 4662); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4662; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4663
4664 Node pattern;
4665 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)
;
4666
4667 if (initialDeclaration && forHeadKind) {
4668 bool isForIn, isForOf;
4669 if (!matchInOrOf(&isForIn, &isForOf)) {
4670 return errorResult();
4671 }
4672
4673 if (isForIn) {
4674 *forHeadKind = ParseNodeKind::ForIn;
4675 } else if (isForOf) {
4676 *forHeadKind = ParseNodeKind::ForOf;
4677 } else {
4678 *forHeadKind = ParseNodeKind::ForHead;
4679 }
4680
4681 if (*forHeadKind != ParseNodeKind::ForHead) {
4682 MOZ_TRY_VAR(*forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4683 expressionAfterForInOrOf(*forHeadKind, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4684
4685 return pattern;
4686 }
4687 }
4688
4689 if (!mustMatchToken(TokenKind::Assign, JSMSG_BAD_DESTRUCT_DECL)) {
4690 return errorResult();
4691 }
4692
4693 Node init;
4694 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)
4695 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)
;
4696
4697 return handler_.newAssignment(ParseNodeKind::AssignExpr, pattern, init);
4698}
4699
4700template <class ParseHandler, typename Unit>
4701typename ParseHandler::AssignmentNodeResult
4702GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
4703 NameNodeType binding, DeclarationKind declKind, bool initialDeclaration,
4704 YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
4705 Node* forInOrOfExpression) {
4706 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"
, 4706); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assign)"
")"); do { *((volatile int*)__null) = 4706; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4707
4708 uint32_t initializerOffset;
4709 if (!tokenStream.peekOffset(&initializerOffset, TokenStream::SlashIsRegExp)) {
4710 return errorResult();
4711 }
4712
4713 Node initializer;
4714 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)
4715 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)
;
4716
4717 if (forHeadKind && initialDeclaration) {
4718 bool isForIn, isForOf;
4719 if (!matchInOrOf(&isForIn, &isForOf)) {
4720 return errorResult();
4721 }
4722
4723 // An initialized declaration can't appear in a for-of:
4724 //
4725 // for (var/let/const x = ... of ...); // BAD
4726 if (isForOf) {
4727 errorAt(initializerOffset, JSMSG_OF_AFTER_FOR_LOOP_DECL);
4728 return errorResult();
4729 }
4730
4731 if (isForIn) {
4732 // Lexical declarations in for-in loops can't be initialized:
4733 //
4734 // for (let/const x = ... in ...); // BAD
4735 if (DeclarationKindIsLexical(declKind)) {
4736 errorAt(initializerOffset, JSMSG_IN_AFTER_LEXICAL_FOR_DECL);
4737 return errorResult();
4738 }
4739
4740 // This leaves only initialized for-in |var| declarations. ES6
4741 // forbids these; later ES un-forbids in non-strict mode code.
4742 *forHeadKind = ParseNodeKind::ForIn;
4743 if (!strictModeErrorAt(initializerOffset,
4744 JSMSG_INVALID_FOR_IN_DECL_WITH_INIT)) {
4745 return errorResult();
4746 }
4747
4748 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4749 *forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4750 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)
;
4751 } else {
4752 *forHeadKind = ParseNodeKind::ForHead;
4753 }
4754 }
4755
4756 return handler_.finishInitializerAssignment(binding, initializer);
4757}
4758
4759template <class ParseHandler, typename Unit>
4760typename ParseHandler::NodeResult
4761GeneralParser<ParseHandler, Unit>::declarationName(DeclarationKind declKind,
4762 TokenKind tt,
4763 bool initialDeclaration,
4764 YieldHandling yieldHandling,
4765 ParseNodeKind* forHeadKind,
4766 Node* forInOrOfExpression) {
4767 // Anything other than possible identifier is an error.
4768 if (!TokenKindIsPossibleIdentifier(tt)) {
4769 error(JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
4770 return errorResult();
4771 }
4772
4773 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
4774 if (!name) {
4775 return errorResult();
4776 }
4777
4778 NameNodeType binding;
4779 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)
;
4780
4781 TokenPos namePos = pos();
4782
4783 // The '=' context after a variable name in a declaration is an opportunity
4784 // for ASI, and thus for the next token to start an ExpressionStatement:
4785 //
4786 // var foo // VariableDeclaration
4787 // /bar/g; // ExpressionStatement
4788 //
4789 // Therefore get the token here with SlashIsRegExp.
4790 bool matched;
4791 if (!tokenStream.matchToken(&matched, TokenKind::Assign,
4792 TokenStream::SlashIsRegExp)) {
4793 return errorResult();
4794 }
4795
4796 Node declaration;
4797 if (matched) {
4798 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)
4799 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)
4800 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)
4801 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)
;
4802 } else {
4803 declaration = binding;
4804
4805 if (initialDeclaration && forHeadKind) {
4806 bool isForIn, isForOf;
4807 if (!matchInOrOf(&isForIn, &isForOf)) {
4808 return errorResult();
4809 }
4810
4811 if (isForIn) {
4812 *forHeadKind = ParseNodeKind::ForIn;
4813#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
4814 if (declKind == DeclarationKind::Using ||
4815 declKind == DeclarationKind::AwaitUsing) {
4816 errorAt(namePos.begin, JSMSG_NO_IN_WITH_USING);
4817 return errorResult();
4818 }
4819#endif
4820 } else if (isForOf) {
4821 *forHeadKind = ParseNodeKind::ForOf;
4822 } else {
4823 *forHeadKind = ParseNodeKind::ForHead;
4824 }
4825 }
4826
4827 if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
4828 MOZ_TRY_VAR(*forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4829 expressionAfterForInOrOf(*forHeadKind, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4830 } else {
4831 // Normal const declarations, and const declarations in for(;;)
4832 // heads, must be initialized.
4833 if (declKind == DeclarationKind::Const) {
4834 errorAt(namePos.begin, JSMSG_BAD_CONST_DECL);
4835 return errorResult();
4836 }
4837#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
4838 if (declKind == DeclarationKind::Using ||
4839 declKind == DeclarationKind::AwaitUsing) {
4840 errorAt(namePos.begin, JSMSG_BAD_USING_DECL);
4841 return errorResult();
4842 }
4843#endif
4844 }
4845 }
4846
4847 // Note the declared name after knowing whether or not we are in a for-of
4848 // loop, due to special early error semantics in Annex B.3.5.
4849 if (!noteDeclaredName(name, declKind, namePos)) {
4850 return errorResult();
4851 }
4852
4853 return declaration;
4854}
4855
4856template <class ParseHandler, typename Unit>
4857typename ParseHandler::DeclarationListNodeResult
4858GeneralParser<ParseHandler, Unit>::declarationList(
4859 YieldHandling yieldHandling, ParseNodeKind kind,
4860 ParseNodeKind* forHeadKind /* = nullptr */,
4861 Node* forInOrOfExpression /* = nullptr */) {
4862 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 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4863 kind == ParseNodeKind::ConstDecldo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4864#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENTdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4865 || kind == ParseNodeKind::UsingDecl ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4866 kind == ParseNodeKind::AwaitUsingDecldo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4867#endifdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4868 )do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4869
4870 DeclarationKind declKind;
4871 switch (kind) {
4872 case ParseNodeKind::VarStmt:
4873 declKind = DeclarationKind::Var;
4874 break;
4875 case ParseNodeKind::ConstDecl:
4876 declKind = DeclarationKind::Const;
4877 break;
4878 case ParseNodeKind::LetDecl:
4879 declKind = DeclarationKind::Let;
4880 break;
4881#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
4882 case ParseNodeKind::UsingDecl:
4883 declKind = DeclarationKind::Using;
4884 break;
4885 case ParseNodeKind::AwaitUsingDecl:
4886 declKind = DeclarationKind::AwaitUsing;
4887 break;
4888#endif
4889 default:
4890 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"
, 4890); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown declaration kind"
")"); do { *((volatile int*)__null) = 4890; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4891 }
4892
4893 DeclarationListNodeType decl;
4894 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)
;
4895
4896 bool moreDeclarations;
4897 bool initialDeclaration = true;
4898 do {
4899 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"
, 4900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*forHeadKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 4900; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
4900 *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"
, 4900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*forHeadKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 4900; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4901
4902 TokenKind tt;
4903 if (!tokenStream.getToken(&tt)) {
4904 return errorResult();
4905 }
4906
4907 Node binding;
4908 if (tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly) {
4909 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)
4910 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)
4911 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)
;
4912 } else {
4913 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)
4914 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)
4915 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)
;
4916 }
4917
4918 handler_.addList(decl, binding);
4919
4920 // If we have a for-in/of loop, the above call matches the entirety
4921 // of the loop head (up to the closing parenthesis).
4922 if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
4923 break;
4924 }
4925
4926 initialDeclaration = false;
4927
4928 if (!tokenStream.matchToken(&moreDeclarations, TokenKind::Comma,
4929 TokenStream::SlashIsRegExp)) {
4930 return errorResult();
4931 }
4932 } while (moreDeclarations);
4933
4934 return decl;
4935}
4936
4937template <class ParseHandler, typename Unit>
4938typename ParseHandler::DeclarationListNodeResult
4939GeneralParser<ParseHandler, Unit>::lexicalDeclaration(
4940 YieldHandling yieldHandling, DeclarationKind kind) {
4941 MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Letdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4942#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENTdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4943 || kind == DeclarationKind::Using ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4944 kind == DeclarationKind::AwaitUsingdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4945#endifdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4946 )do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4947
4948 if (options().selfHostingMode) {
4949 error(JSMSG_SELFHOSTED_LEXICAL);
4950 return errorResult();
4951 }
4952
4953 /*
4954 * Parse body-level lets without a new block object. ES6 specs
4955 * that an execution environment's initial lexical environment
4956 * is the VariableEnvironment, i.e., body-level lets are in
4957 * the same environment record as vars.
4958 *
4959 * However, they cannot be parsed exactly as vars, as ES6
4960 * requires that uninitialized lets throw ReferenceError on use.
4961 *
4962 * See 8.1.1.1.6 and the note in 13.2.1.
4963 */
4964 DeclarationListNodeType decl;
4965 ParseNodeKind pnk;
4966 switch (kind) {
4967 case DeclarationKind::Const:
4968 pnk = ParseNodeKind::ConstDecl;
4969 break;
4970#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
4971 case DeclarationKind::Using:
4972 pnk = ParseNodeKind::UsingDecl;
4973 break;
4974 case DeclarationKind::AwaitUsing:
4975 pnk = ParseNodeKind::AwaitUsingDecl;
4976 break;
4977#endif
4978 case DeclarationKind::Let:
4979 pnk = ParseNodeKind::LetDecl;
4980 break;
4981 default:
4982 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"
, 4982); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected node kind"
")"); do { *((volatile int*)__null) = 4982; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4983 }
4984 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)
;
4985 if (!matchOrInsertSemicolon()) {
4986 return errorResult();
4987 }
4988
4989 return decl;
4990}
4991
4992template <class ParseHandler, typename Unit>
4993typename ParseHandler::NameNodeResult
4994GeneralParser<ParseHandler, Unit>::moduleExportName() {
4995 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"
, 4995); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::String"
")"); do { *((volatile int*)__null) = 4995; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4996 TaggedParserAtomIndex name = anyChars.currentToken().atom();
4997 if (!this->parserAtoms().isModuleExportName(name)) {
4998 error(JSMSG_UNPAIRED_SURROGATE_EXPORT);
4999 return errorResult();
5000 }
5001 return handler_.newStringLiteral(name, pos());
5002}
5003
5004template <class ParseHandler, typename Unit>
5005bool GeneralParser<ParseHandler, Unit>::withClause(ListNodeType attributesSet) {
5006 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"
, 5007); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 5007; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5007 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"
, 5007); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 5007; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5008
5009 if (!options().importAttributes()) {
5010 error(JSMSG_IMPORT_ASSERTIONS_NOT_SUPPORTED);
5011 return false;
5012 }
5013
5014 if (!abortIfSyntaxParser()) {
5015 return false;
5016 }
5017
5018 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_AFTER_ASSERT)) {
5019 return false;
5020 }
5021
5022 // Handle the form |... assert {}|
5023 TokenKind token;
5024 if (!tokenStream.getToken(&token)) {
5025 return false;
5026 }
5027 if (token == TokenKind::RightCurly) {
5028 return true;
5029 }
5030
5031 js::HashSet<TaggedParserAtomIndex, TaggedParserAtomIndexHasher,
5032 js::SystemAllocPolicy>
5033 usedAssertionKeys;
5034
5035 for (;;) {
5036 TaggedParserAtomIndex keyName;
5037 if (TokenKindIsPossibleIdentifierName(token)) {
5038 keyName = anyChars.currentName();
5039 } else if (token == TokenKind::String) {
5040 keyName = anyChars.currentToken().atom();
5041 } else {
5042 error(JSMSG_ASSERT_KEY_EXPECTED);
5043 return false;
5044 }
5045
5046 auto p = usedAssertionKeys.lookupForAdd(keyName);
5047 if (p) {
5048 UniqueChars str = this->parserAtoms().toPrintableString(keyName);
5049 if (!str) {
5050 ReportOutOfMemory(this->fc_);
5051 return false;
5052 }
5053 error(JSMSG_DUPLICATE_ASSERT_KEY, str.get());
5054 return false;
5055 }
5056 if (!usedAssertionKeys.add(p, keyName)) {
5057 ReportOutOfMemory(this->fc_);
5058 return false;
5059 }
5060
5061 NameNodeType keyNode;
5062 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)
;
5063
5064 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_ASSERT_KEY)) {
5065 return false;
5066 }
5067 if (!mustMatchToken(TokenKind::String, JSMSG_ASSERT_STRING_LITERAL)) {
5068 return false;
5069 }
5070
5071 NameNodeType valueNode;
5072 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)
;
5073
5074 BinaryNodeType importAttributeNode;
5075 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)
5076 handler_.newImportAttribute(keyNode, valueNode),do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
5077 false)do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5078
5079 handler_.addList(attributesSet, importAttributeNode);
5080
5081 if (!tokenStream.getToken(&token)) {
5082 return false;
5083 }
5084 if (token == TokenKind::Comma) {
5085 if (!tokenStream.getToken(&token)) {
5086 return false;
5087 }
5088 }
5089 if (token == TokenKind::RightCurly) {
5090 break;
5091 }
5092 }
5093
5094 return true;
5095}
5096
5097template <class ParseHandler, typename Unit>
5098bool GeneralParser<ParseHandler, Unit>::namedImports(
5099 ListNodeType importSpecSet) {
5100 if (!abortIfSyntaxParser()) {
5101 return false;
5102 }
5103
5104 while (true) {
5105 // Handle the forms |import {} from 'a'| and
5106 // |import { ..., } from 'a'| (where ... is non empty), by
5107 // escaping the loop early if the next token is }.
5108 TokenKind tt;
5109 if (!tokenStream.getToken(&tt)) {
5110 return false;
5111 }
5112
5113 if (tt == TokenKind::RightCurly) {
5114 break;
5115 }
5116
5117 TaggedParserAtomIndex importName;
5118 NameNodeType importNameNode = null();
5119 if (TokenKindIsPossibleIdentifierName(tt)) {
5120 importName = anyChars.currentName();
5121 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)
;
5122 } else if (tt == TokenKind::String) {
5123 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)
;
5124 } else {
5125 error(JSMSG_NO_IMPORT_NAME);
5126 return false;
5127 }
5128
5129 bool matched;
5130 if (!tokenStream.matchToken(&matched, TokenKind::As)) {
5131 return false;
5132 }
5133
5134 if (matched) {
5135 TokenKind afterAs;
5136 if (!tokenStream.getToken(&afterAs)) {
5137 return false;
5138 }
5139
5140 if (!TokenKindIsPossibleIdentifierName(afterAs)) {
5141 error(JSMSG_NO_BINDING_NAME);
5142 return false;
5143 }
5144 } else {
5145 // String export names can't refer to local bindings.
5146 if (tt == TokenKind::String) {
5147 error(JSMSG_AS_AFTER_STRING);
5148 return false;
5149 }
5150
5151 // Keywords cannot be bound to themselves, so an import name
5152 // that is a keyword is a syntax error if it is not followed
5153 // by the keyword 'as'.
5154 // See the ImportSpecifier production in ES6 section 15.2.2.
5155 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"
, 5155); AnnotateMozCrashReason("MOZ_ASSERT" "(" "importName"
")"); do { *((volatile int*)__null) = 5155; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5156 if (IsKeyword(importName)) {
5157 error(JSMSG_AS_AFTER_RESERVED_WORD, ReservedWordToCharZ(importName));
5158 return false;
5159 }
5160 }
5161
5162 TaggedParserAtomIndex bindingAtom = importedBinding();
5163 if (!bindingAtom) {
5164 return false;
5165 }
5166
5167 NameNodeType bindingName;
5168 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)
;
5169 if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
5170 return false;
5171 }
5172
5173 BinaryNodeType importSpec;
5174 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)
5175 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)
;
5176
5177 handler_.addList(importSpecSet, importSpec);
5178
5179 TokenKind next;
5180 if (!tokenStream.getToken(&next)) {
5181 return false;
5182 }
5183
5184 if (next == TokenKind::RightCurly) {
5185 break;
5186 }
5187
5188 if (next != TokenKind::Comma) {
5189 error(JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
5190 return false;
5191 }
5192 }
5193
5194 return true;
5195}
5196
5197template <class ParseHandler, typename Unit>
5198bool GeneralParser<ParseHandler, Unit>::namespaceImport(
5199 ListNodeType importSpecSet) {
5200 if (!abortIfSyntaxParser()) {
5201 return false;
5202 }
5203
5204 if (!mustMatchToken(TokenKind::As, JSMSG_AS_AFTER_IMPORT_STAR)) {
5205 return false;
5206 }
5207 uint32_t begin = pos().begin;
5208
5209 if (!mustMatchToken(TokenKindIsPossibleIdentifierName,
5210 JSMSG_NO_BINDING_NAME)) {
5211 return false;
5212 }
5213
5214 // Namespace imports are not indirect bindings but lexical
5215 // definitions that hold a module namespace object. They are treated
5216 // as const variables which are initialized during the
5217 // ModuleInstantiate step.
5218 TaggedParserAtomIndex bindingName = importedBinding();
5219 if (!bindingName) {
5220 return false;
5221 }
5222 NameNodeType bindingNameNode;
5223 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)
;
5224 if (!noteDeclaredName(bindingName, DeclarationKind::Const, pos())) {
5225 return false;
5226 }
5227
5228 // The namespace import name is currently required to live on the
5229 // environment.
5230 pc_->varScope().lookupDeclaredName(bindingName)->value()->setClosedOver();
5231
5232 UnaryNodeType importSpec;
5233 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)
5234 handler_.newImportNamespaceSpec(begin, bindingNameNode),do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5235 false)do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5236
5237 handler_.addList(importSpecSet, importSpec);
5238
5239 return true;
5240}
5241
5242template <class ParseHandler, typename Unit>
5243typename ParseHandler::BinaryNodeResult
5244GeneralParser<ParseHandler, Unit>::importDeclaration() {
5245 if (!abortIfSyntaxParser()) {
5246 return errorResult();
5247 }
5248
5249 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"
, 5249); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 5249; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5250
5251 if (!pc_->atModuleLevel()) {
5252 error(JSMSG_IMPORT_DECL_AT_TOP_LEVEL);
5253 return errorResult();
5254 }
5255
5256 uint32_t begin = pos().begin;
5257 TokenKind tt;
5258 if (!tokenStream.getToken(&tt)) {
5259 return errorResult();
5260 }
5261
5262 ListNodeType importSpecSet;
5263 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)
5264 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)
;
5265
5266 if (tt == TokenKind::String) {
5267 // Handle the form |import 'a'| by leaving the list empty. This is
5268 // equivalent to |import {} from 'a'|.
5269 handler_.setEndPosition(importSpecSet, pos().begin);
5270 } else {
5271 if (tt == TokenKind::LeftCurly) {
5272 if (!namedImports(importSpecSet)) {
5273 return errorResult();
5274 }
5275 } else if (tt == TokenKind::Mul) {
5276 if (!namespaceImport(importSpecSet)) {
5277 return errorResult();
5278 }
5279 } else if (TokenKindIsPossibleIdentifierName(tt)) {
5280 // Handle the form |import a from 'b'|, by adding a single import
5281 // specifier to the list, with 'default' as the import name and
5282 // 'a' as the binding name. This is equivalent to
5283 // |import { default as a } from 'b'|.
5284 NameNodeType importName;
5285 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)
5286 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)
;
5287
5288 TaggedParserAtomIndex bindingAtom = importedBinding();
5289 if (!bindingAtom) {
5290 return errorResult();
5291 }
5292
5293 NameNodeType bindingName;
5294 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)
;
5295
5296 if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
5297 return errorResult();
5298 }
5299
5300 BinaryNodeType importSpec;
5301 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)
;
5302
5303 handler_.addList(importSpecSet, importSpec);
5304
5305 if (!tokenStream.peekToken(&tt)) {
5306 return errorResult();
5307 }
5308
5309 if (tt == TokenKind::Comma) {
5310 tokenStream.consumeKnownToken(tt);
5311 if (!tokenStream.getToken(&tt)) {
5312 return errorResult();
5313 }
5314
5315 if (tt == TokenKind::LeftCurly) {
5316 if (!namedImports(importSpecSet)) {
5317 return errorResult();
5318 }
5319 } else if (tt == TokenKind::Mul) {
5320 if (!namespaceImport(importSpecSet)) {
5321 return errorResult();
5322 }
5323 } else {
5324 error(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT);
5325 return errorResult();
5326 }
5327 }
5328 } else {
5329 error(JSMSG_DECLARATION_AFTER_IMPORT);
5330 return errorResult();
5331 }
5332
5333 if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_IMPORT_CLAUSE)) {
5334 return errorResult();
5335 }
5336
5337 if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
5338 return errorResult();
5339 }
5340 }
5341
5342 NameNodeType moduleSpec;
5343 MOZ_TRY_VAR(moduleSpec, stringLiteral())do { auto mozTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleSpec) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5344
5345 // The `assert` keyword has a [no LineTerminator here] production before it in
5346 // the grammar -- `with` does not. We need to handle this distinction.
5347 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
5348 return errorResult();
5349 }
5350
5351 // `with` may have an EOL prior, so peek the next token and replace
5352 // EOL if the next token is `with`.
5353 if (tt == TokenKind::Eol) {
5354 // Doing a regular peek won't produce Eol, but the actual next token.
5355 TokenKind peekedToken;
5356 if (!tokenStream.peekToken(&peekedToken, TokenStream::SlashIsRegExp)) {
5357 return errorResult();
5358 }
5359
5360 if (peekedToken == TokenKind::With) {
5361 tt = TokenKind::With;
5362 }
5363 }
5364
5365 ListNodeType importAttributeList;
5366 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)
5367 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)
;
5368
5369 if (tt == TokenKind::With) {
5370 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
5371
5372 if (!withClause(importAttributeList)) {
5373 return errorResult();
5374 }
5375 }
5376
5377 if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
5378 return errorResult();
5379 }
5380
5381 BinaryNodeType moduleRequest;
5382 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)
5383 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)
5384 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)
;
5385
5386 BinaryNodeType node;
5387 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)
5388 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)
;
5389 if (!processImport(node)) {
5390 return errorResult();
5391 }
5392
5393 return node;
5394}
5395
5396template <class ParseHandler, typename Unit>
5397inline typename ParseHandler::NodeResult
5398GeneralParser<ParseHandler, Unit>::importDeclarationOrImportExpr(
5399 YieldHandling yieldHandling) {
5400 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"
, 5400); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 5400; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5401
5402 TokenKind tt;
5403 if (!tokenStream.peekToken(&tt)) {
5404 return errorResult();
5405 }
5406
5407 if (tt == TokenKind::Dot || tt == TokenKind::LeftParen) {
5408 return expressionStatement(yieldHandling);
5409 }
5410
5411 return importDeclaration();
5412}
5413
5414template <typename Unit>
5415bool Parser<FullParseHandler, Unit>::checkExportedName(
5416 TaggedParserAtomIndex exportName) {
5417 switch (pc_->sc()->asModuleContext()->builder.noteExportedName(exportName)) {
5418 case ModuleBuilder::NoteExportedNameResult::Success:
5419 return true;
5420 case ModuleBuilder::NoteExportedNameResult::OutOfMemory:
5421 return false;
5422 case ModuleBuilder::NoteExportedNameResult::AlreadyDeclared:
5423 break;
5424 }
5425
5426 UniqueChars str = this->parserAtoms().toPrintableString(exportName);
5427 if (!str) {
5428 ReportOutOfMemory(this->fc_);
5429 return false;
5430 }
5431
5432 error(JSMSG_DUPLICATE_EXPORT_NAME, str.get());
5433 return false;
5434}
5435
5436template <typename Unit>
5437inline bool Parser<SyntaxParseHandler, Unit>::checkExportedName(
5438 TaggedParserAtomIndex exportName) {
5439 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5439); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5439; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5440 return false;
5441}
5442
5443template <class ParseHandler, typename Unit>
5444inline bool GeneralParser<ParseHandler, Unit>::checkExportedName(
5445 TaggedParserAtomIndex exportName) {
5446 return asFinalParser()->checkExportedName(exportName);
5447}
5448
5449template <typename Unit>
5450bool Parser<FullParseHandler, Unit>::checkExportedNamesForArrayBinding(
5451 ListNode* array) {
5452 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"
, 5452); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array->isKind(ParseNodeKind::ArrayExpr)"
")"); do { *((volatile int*)__null) = 5452; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5453
5454 for (ParseNode* node : array->contents()) {
5455 if (node->isKind(ParseNodeKind::Elision)) {
5456 continue;
5457 }
5458
5459 ParseNode* binding;
5460 if (node->isKind(ParseNodeKind::Spread)) {
5461 binding = node->as<UnaryNode>().kid();
5462 } else if (node->isKind(ParseNodeKind::AssignExpr)) {
5463 binding = node->as<AssignmentNode>().left();
5464 } else {
5465 binding = node;
5466 }
5467
5468 if (!checkExportedNamesForDeclaration(binding)) {
5469 return false;
5470 }
5471 }
5472
5473 return true;
5474}
5475
5476template <typename Unit>
5477inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForArrayBinding(
5478 ListNodeType array) {
5479 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5479); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5479; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5480 return false;
5481}
5482
5483template <class ParseHandler, typename Unit>
5484inline bool
5485GeneralParser<ParseHandler, Unit>::checkExportedNamesForArrayBinding(
5486 ListNodeType array) {
5487 return asFinalParser()->checkExportedNamesForArrayBinding(array);
5488}
5489
5490template <typename Unit>
5491bool Parser<FullParseHandler, Unit>::checkExportedNamesForObjectBinding(
5492 ListNode* obj) {
5493 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"
, 5493); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->isKind(ParseNodeKind::ObjectExpr)"
")"); do { *((volatile int*)__null) = 5493; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5494
5495 for (ParseNode* node : obj->contents()) {
5496 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"
, 5499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5497 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"
, 5499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5498 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"
, 5499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5499 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"
, 5499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5500
5501 ParseNode* target;
5502 if (node->isKind(ParseNodeKind::Spread)) {
5503 target = node->as<UnaryNode>().kid();
5504 } else {
5505 if (node->isKind(ParseNodeKind::MutateProto)) {
5506 target = node->as<UnaryNode>().kid();
5507 } else {
5508 target = node->as<BinaryNode>().right();
5509 }
5510
5511 if (target->isKind(ParseNodeKind::AssignExpr)) {
5512 target = target->as<AssignmentNode>().left();
5513 }
5514 }
5515
5516 if (!checkExportedNamesForDeclaration(target)) {
5517 return false;
5518 }
5519 }
5520
5521 return true;
5522}
5523
5524template <typename Unit>
5525inline bool Parser<SyntaxParseHandler,
5526 Unit>::checkExportedNamesForObjectBinding(ListNodeType obj) {
5527 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5527); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5527; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5528 return false;
5529}
5530
5531template <class ParseHandler, typename Unit>
5532inline bool
5533GeneralParser<ParseHandler, Unit>::checkExportedNamesForObjectBinding(
5534 ListNodeType obj) {
5535 return asFinalParser()->checkExportedNamesForObjectBinding(obj);
5536}
5537
5538template <typename Unit>
5539bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclaration(
5540 ParseNode* node) {
5541 if (node->isKind(ParseNodeKind::Name)) {
5542 if (!checkExportedName(node->as<NameNode>().atom())) {
5543 return false;
5544 }
5545 } else if (node->isKind(ParseNodeKind::ArrayExpr)) {
5546 if (!checkExportedNamesForArrayBinding(&node->as<ListNode>())) {
5547 return false;
5548 }
5549 } else {
5550 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"
, 5550); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::ObjectExpr)"
")"); do { *((volatile int*)__null) = 5550; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5551 if (!checkExportedNamesForObjectBinding(&node->as<ListNode>())) {
5552 return false;
5553 }
5554 }
5555
5556 return true;
5557}
5558
5559template <typename Unit>
5560inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForDeclaration(
5561 Node node) {
5562 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5562); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5562; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5563 return false;
5564}
5565
5566template <class ParseHandler, typename Unit>
5567inline bool GeneralParser<ParseHandler, Unit>::checkExportedNamesForDeclaration(
5568 Node node) {
5569 return asFinalParser()->checkExportedNamesForDeclaration(node);
5570}
5571
5572template <typename Unit>
5573bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclarationList(
5574 DeclarationListNodeType node) {
5575 for (ParseNode* binding : node->contents()) {
5576 if (binding->isKind(ParseNodeKind::AssignExpr)) {
5577 binding = binding->as<AssignmentNode>().left();
5578 } else {
5579 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"
, 5579); AnnotateMozCrashReason("MOZ_ASSERT" "(" "binding->isKind(ParseNodeKind::Name)"
")"); do { *((volatile int*)__null) = 5579; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5580 }
5581
5582 if (!checkExportedNamesForDeclaration(binding)) {
5583 return false;
5584 }
5585 }
5586
5587 return true;
5588}
5589
5590template <typename Unit>
5591inline bool
5592Parser<SyntaxParseHandler, Unit>::checkExportedNamesForDeclarationList(
5593 DeclarationListNodeType node) {
5594 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5594); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5594; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5595 return false;
5596}
5597
5598template <class ParseHandler, typename Unit>
5599inline bool
5600GeneralParser<ParseHandler, Unit>::checkExportedNamesForDeclarationList(
5601 DeclarationListNodeType node) {
5602 return asFinalParser()->checkExportedNamesForDeclarationList(node);
5603}
5604
5605template <typename Unit>
5606inline bool Parser<FullParseHandler, Unit>::checkExportedNameForClause(
5607 NameNode* nameNode) {
5608 return checkExportedName(nameNode->atom());
5609}
5610
5611template <typename Unit>
5612inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForClause(
5613 NameNodeType nameNode) {
5614 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5614); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5614; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5615 return false;
5616}
5617
5618template <class ParseHandler, typename Unit>
5619inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForClause(
5620 NameNodeType nameNode) {
5621 return asFinalParser()->checkExportedNameForClause(nameNode);
5622}
5623
5624template <typename Unit>
5625bool Parser<FullParseHandler, Unit>::checkExportedNameForFunction(
5626 FunctionNode* funNode) {
5627 return checkExportedName(funNode->funbox()->explicitName());
5628}
5629
5630template <typename Unit>
5631inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForFunction(
5632 FunctionNodeType funNode) {
5633 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5633); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5633; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5634 return false;
5635}
5636
5637template <class ParseHandler, typename Unit>
5638inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForFunction(
5639 FunctionNodeType funNode) {
5640 return asFinalParser()->checkExportedNameForFunction(funNode);
5641}
5642
5643template <typename Unit>
5644bool Parser<FullParseHandler, Unit>::checkExportedNameForClass(
5645 ClassNode* classNode) {
5646 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"
, 5646); AnnotateMozCrashReason("MOZ_ASSERT" "(" "classNode->names()"
")"); do { *((volatile int*)__null) = 5646; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5647 return checkExportedName(classNode->names()->innerBinding()->atom());
5648}
5649
5650template <typename Unit>
5651inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForClass(
5652 ClassNodeType classNode) {
5653 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5653); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5653; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5654 return false;
5655}
5656
5657template <class ParseHandler, typename Unit>
5658inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForClass(
5659 ClassNodeType classNode) {
5660 return asFinalParser()->checkExportedNameForClass(classNode);
5661}
5662
5663template <>
5664inline bool PerHandlerParser<FullParseHandler>::processExport(ParseNode* node) {
5665 return pc_->sc()->asModuleContext()->builder.processExport(node);
5666}
5667
5668template <>
5669inline bool PerHandlerParser<SyntaxParseHandler>::processExport(Node node) {
5670 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5670); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5670; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5671 return false;
5672}
5673
5674template <>
5675inline bool PerHandlerParser<FullParseHandler>::processExportFrom(
5676 BinaryNodeType node) {
5677 return pc_->sc()->asModuleContext()->builder.processExportFrom(node);
5678}
5679
5680template <>
5681inline bool PerHandlerParser<SyntaxParseHandler>::processExportFrom(
5682 BinaryNodeType node) {
5683 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5683); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5683; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5684 return false;
5685}
5686
5687template <>
5688inline bool PerHandlerParser<FullParseHandler>::processImport(
5689 BinaryNodeType node) {
5690 return pc_->sc()->asModuleContext()->builder.processImport(node);
5691}
5692
5693template <>
5694inline bool PerHandlerParser<SyntaxParseHandler>::processImport(
5695 BinaryNodeType node) {
5696 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5696); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5696; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5697 return false;
5698}
5699
5700template <class ParseHandler, typename Unit>
5701typename ParseHandler::BinaryNodeResult
5702GeneralParser<ParseHandler, Unit>::exportFrom(uint32_t begin, Node specList) {
5703 if (!abortIfSyntaxParser()) {
5704 return errorResult();
5705 }
5706
5707 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"
, 5707); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::From)"
")"); do { *((volatile int*)__null) = 5707; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5708
5709 if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
5710 return errorResult();
5711 }
5712
5713 NameNodeType moduleSpec;
5714 MOZ_TRY_VAR(moduleSpec, stringLiteral())do { auto mozTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleSpec) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5715
5716 TokenKind tt;
5717
5718 // The `assert` keyword has a [no LineTerminator here] production before it in
5719 // the grammar -- `with` does not. We need to handle this distinction.
5720 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
5721 return errorResult();
5722 }
5723
5724 // `with` may have an EOL prior, so peek the next token and replace
5725 // EOL if the next token is `with`.
5726 if (tt == TokenKind::Eol) {
5727 // Doing a regular peek won't produce Eol, but the actual next token.
5728 TokenKind peekedToken;
5729 if (!tokenStream.peekToken(&peekedToken, TokenStream::SlashIsRegExp)) {
5730 return errorResult();
5731 }
5732
5733 if (peekedToken == TokenKind::With) {
5734 tt = TokenKind::With;
5735 }
5736 }
5737
5738 uint32_t moduleSpecPos = pos().begin;
5739
5740 ListNodeType importAttributeList;
5741 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)
5742 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)
;
5743 if (tt == TokenKind::With) {
5744 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
5745
5746 if (!withClause(importAttributeList)) {
5747 return errorResult();
5748 }
5749 }
5750
5751 if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
5752 return errorResult();
5753 }
5754
5755 BinaryNodeType moduleRequest;
5756 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)
5757 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)
5758 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)
;
5759
5760 BinaryNodeType node;
5761 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)
5762 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)
;
5763
5764 if (!processExportFrom(node)) {
5765 return errorResult();
5766 }
5767
5768 return node;
5769}
5770
5771template <class ParseHandler, typename Unit>
5772typename ParseHandler::BinaryNodeResult
5773GeneralParser<ParseHandler, Unit>::exportBatch(uint32_t begin) {
5774 if (!abortIfSyntaxParser()) {
5775 return errorResult();
5776 }
5777
5778 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"
, 5778); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Mul)"
")"); do { *((volatile int*)__null) = 5778; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5779 uint32_t beginExportSpec = pos().begin;
5780
5781 ListNodeType kid;
5782 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)
;
5783
5784 bool foundAs;
5785 if (!tokenStream.matchToken(&foundAs, TokenKind::As)) {
5786 return errorResult();
5787 }
5788
5789 if (foundAs) {
5790 TokenKind tt;
5791 if (!tokenStream.getToken(&tt)) {
5792 return errorResult();
5793 }
5794
5795 NameNodeType exportName = null();
5796 if (TokenKindIsPossibleIdentifierName(tt)) {
5797 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)
;
5798 } else if (tt == TokenKind::String) {
5799 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5800 } else {
5801 error(JSMSG_NO_EXPORT_NAME);
5802 return errorResult();
5803 }
5804
5805 if (!checkExportedNameForClause(exportName)) {
5806 return errorResult();
5807 }
5808
5809 UnaryNodeType exportSpec;
5810 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)
5811 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)
;
5812
5813 handler_.addList(kid, exportSpec);
5814 } else {
5815 // Handle the form |export *| by adding a special export batch
5816 // specifier to the list.
5817 NullaryNodeType exportSpec;
5818 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)
;
5819
5820 handler_.addList(kid, exportSpec);
5821 }
5822
5823 if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_EXPORT_STAR)) {
5824 return errorResult();
5825 }
5826
5827 return exportFrom(begin, kid);
5828}
5829
5830template <typename Unit>
5831bool Parser<FullParseHandler, Unit>::checkLocalExportNames(ListNode* node) {
5832 // ES 2017 draft 15.2.3.1.
5833 for (ParseNode* next : node->contents()) {
5834 ParseNode* name = next->as<BinaryNode>().left();
5835
5836 if (name->isKind(ParseNodeKind::StringExpr)) {
5837 errorAt(name->pn_pos.begin, JSMSG_BAD_LOCAL_STRING_EXPORT);
5838 return false;
5839 }
5840
5841 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"
, 5841); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name->isKind(ParseNodeKind::Name)"
")"); do { *((volatile int*)__null) = 5841; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5842
5843 TaggedParserAtomIndex ident = name->as<NameNode>().atom();
5844 if (!checkLocalExportName(ident, name->pn_pos.begin)) {
5845 return false;
5846 }
5847 }
5848
5849 return true;
5850}
5851
5852template <typename Unit>
5853bool Parser<SyntaxParseHandler, Unit>::checkLocalExportNames(
5854 ListNodeType node) {
5855 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5855); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5855; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5856 return false;
5857}
5858
5859template <class ParseHandler, typename Unit>
5860inline bool GeneralParser<ParseHandler, Unit>::checkLocalExportNames(
5861 ListNodeType node) {
5862 return asFinalParser()->checkLocalExportNames(node);
5863}
5864
5865template <class ParseHandler, typename Unit>
5866typename ParseHandler::NodeResult
5867GeneralParser<ParseHandler, Unit>::exportClause(uint32_t begin) {
5868 if (!abortIfSyntaxParser()) {
5869 return errorResult();
5870 }
5871
5872 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"
, 5872); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 5872; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5873
5874 ListNodeType kid;
5875 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)
;
5876
5877 TokenKind tt;
5878 while (true) {
5879 // Handle the forms |export {}| and |export { ..., }| (where ... is non
5880 // empty), by escaping the loop early if the next token is }.
5881 if (!tokenStream.getToken(&tt)) {
5882 return errorResult();
5883 }
5884
5885 if (tt == TokenKind::RightCurly) {
5886 break;
5887 }
5888
5889 NameNodeType bindingName = null();
5890 if (TokenKindIsPossibleIdentifierName(tt)) {
5891 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)
;
5892 } else if (tt == TokenKind::String) {
5893 MOZ_TRY_VAR(bindingName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (bindingName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5894 } else {
5895 error(JSMSG_NO_BINDING_NAME);
5896 return errorResult();
5897 }
5898
5899 bool foundAs;
5900 if (!tokenStream.matchToken(&foundAs, TokenKind::As)) {
5901 return errorResult();
5902 }
5903
5904 NameNodeType exportName = null();
5905 if (foundAs) {
5906 TokenKind tt;
5907 if (!tokenStream.getToken(&tt)) {
5908 return errorResult();
5909 }
5910
5911 if (TokenKindIsPossibleIdentifierName(tt)) {
5912 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)
;
5913 } else if (tt == TokenKind::String) {
5914 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5915 } else {
5916 error(JSMSG_NO_EXPORT_NAME);
5917 return errorResult();
5918 }
5919 } else {
5920 if (tt != TokenKind::String) {
5921 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)
;
5922 } else {
5923 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5924 }
5925 }
5926
5927 if (!checkExportedNameForClause(exportName)) {
5928 return errorResult();
5929 }
5930
5931 BinaryNodeType exportSpec;
5932 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)
;
5933
5934 handler_.addList(kid, exportSpec);
5935
5936 TokenKind next;
5937 if (!tokenStream.getToken(&next)) {
5938 return errorResult();
5939 }
5940
5941 if (next == TokenKind::RightCurly) {
5942 break;
5943 }
5944
5945 if (next != TokenKind::Comma) {
5946 error(JSMSG_RC_AFTER_EXPORT_SPEC_LIST);
5947 return errorResult();
5948 }
5949 }
5950
5951 // Careful! If |from| follows, even on a new line, it must start a
5952 // FromClause:
5953 //
5954 // export { x }
5955 // from "foo"; // a single ExportDeclaration
5956 //
5957 // But if it doesn't, we might have an ASI opportunity in SlashIsRegExp
5958 // context:
5959 //
5960 // export { x } // ExportDeclaration, terminated by ASI
5961 // fro\u006D // ExpressionStatement, the name "from"
5962 //
5963 // In that case let matchOrInsertSemicolon sort out ASI or any necessary
5964 // error.
5965 bool matched;
5966 if (!tokenStream.matchToken(&matched, TokenKind::From,
5967 TokenStream::SlashIsRegExp)) {
5968 return errorResult();
5969 }
5970
5971 if (matched) {
5972 return exportFrom(begin, kid);
5973 }
5974
5975 if (!matchOrInsertSemicolon()) {
5976 return errorResult();
5977 }
5978
5979 if (!checkLocalExportNames(kid)) {
5980 return errorResult();
5981 }
5982
5983 UnaryNodeType node;
5984 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)
5985 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)
;
5986
5987 if (!processExport(node)) {
5988 return errorResult();
5989 }
5990
5991 return node;
5992}
5993
5994template <class ParseHandler, typename Unit>
5995typename ParseHandler::UnaryNodeResult
5996GeneralParser<ParseHandler, Unit>::exportVariableStatement(uint32_t begin) {
5997 if (!abortIfSyntaxParser()) {
5998 return errorResult();
5999 }
6000
6001 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"
, 6001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Var)"
")"); do { *((volatile int*)__null) = 6001; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6002
6003 DeclarationListNodeType kid;
6004 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)
;
6005 if (!matchOrInsertSemicolon()) {
6006 return errorResult();
6007 }
6008 if (!checkExportedNamesForDeclarationList(kid)) {
6009 return errorResult();
6010 }
6011
6012 UnaryNodeType node;
6013 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)
6014 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)
;
6015
6016 if (!processExport(node)) {
6017 return errorResult();
6018 }
6019
6020 return node;
6021}
6022
6023template <class ParseHandler, typename Unit>
6024typename ParseHandler::UnaryNodeResult
6025GeneralParser<ParseHandler, Unit>::exportFunctionDeclaration(
6026 uint32_t begin, uint32_t toStringStart,
6027 FunctionAsyncKind asyncKind /* = SyncFunction */) {
6028 if (!abortIfSyntaxParser()) {
6029 return errorResult();
6030 }
6031
6032 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"
, 6032); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 6032; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6033
6034 Node kid;
6035 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)
6036 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)
;
6037
6038 if (!checkExportedNameForFunction(handler_.asFunctionNode(kid))) {
6039 return errorResult();
6040 }
6041
6042 UnaryNodeType node;
6043 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)
6044 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)
;
6045
6046 if (!processExport(node)) {
6047 return errorResult();
6048 }
6049
6050 return node;
6051}
6052
6053template <class ParseHandler, typename Unit>
6054typename ParseHandler::UnaryNodeResult
6055GeneralParser<ParseHandler, Unit>::exportClassDeclaration(uint32_t begin) {
6056 if (!abortIfSyntaxParser()) {
6057 return errorResult();
6058 }
6059
6060 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"
, 6060); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 6060; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6061
6062 ClassNodeType kid;
6063 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)
;
6064
6065 if (!checkExportedNameForClass(kid)) {
6066 return errorResult();
6067 }
6068
6069 UnaryNodeType node;
6070 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)
6071 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)
;
6072
6073 if (!processExport(node)) {
6074 return errorResult();
6075 }
6076
6077 return node;
6078}
6079
6080template <class ParseHandler, typename Unit>
6081typename ParseHandler::UnaryNodeResult
6082GeneralParser<ParseHandler, Unit>::exportLexicalDeclaration(
6083 uint32_t begin, DeclarationKind kind) {
6084 if (!abortIfSyntaxParser()) {
6085 return errorResult();
6086 }
6087
6088 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"
, 6088); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Let"
")"); do { *((volatile int*)__null) = 6088; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6089 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"
, 6090); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Const)"
")"); do { *((volatile int*)__null) = 6090; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6090 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"
, 6090); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Const)"
")"); do { *((volatile int*)__null) = 6090; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6091 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"
, 6092); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 6092; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6092 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"
, 6092); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 6092; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6093
6094 DeclarationListNodeType kid;
6095 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)
;
6096 if (!checkExportedNamesForDeclarationList(kid)) {
6097 return errorResult();
6098 }
6099
6100 UnaryNodeType node;
6101 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)
6102 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)
;
6103
6104 if (!processExport(node)) {
6105 return errorResult();
6106 }
6107
6108 return node;
6109}
6110
6111template <class ParseHandler, typename Unit>
6112typename ParseHandler::BinaryNodeResult
6113GeneralParser<ParseHandler, Unit>::exportDefaultFunctionDeclaration(
6114 uint32_t begin, uint32_t toStringStart,
6115 FunctionAsyncKind asyncKind /* = SyncFunction */) {
6116 if (!abortIfSyntaxParser()) {
6117 return errorResult();
6118 }
6119
6120 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"
, 6120); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 6120; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6121
6122 Node kid;
6123 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)
6124 asyncKind))do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, AllowDefaultName, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6125
6126 BinaryNodeType node;
6127 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)
6128 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)
;
6129
6130 if (!processExport(node)) {
6131 return errorResult();
6132 }
6133
6134 return node;
6135}
6136
6137template <class ParseHandler, typename Unit>
6138typename ParseHandler::BinaryNodeResult
6139GeneralParser<ParseHandler, Unit>::exportDefaultClassDeclaration(
6140 uint32_t begin) {
6141 if (!abortIfSyntaxParser()) {
6142 return errorResult();
6143 }
6144
6145 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"
, 6145); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 6145; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6146
6147 ClassNodeType kid;
6148 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)
6149 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)
;
6150
6151 BinaryNodeType node;
6152 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)
6153 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)
;
6154
6155 if (!processExport(node)) {
6156 return errorResult();
6157 }
6158
6159 return node;
6160}
6161
6162template <class ParseHandler, typename Unit>
6163typename ParseHandler::BinaryNodeResult
6164GeneralParser<ParseHandler, Unit>::exportDefaultAssignExpr(uint32_t begin) {
6165 if (!abortIfSyntaxParser()) {
6166 return errorResult();
6167 }
6168
6169 TaggedParserAtomIndex name = TaggedParserAtomIndex::WellKnown::default_();
6170 NameNodeType nameNode;
6171 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)
;
6172 if (!noteDeclaredName(name, DeclarationKind::Const, pos())) {
6173 return errorResult();
6174 }
6175
6176 Node kid;
6177 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)
;
6178
6179 if (!matchOrInsertSemicolon()) {
6180 return errorResult();
6181 }
6182
6183 BinaryNodeType node;
6184 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)
6185 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)
;
6186
6187 if (!processExport(node)) {
6188 return errorResult();
6189 }
6190
6191 return node;
6192}
6193
6194template <class ParseHandler, typename Unit>
6195typename ParseHandler::BinaryNodeResult
6196GeneralParser<ParseHandler, Unit>::exportDefault(uint32_t begin) {
6197 if (!abortIfSyntaxParser()) {
6198 return errorResult();
6199 }
6200
6201 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"
, 6201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Default)"
")"); do { *((volatile int*)__null) = 6201; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6202
6203 TokenKind tt;
6204 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6205 return errorResult();
6206 }
6207
6208 if (!checkExportedName(TaggedParserAtomIndex::WellKnown::default_())) {
6209 return errorResult();
6210 }
6211
6212 switch (tt) {
6213 case TokenKind::Function:
6214 return exportDefaultFunctionDeclaration(begin, pos().begin);
6215
6216 case TokenKind::Async: {
6217 TokenKind nextSameLine = TokenKind::Eof;
6218 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
6219 return errorResult();
6220 }
6221
6222 if (nextSameLine == TokenKind::Function) {
6223 uint32_t toStringStart = pos().begin;
6224 tokenStream.consumeKnownToken(TokenKind::Function);
6225 return exportDefaultFunctionDeclaration(
6226 begin, toStringStart, FunctionAsyncKind::AsyncFunction);
6227 }
6228
6229 anyChars.ungetToken();
6230 return exportDefaultAssignExpr(begin);
6231 }
6232
6233 case TokenKind::Class:
6234 return exportDefaultClassDeclaration(begin);
6235
6236 default:
6237 anyChars.ungetToken();
6238 return exportDefaultAssignExpr(begin);
6239 }
6240}
6241
6242template <class ParseHandler, typename Unit>
6243typename ParseHandler::NodeResult
6244GeneralParser<ParseHandler, Unit>::exportDeclaration() {
6245 if (!abortIfSyntaxParser()) {
6246 return errorResult();
6247 }
6248
6249 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"
, 6249); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Export)"
")"); do { *((volatile int*)__null) = 6249; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6250
6251 if (!pc_->atModuleLevel()) {
6252 error(JSMSG_EXPORT_DECL_AT_TOP_LEVEL);
6253 return errorResult();
6254 }
6255
6256 uint32_t begin = pos().begin;
6257
6258 TokenKind tt;
6259 if (!tokenStream.getToken(&tt)) {
6260 return errorResult();
6261 }
6262 switch (tt) {
6263 case TokenKind::Mul:
6264 return exportBatch(begin);
6265
6266 case TokenKind::LeftCurly:
6267 return exportClause(begin);
6268
6269 case TokenKind::Var:
6270 return exportVariableStatement(begin);
6271
6272 case TokenKind::Function:
6273 return exportFunctionDeclaration(begin, pos().begin);
6274
6275 case TokenKind::Async: {
6276 TokenKind nextSameLine = TokenKind::Eof;
6277 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
6278 return errorResult();
6279 }
6280
6281 if (nextSameLine == TokenKind::Function) {
6282 uint32_t toStringStart = pos().begin;
6283 tokenStream.consumeKnownToken(TokenKind::Function);
6284 return exportFunctionDeclaration(begin, toStringStart,
6285 FunctionAsyncKind::AsyncFunction);
6286 }
6287
6288 error(JSMSG_DECLARATION_AFTER_EXPORT);
6289 return errorResult();
6290 }
6291
6292 case TokenKind::Class:
6293 return exportClassDeclaration(begin);
6294
6295 case TokenKind::Const:
6296 return exportLexicalDeclaration(begin, DeclarationKind::Const);
6297
6298 case TokenKind::Let:
6299 return exportLexicalDeclaration(begin, DeclarationKind::Let);
6300
6301 case TokenKind::Default:
6302 return exportDefault(begin);
6303
6304 default:
6305 error(JSMSG_DECLARATION_AFTER_EXPORT);
6306 return errorResult();
6307 }
6308}
6309
6310template <class ParseHandler, typename Unit>
6311typename ParseHandler::UnaryNodeResult
6312GeneralParser<ParseHandler, Unit>::expressionStatement(
6313 YieldHandling yieldHandling, InvokedPrediction invoked) {
6314 anyChars.ungetToken();
6315 Node pnexpr;
6316 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)
6317 /* 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)
;
6318 if (!matchOrInsertSemicolon()) {
6319 return errorResult();
6320 }
6321 return handler_.newExprStatement(pnexpr, pos().end);
6322}
6323
6324template <class ParseHandler, typename Unit>
6325typename ParseHandler::NodeResult
6326GeneralParser<ParseHandler, Unit>::consequentOrAlternative(
6327 YieldHandling yieldHandling) {
6328 TokenKind next;
6329 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
6330 return errorResult();
6331 }
6332
6333 // Annex B.3.4 says that unbraced FunctionDeclarations under if/else in
6334 // non-strict code act as if they were braced: |if (x) function f() {}|
6335 // parses as |if (x) { function f() {} }|.
6336 //
6337 // Careful! FunctionDeclaration doesn't include generators or async
6338 // functions.
6339 if (next == TokenKind::Function) {
6340 tokenStream.consumeKnownToken(next, TokenStream::SlashIsRegExp);
6341
6342 // Parser::statement would handle this, but as this function handles
6343 // every other error case, it seems best to handle this.
6344 if (pc_->sc()->strict()) {
6345 error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
6346 return errorResult();
6347 }
6348
6349 TokenKind maybeStar;
6350 if (!tokenStream.peekToken(&maybeStar)) {
6351 return errorResult();
6352 }
6353
6354 if (maybeStar == TokenKind::Mul) {
6355 error(JSMSG_FORBIDDEN_AS_STATEMENT, "generator declarations");
6356 return errorResult();
6357 }
6358
6359 ParseContext::Statement stmt(pc_, StatementKind::Block);
6360 ParseContext::Scope scope(this);
6361 if (!scope.init(pc_)) {
6362 return errorResult();
6363 }
6364
6365 TokenPos funcPos = pos();
6366 Node fun;
6367 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)
;
6368
6369 ListNodeType block;
6370 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)
;
6371
6372 handler_.addStatementToList(block, fun);
6373 return finishLexicalScope(scope, block);
6374 }
6375
6376 return statement(yieldHandling);
6377}
6378
6379template <class ParseHandler, typename Unit>
6380typename ParseHandler::TernaryNodeResult
6381GeneralParser<ParseHandler, Unit>::ifStatement(YieldHandling yieldHandling) {
6382 Vector<Node, 4> condList(fc_), thenList(fc_);
6383 Vector<uint32_t, 4> posList(fc_);
6384 Node elseBranch;
6385
6386 ParseContext::Statement stmt(pc_, StatementKind::If);
6387
6388 while (true) {
6389 uint32_t begin = pos().begin;
6390
6391 /* An IF node has three kids: condition, then, and optional else. */
6392 Node cond;
6393 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)
;
6394
6395 TokenKind tt;
6396 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6397 return errorResult();
6398 }
6399
6400 Node thenBranch;
6401 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)
;
6402
6403 if (!condList.append(cond) || !thenList.append(thenBranch) ||
6404 !posList.append(begin)) {
6405 return errorResult();
6406 }
6407
6408 bool matched;
6409 if (!tokenStream.matchToken(&matched, TokenKind::Else,
6410 TokenStream::SlashIsRegExp)) {
6411 return errorResult();
6412 }
6413 if (matched) {
6414 if (!tokenStream.matchToken(&matched, TokenKind::If,
6415 TokenStream::SlashIsRegExp)) {
6416 return errorResult();
6417 }
6418 if (matched) {
6419 continue;
6420 }
6421 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)
;
6422 } else {
6423 elseBranch = null();
6424 }
6425 break;
6426 }
6427
6428 TernaryNodeType ifNode;
6429 for (int i = condList.length() - 1; i >= 0; i--) {
6430 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)
6431 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)
;
6432 elseBranch = ifNode;
6433 }
6434
6435 return ifNode;
6436}
6437
6438template <class ParseHandler, typename Unit>
6439typename ParseHandler::BinaryNodeResult
6440GeneralParser<ParseHandler, Unit>::doWhileStatement(
6441 YieldHandling yieldHandling) {
6442 uint32_t begin = pos().begin;
6443 ParseContext::Statement stmt(pc_, StatementKind::DoLoop);
6444 Node body;
6445 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)
;
6446 if (!mustMatchToken(TokenKind::While, JSMSG_WHILE_AFTER_DO)) {
6447 return errorResult();
6448 }
6449 Node cond;
6450 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)
;
6451
6452 // The semicolon after do-while is even more optional than most
6453 // semicolons in JS. Web compat required this by 2004:
6454 // http://bugzilla.mozilla.org/show_bug.cgi?id=238945
6455 // ES3 and ES5 disagreed, but ES6 conforms to Web reality:
6456 // https://bugs.ecmascript.org/show_bug.cgi?id=157
6457 // To parse |do {} while (true) false| correctly, use SlashIsRegExp.
6458 bool ignored;
6459 if (!tokenStream.matchToken(&ignored, TokenKind::Semi,
6460 TokenStream::SlashIsRegExp)) {
6461 return errorResult();
6462 }
6463 return handler_.newDoWhileStatement(body, cond, TokenPos(begin, pos().end));
6464}
6465
6466template <class ParseHandler, typename Unit>
6467typename ParseHandler::BinaryNodeResult
6468GeneralParser<ParseHandler, Unit>::whileStatement(YieldHandling yieldHandling) {
6469 uint32_t begin = pos().begin;
6470 ParseContext::Statement stmt(pc_, StatementKind::WhileLoop);
6471 Node cond;
6472 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)
;
6473 Node body;
6474 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)
;
6475 return handler_.newWhileStatement(begin, cond, body);
6476}
6477
6478template <class ParseHandler, typename Unit>
6479bool GeneralParser<ParseHandler, Unit>::matchInOrOf(bool* isForInp,
6480 bool* isForOfp) {
6481 TokenKind tt;
6482 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6483 return false;
6484 }
6485
6486 *isForInp = tt == TokenKind::In;
6487 *isForOfp = tt == TokenKind::Of;
6488 if (!*isForInp && !*isForOfp) {
6489 anyChars.ungetToken();
6490 }
6491
6492 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"
, 6492); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*isForInp != *isForOfp"
")"); do { *((volatile int*)__null) = 6492; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6493 return true;
6494}
6495
6496template <class ParseHandler, typename Unit>
6497bool GeneralParser<ParseHandler, Unit>::forHeadStart(
6498 YieldHandling yieldHandling, IteratorKind iterKind,
6499 ParseNodeKind* forHeadKind, Node* forInitialPart,
6500 Maybe<ParseContext::Scope>& forLoopLexicalScope,
6501 Node* forInOrOfExpression) {
6502 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"
, 6502); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftParen)"
")"); do { *((volatile int*)__null) = 6502; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6503
6504 TokenKind tt;
6505 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6506 return false;
6507 }
6508
6509 // Super-duper easy case: |for (;| is a C-style for-loop with no init
6510 // component.
6511 if (tt == TokenKind::Semi) {
6512 *forInitialPart = null();
6513 *forHeadKind = ParseNodeKind::ForHead;
6514 return true;
6515 }
6516
6517 // Parsing after |for (var| is also relatively simple (from this method's
6518 // point of view). No block-related work complicates matters, so delegate
6519 // to Parser::declaration.
6520 if (tt == TokenKind::Var) {
6521 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6522
6523 // Pass null for block object because |var| declarations don't use one.
6524 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)
6525 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)
6526 forHeadKind, forInOrOfExpression),do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
6527 false)do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
;
6528 return true;
6529 }
6530
6531 // Otherwise we have a lexical declaration or an expression.
6532
6533 // For-in loop backwards compatibility requires that |let| starting a
6534 // for-loop that's not a (new to ES6) for-of loop, in non-strict mode code,
6535 // parse as an identifier. (|let| in for-of is always a declaration.)
6536 //
6537 // For-of loops can't start with the token sequence "async of", because that
6538 // leads to a shift-reduce conflict when parsing |for (async of => {};;)| or
6539 // |for (async of [])|.
6540 bool parsingLexicalDeclaration = false;
6541 bool letIsIdentifier = false;
6542 bool startsWithForOf = false;
6543
6544 if (tt == TokenKind::Const) {
6545 parsingLexicalDeclaration = true;
6546 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6547 }
6548#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
6549 else if (tt == TokenKind::Await && options().explicitResourceManagement()) {
6550 if (!pc_->isAsync()) {
6551 if (pc_->atModuleTopLevel()) {
6552 if (!options().topLevelAwait) {
6553 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
6554 return false;
6555 }
6556 pc_->sc()->asModuleContext()->setIsAsync();
6557 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"
, 6557); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 6557; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6558 }
6559 }
6560 if (pc_->isAsync()) {
6561 // Try finding evidence of a AwaitUsingDeclaration the syntax for which
6562 // would be:
6563 // await [no LineTerminator here] using [no LineTerminator here]
6564 // identifier
6565 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6566
6567 TokenKind nextTok = TokenKind::Eof;
6568 if (!tokenStream.peekTokenSameLine(&nextTok,
6569 TokenStream::SlashIsRegExp)) {
6570 return false;
6571 }
6572
6573 if (nextTok == TokenKind::Using) {
6574 tokenStream.consumeKnownToken(nextTok, TokenStream::SlashIsRegExp);
6575
6576 TokenKind nextTokIdent = TokenKind::Eof;
6577 if (!tokenStream.peekTokenSameLine(&nextTokIdent)) {
6578 return false;
6579 }
6580
6581 if (TokenKindIsPossibleIdentifier(nextTokIdent)) {
6582 parsingLexicalDeclaration = true;
6583 } else {
6584 anyChars.ungetToken(); // put back using token
6585 anyChars.ungetToken(); // put back await token
6586 }
6587 } else {
6588 anyChars.ungetToken(); // put back await token
6589 }
6590 }
6591 } else if (tt == TokenKind::Using && options().explicitResourceManagement()) {
6592 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6593
6594 // Look ahead to find either a 'of' token or if not identifier
6595 TokenKind nextTok = TokenKind::Eof;
6596 if (!tokenStream.peekTokenSameLine(&nextTok)) {
6597 return false;
6598 }
6599
6600 if (nextTok == TokenKind::Of || !TokenKindIsPossibleIdentifier(nextTok)) {
6601 anyChars.ungetToken(); // we didnt find a valid case of using decl put
6602 // back the token
6603 } else {
6604 parsingLexicalDeclaration = true;
6605 }
6606 }
6607#endif
6608 else if (tt == TokenKind::Let) {
6609 // We could have a {For,Lexical}Declaration, or we could have a
6610 // LeftHandSideExpression with lookahead restrictions so it's not
6611 // ambiguous with the former. Check for a continuation of the former
6612 // to decide which we have.
6613 tokenStream.consumeKnownToken(TokenKind::Let, TokenStream::SlashIsRegExp);
6614
6615 TokenKind next;
6616 if (!tokenStream.peekToken(&next)) {
6617 return false;
6618 }
6619
6620 parsingLexicalDeclaration = nextTokenContinuesLetDeclaration(next);
6621 if (!parsingLexicalDeclaration) {
6622 // If we end up here, we may have `for (let <reserved word> of/in ...`,
6623 // which is not valid.
6624 if (next != TokenKind::In && next != TokenKind::Of &&
6625 TokenKindIsReservedWord(next)) {
6626 tokenStream.consumeKnownToken(next);
6627 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
6628 return false;
6629 }
6630
6631 anyChars.ungetToken();
6632 letIsIdentifier = true;
6633 }
6634 } else if (tt == TokenKind::Async && iterKind == IteratorKind::Sync) {
6635 tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::SlashIsRegExp);
6636
6637 TokenKind next;
6638 if (!tokenStream.peekToken(&next)) {
6639 return false;
6640 }
6641
6642 if (next == TokenKind::Of) {
6643 startsWithForOf = true;
6644 }
6645 anyChars.ungetToken();
6646 }
6647
6648 if (parsingLexicalDeclaration) {
6649 if (options().selfHostingMode) {
6650 error(JSMSG_SELFHOSTED_LEXICAL);
6651 return false;
6652 }
6653
6654 forLoopLexicalScope.emplace(this);
6655 if (!forLoopLexicalScope->init(pc_)) {
6656 return false;
6657 }
6658
6659 // Push a temporary ForLoopLexicalHead Statement that allows for
6660 // lexical declarations, as they are usually allowed only in braced
6661 // statements.
6662 ParseContext::Statement forHeadStmt(pc_, StatementKind::ForLoopLexicalHead);
6663
6664 ParseNodeKind declKind;
6665 switch (tt) {
6666 case TokenKind::Const:
6667 declKind = ParseNodeKind::ConstDecl;
6668 break;
6669#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
6670 case TokenKind::Using:
6671 declKind = ParseNodeKind::UsingDecl;
6672 break;
6673 case TokenKind::Await:
6674 declKind = ParseNodeKind::AwaitUsingDecl;
6675 break;
6676#endif
6677 case TokenKind::Let:
6678 declKind = ParseNodeKind::LetDecl;
6679 break;
6680 default:
6681 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"
, 6681); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected node kind"
")"); do { *((volatile int*)__null) = 6681; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6682 }
6683
6684 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)
6685 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)
6686 forInOrOfExpression),do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6687 false)do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
;
6688 return true;
6689 }
6690
6691 uint32_t exprOffset;
6692 if (!tokenStream.peekOffset(&exprOffset, TokenStream::SlashIsRegExp)) {
6693 return false;
6694 }
6695
6696 // Finally, handle for-loops that start with expressions. Pass
6697 // |InProhibited| so that |in| isn't parsed in a RelationalExpression as a
6698 // binary operator. |in| makes it a for-in loop, *not* an |in| expression.
6699 PossibleError possibleError(*this);
6700 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)
6701 *forInitialPart,do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6702 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)
6703 false)do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
;
6704
6705 bool isForIn, isForOf;
6706 if (!matchInOrOf(&isForIn, &isForOf)) {
6707 return false;
6708 }
6709
6710 // If we don't encounter 'in'/'of', we have a for(;;) loop. We've handled
6711 // the init expression; the caller handles the rest.
6712 if (!isForIn && !isForOf) {
6713 if (!possibleError.checkForExpressionError()) {
6714 return false;
6715 }
6716
6717 *forHeadKind = ParseNodeKind::ForHead;
6718 return true;
6719 }
6720
6721 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"
, 6721); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isForIn != isForOf"
")"); do { *((volatile int*)__null) = 6721; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6722
6723 // In a for-of loop, 'let' that starts the loop head is a |let| keyword,
6724 // per the [lookahead ≠ let] restriction on the LeftHandSideExpression
6725 // variant of such loops. Expressions that start with |let| can't be used
6726 // here.
6727 //
6728 // var let = {};
6729 // for (let.prop of [1]) // BAD
6730 // break;
6731 //
6732 // See ES6 13.7.
6733 if (isForOf && letIsIdentifier) {
6734 errorAt(exprOffset, JSMSG_BAD_STARTING_FOROF_LHS, "let");
6735 return false;
6736 }
6737
6738 // In a for-of loop, the LeftHandSideExpression isn't allowed to be an
6739 // identifier named "async" per the [lookahead ≠ async of] restriction.
6740 if (isForOf && startsWithForOf) {
6741 errorAt(exprOffset, JSMSG_BAD_STARTING_FOROF_LHS, "async of");
6742 return false;
6743 }
6744
6745 *forHeadKind = isForIn ? ParseNodeKind::ForIn : ParseNodeKind::ForOf;
6746
6747 // Verify the left-hand side expression doesn't have a forbidden form.
6748 if (handler_.isUnparenthesizedDestructuringPattern(*forInitialPart)) {
6749 if (!possibleError.checkForDestructuringErrorOrWarning()) {
6750 return false;
6751 }
6752 } else if (handler_.isName(*forInitialPart)) {
6753 if (const char* chars = nameIsArgumentsOrEval(*forInitialPart)) {
6754 // |chars| is "arguments" or "eval" here.
6755 if (!strictModeErrorAt(exprOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) {
6756 return false;
6757 }
6758 }
6759 } else if (handler_.isArgumentsLength(*forInitialPart)) {
6760 pc_->sc()->setIneligibleForArgumentsLength();
6761 } else if (handler_.isPropertyOrPrivateMemberAccess(*forInitialPart)) {
6762 // Permitted: no additional testing/fixup needed.
6763 } else if (handler_.isFunctionCall(*forInitialPart)) {
6764 if (!strictModeErrorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE)) {
6765 return false;
6766 }
6767 } else {
6768 errorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE);
6769 return false;
6770 }
6771
6772 if (!possibleError.checkForExpressionError()) {
6773 return false;
6774 }
6775
6776 // Finally, parse the iterated expression, making the for-loop's closing
6777 // ')' the next token.
6778 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)
6779 expressionAfterForInOrOf(*forHeadKind, yieldHandling),do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
6780 false)do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
;
6781 return true;
6782}
6783
6784template <class ParseHandler, typename Unit>
6785typename ParseHandler::NodeResult
6786GeneralParser<ParseHandler, Unit>::forStatement(YieldHandling yieldHandling) {
6787 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"
, 6787); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::For)"
")"); do { *((volatile int*)__null) = 6787; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6788
6789 uint32_t begin = pos().begin;
6790
6791 ParseContext::Statement stmt(pc_, StatementKind::ForLoop);
6792
6793 IteratorKind iterKind = IteratorKind::Sync;
6794 unsigned iflags = 0;
6795
6796 if (pc_->isAsync() || pc_->sc()->isModuleContext()) {
6797 bool matched;
6798 if (!tokenStream.matchToken(&matched, TokenKind::Await)) {
6799 return errorResult();
6800 }
6801
6802 // If we come across a top level await here, mark the module as async.
6803 if (matched && pc_->sc()->isModuleContext() && !pc_->isAsync()) {
6804 if (!options().topLevelAwait) {
6805 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
6806 return errorResult();
6807 }
6808 pc_->sc()->asModuleContext()->setIsAsync();
6809 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"
, 6809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 6809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6810 }
6811
6812 if (matched) {
6813 iflags |= JSITER_FORAWAITOF0x80;
6814 iterKind = IteratorKind::Async;
6815 }
6816 }
6817
6818 if (!mustMatchToken(TokenKind::LeftParen, [this](TokenKind actual) {
6819 this->error((actual == TokenKind::Await && !this->pc_->isAsync())
6820 ? JSMSG_FOR_AWAIT_OUTSIDE_ASYNC
6821 : JSMSG_PAREN_AFTER_FOR);
6822 })) {
6823 return errorResult();
6824 }
6825
6826 // ParseNodeKind::ForHead, ParseNodeKind::ForIn, or
6827 // ParseNodeKind::ForOf depending on the loop type.
6828 ParseNodeKind headKind;
6829
6830 // |x| in either |for (x; ...; ...)| or |for (x in/of ...)|.
6831 Node startNode;
6832
6833 // The next two variables are used to implement `for (let/const ...)`.
6834 //
6835 // We generate an implicit block, wrapping the whole loop, to store loop
6836 // variables declared this way. Note that if the loop uses `for (var...)`
6837 // instead, those variables go on some existing enclosing scope, so no
6838 // implicit block scope is created.
6839 //
6840 // Both variables remain null/none if the loop is any other form.
6841
6842 // The static block scope for the implicit block scope.
6843 Maybe<ParseContext::Scope> forLoopLexicalScope;
6844
6845 // The expression being iterated over, for for-in/of loops only. Unused
6846 // for for(;;) loops.
6847 Node iteratedExpr;
6848
6849 // Parse the entirety of the loop-head for a for-in/of loop (so the next
6850 // token is the closing ')'):
6851 //
6852 // for (... in/of ...) ...
6853 // ^next token
6854 //
6855 // ...OR, parse up to the first ';' in a C-style for-loop:
6856 //
6857 // for (...; ...; ...) ...
6858 // ^next token
6859 //
6860 // In either case the subsequent token can be consistently accessed using
6861 // TokenStream::SlashIsDiv semantics.
6862 if (!forHeadStart(yieldHandling, iterKind, &headKind, &startNode,
6863 forLoopLexicalScope, &iteratedExpr)) {
6864 return errorResult();
6865 }
6866
6867 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"
, 6869); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6869; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6868 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"
, 6869); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6869; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6869 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"
, 6869); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6869; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6870
6871 if (iterKind == IteratorKind::Async && headKind != ParseNodeKind::ForOf) {
6872 errorAt(begin, JSMSG_FOR_AWAIT_NOT_OF);
6873 return errorResult();
6874 }
6875
6876 TernaryNodeType forHead;
6877 if (headKind == ParseNodeKind::ForHead) {
6878 Node init = startNode;
6879
6880 // Look for an operand: |for (;| means we might have already examined
6881 // this semicolon with that modifier.
6882 if (!mustMatchToken(TokenKind::Semi, JSMSG_SEMI_AFTER_FOR_INIT)) {
6883 return errorResult();
6884 }
6885
6886 TokenKind tt;
6887 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6888 return errorResult();
6889 }
6890
6891 Node test;
6892 if (tt == TokenKind::Semi) {
6893 test = null();
6894 } else {
6895 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)
;
6896 }
6897
6898 if (!mustMatchToken(TokenKind::Semi, JSMSG_SEMI_AFTER_FOR_COND)) {
6899 return errorResult();
6900 }
6901
6902 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6903 return errorResult();
6904 }
6905
6906 Node update;
6907 if (tt == TokenKind::RightParen) {
6908 update = null();
6909 } else {
6910 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)
;
6911 }
6912
6913 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_FOR_CTRL)) {
6914 return errorResult();
6915 }
6916
6917 TokenPos headPos(begin, pos().end);
6918 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)
;
6919 } else {
6920 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"
, 6921); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 6921; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6921 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"
, 6921); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 6921; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6922
6923 // |target| is the LeftHandSideExpression or declaration to which the
6924 // per-iteration value (an arbitrary value exposed by the iteration
6925 // protocol, or a string naming a property) is assigned.
6926 Node target = startNode;
6927
6928 // Parse the rest of the for-in/of head.
6929 if (headKind == ParseNodeKind::ForIn) {
6930 stmt.refineForKind(StatementKind::ForInLoop);
6931 } else {
6932 stmt.refineForKind(StatementKind::ForOfLoop);
6933 }
6934
6935 // Parser::declaration consumed everything up to the closing ')'. That
6936 // token follows an {Assignment,}Expression and so must be interpreted
6937 // as an operand to be consistent with normal expression tokenizing.
6938 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_FOR_CTRL)) {
6939 return errorResult();
6940 }
6941
6942 TokenPos headPos(begin, pos().end);
6943 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)
6944 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)
;
6945 }
6946
6947 Node body;
6948 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)
;
6949
6950 ForNodeType forLoop;
6951 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)
;
6952
6953 if (forLoopLexicalScope) {
6954 return finishLexicalScope(*forLoopLexicalScope, forLoop);
6955 }
6956
6957 return forLoop;
6958}
6959
6960template <class ParseHandler, typename Unit>
6961typename ParseHandler::SwitchStatementResult
6962GeneralParser<ParseHandler, Unit>::switchStatement(
6963 YieldHandling yieldHandling) {
6964 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"
, 6964); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Switch)"
")"); do { *((volatile int*)__null) = 6964; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6965 uint32_t begin = pos().begin;
6966
6967 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_SWITCH)) {
6968 return errorResult();
6969 }
6970
6971 Node discriminant;
6972 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
)
6973 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
)
;
6974
6975 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_SWITCH)) {
6976 return errorResult();
6977 }
6978 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_SWITCH)) {
6979 return errorResult();
6980 }
6981
6982 ParseContext::Statement stmt(pc_, StatementKind::Switch);
6983 ParseContext::Scope scope(this);
6984 if (!scope.init(pc_)) {
6985 return errorResult();
6986 }
6987
6988 ListNodeType caseList;
6989 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)
;
6990
6991 bool seenDefault = false;
6992 TokenKind tt;
6993 while (true) {
6994 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6995 return errorResult();
6996 }
6997 if (tt == TokenKind::RightCurly) {
6998 break;
6999 }
7000 uint32_t caseBegin = pos().begin;
7001
7002 Node caseExpr;
7003 switch (tt) {
7004 case TokenKind::Default:
7005 if (seenDefault) {
7006 error(JSMSG_TOO_MANY_DEFAULTS);
7007 return errorResult();
7008 }
7009 seenDefault = true;
7010 caseExpr = null(); // The default case has pn_left == nullptr.
7011 break;
7012
7013 case TokenKind::Case:
7014 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)
7015 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)
;
7016 break;
7017
7018 default:
7019 error(JSMSG_BAD_SWITCH);
7020 return errorResult();
7021 }
7022
7023 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_CASE)) {
7024 return errorResult();
7025 }
7026
7027 ListNodeType body;
7028 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)
;
7029
7030 bool afterReturn = false;
7031 bool warnedAboutStatementsAfterReturn = false;
7032 uint32_t statementBegin = 0;
7033 while (true) {
7034 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
7035 return errorResult();
7036 }
7037 if (tt == TokenKind::RightCurly || tt == TokenKind::Case ||
7038 tt == TokenKind::Default) {
7039 break;
7040 }
7041 if (afterReturn) {
7042 if (!tokenStream.peekOffset(&statementBegin,
7043 TokenStream::SlashIsRegExp)) {
7044 return errorResult();
7045 }
7046 }
7047 Node stmt;
7048 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)
;
7049 if (!warnedAboutStatementsAfterReturn) {
7050 if (afterReturn) {
7051 if (!handler_.isStatementPermittedAfterReturnStatement(stmt)) {
7052 if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
7053 return errorResult();
7054 }
7055
7056 warnedAboutStatementsAfterReturn = true;
7057 }
7058 } else if (handler_.isReturnStatement(stmt)) {
7059 afterReturn = true;
7060 }
7061 }
7062 handler_.addStatementToList(body, stmt);
7063 }
7064
7065 CaseClauseType caseClause;
7066 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)
7067 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)
;
7068 handler_.addCaseStatementToList(caseList, caseClause);
7069 }
7070
7071 LexicalScopeNodeType lexicalForCaseList;
7072 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)
;
7073
7074 handler_.setEndPosition(lexicalForCaseList, pos().end);
7075
7076 return handler_.newSwitchStatement(begin, discriminant, lexicalForCaseList,
7077 seenDefault);
7078}
7079
7080template <class ParseHandler, typename Unit>
7081typename ParseHandler::ContinueStatementResult
7082GeneralParser<ParseHandler, Unit>::continueStatement(
7083 YieldHandling yieldHandling) {
7084 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"
, 7084); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Continue)"
")"); do { *((volatile int*)__null) = 7084; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7085 uint32_t begin = pos().begin;
7086
7087 TaggedParserAtomIndex label;
7088 if (!matchLabel(yieldHandling, &label)) {
7089 return errorResult();
7090 }
7091
7092 auto validity = pc_->checkContinueStatement(label);
7093 if (validity.isErr()) {
7094 switch (validity.unwrapErr()) {
7095 case ParseContext::ContinueStatementError::NotInALoop:
7096 errorAt(begin, JSMSG_BAD_CONTINUE);
7097 break;
7098 case ParseContext::ContinueStatementError::LabelNotFound:
7099 error(JSMSG_LABEL_NOT_FOUND);
7100 break;
7101 }
7102 return errorResult();
7103 }
7104
7105 if (!matchOrInsertSemicolon()) {
7106 return errorResult();
7107 }
7108
7109 return handler_.newContinueStatement(label, TokenPos(begin, pos().end));
7110}
7111
7112template <class ParseHandler, typename Unit>
7113typename ParseHandler::BreakStatementResult
7114GeneralParser<ParseHandler, Unit>::breakStatement(YieldHandling yieldHandling) {
7115 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"
, 7115); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Break)"
")"); do { *((volatile int*)__null) = 7115; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7116 uint32_t begin = pos().begin;
7117
7118 TaggedParserAtomIndex label;
7119 if (!matchLabel(yieldHandling, &label)) {
7120 return errorResult();
7121 }
7122
7123 auto validity = pc_->checkBreakStatement(label);
7124 if (validity.isErr()) {
7125 switch (validity.unwrapErr()) {
7126 case ParseContext::BreakStatementError::ToughBreak:
7127 errorAt(begin, JSMSG_TOUGH_BREAK);
7128 return errorResult();
7129 case ParseContext::BreakStatementError::LabelNotFound:
7130 error(JSMSG_LABEL_NOT_FOUND);
7131 return errorResult();
7132 }
7133 }
7134
7135 if (!matchOrInsertSemicolon()) {
7136 return errorResult();
7137 }
7138
7139 return handler_.newBreakStatement(label, TokenPos(begin, pos().end));
7140}
7141
7142template <class ParseHandler, typename Unit>
7143typename ParseHandler::UnaryNodeResult
7144GeneralParser<ParseHandler, Unit>::returnStatement(
7145 YieldHandling yieldHandling) {
7146 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"
, 7146); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Return)"
")"); do { *((volatile int*)__null) = 7146; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7147 uint32_t begin = pos().begin;
7148
7149 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"
, 7149); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 7149; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7150
7151 // Parse an optional operand.
7152 //
7153 // This is ugly, but we don't want to require a semicolon.
7154 Node exprNode;
7155 TokenKind tt = TokenKind::Eof;
7156 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7157 return errorResult();
7158 }
7159 switch (tt) {
7160 case TokenKind::Eol:
7161 case TokenKind::Eof:
7162 case TokenKind::Semi:
7163 case TokenKind::RightCurly:
7164 exprNode = null();
7165 break;
7166 default: {
7167 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)
7168 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)
;
7169 }
7170 }
7171
7172 if (!matchOrInsertSemicolon()) {
7173 return errorResult();
7174 }
7175
7176 return handler_.newReturnStatement(exprNode, TokenPos(begin, pos().end));
7177}
7178
7179template <class ParseHandler, typename Unit>
7180typename ParseHandler::UnaryNodeResult
7181GeneralParser<ParseHandler, Unit>::yieldExpression(InHandling inHandling) {
7182 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"
, 7182); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Yield)"
")"); do { *((volatile int*)__null) = 7182; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7183 uint32_t begin = pos().begin;
7184
7185 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"
, 7185); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isGenerator()"
")"); do { *((volatile int*)__null) = 7185; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7186 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"
, 7186); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 7186; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7187
7188 pc_->lastYieldOffset = begin;
7189
7190 Node exprNode;
7191 ParseNodeKind kind = ParseNodeKind::YieldExpr;
7192 TokenKind tt = TokenKind::Eof;
7193 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7194 return errorResult();
7195 }
7196 switch (tt) {
7197 // TokenKind::Eol is special; it implements the [no LineTerminator here]
7198 // quirk in the grammar.
7199 case TokenKind::Eol:
7200 // The rest of these make up the complete set of tokens that can
7201 // appear after any of the places where AssignmentExpression is used
7202 // throughout the grammar. Conveniently, none of them can also be the
7203 // start an expression.
7204 case TokenKind::Eof:
7205 case TokenKind::Semi:
7206 case TokenKind::RightCurly:
7207 case TokenKind::RightBracket:
7208 case TokenKind::RightParen:
7209 case TokenKind::Colon:
7210 case TokenKind::Comma:
7211 case TokenKind::In: // Annex B.3.6 `for (x = yield in y) ;`
7212 // No value.
7213 exprNode = null();
7214 break;
7215 case TokenKind::Mul:
7216 kind = ParseNodeKind::YieldStarExpr;
7217 tokenStream.consumeKnownToken(TokenKind::Mul, TokenStream::SlashIsRegExp);
7218 [[fallthrough]];
7219 default:
7220 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)
7221 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)
;
7222 }
7223 if (kind == ParseNodeKind::YieldStarExpr) {
7224 return handler_.newYieldStarExpression(begin, exprNode);
7225 }
7226 return handler_.newYieldExpression(begin, exprNode);
7227}
7228
7229template <class ParseHandler, typename Unit>
7230typename ParseHandler::BinaryNodeResult
7231GeneralParser<ParseHandler, Unit>::withStatement(YieldHandling yieldHandling) {
7232 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"
, 7232); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 7232; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7233 uint32_t begin = pos().begin;
7234
7235 if (pc_->sc()->strict()) {
7236 if (!strictModeError(JSMSG_STRICT_CODE_WITH)) {
7237 return errorResult();
7238 }
7239 }
7240
7241 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_WITH)) {
7242 return errorResult();
7243 }
7244
7245 Node objectExpr;
7246 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)
7247 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)
;
7248
7249 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_WITH)) {
7250 return errorResult();
7251 }
7252
7253 Node innerBlock;
7254 {
7255 ParseContext::Statement stmt(pc_, StatementKind::With);
7256 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)
;
7257 }
7258
7259 pc_->sc()->setBindingsAccessedDynamically();
7260
7261 return handler_.newWithStatement(begin, objectExpr, innerBlock);
7262}
7263
7264template <class ParseHandler, typename Unit>
7265typename ParseHandler::NodeResult
7266GeneralParser<ParseHandler, Unit>::labeledItem(YieldHandling yieldHandling) {
7267 TokenKind tt;
7268 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
7269 return errorResult();
7270 }
7271
7272 if (tt == TokenKind::Function) {
7273 TokenKind next;
7274 if (!tokenStream.peekToken(&next)) {
7275 return errorResult();
7276 }
7277
7278 // GeneratorDeclaration is only matched by HoistableDeclaration in
7279 // StatementListItem, so generators can't be inside labels.
7280 if (next == TokenKind::Mul) {
7281 error(JSMSG_GENERATOR_LABEL);
7282 return errorResult();
7283 }
7284
7285 // Per 13.13.1 it's a syntax error if LabelledItem: FunctionDeclaration
7286 // is ever matched. Per Annex B.3.2 that modifies this text, this
7287 // applies only to strict mode code.
7288 if (pc_->sc()->strict()) {
7289 error(JSMSG_FUNCTION_LABEL);
7290 return errorResult();
7291 }
7292
7293 return functionStmt(pos().begin, yieldHandling, NameRequired);
7294 }
7295
7296 anyChars.ungetToken();
7297 return statement(yieldHandling);
7298}
7299
7300template <class ParseHandler, typename Unit>
7301typename ParseHandler::LabeledStatementResult
7302GeneralParser<ParseHandler, Unit>::labeledStatement(
7303 YieldHandling yieldHandling) {
7304 TaggedParserAtomIndex label = labelIdentifier(yieldHandling);
7305 if (!label) {
7306 return errorResult();
7307 }
7308
7309 auto hasSameLabel = [&label](ParseContext::LabelStatement* stmt) {
7310 return stmt->label() == label;
7311 };
7312
7313 uint32_t begin = pos().begin;
7314
7315 if (pc_->template findInnermostStatement<ParseContext::LabelStatement>(
7316 hasSameLabel)) {
7317 errorAt(begin, JSMSG_DUPLICATE_LABEL);
7318 return errorResult();
7319 }
7320
7321 tokenStream.consumeKnownToken(TokenKind::Colon);
7322
7323 /* Push a label struct and parse the statement. */
7324 ParseContext::LabelStatement stmt(pc_, label);
7325 Node pn;
7326 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)
;
7327
7328 return handler_.newLabeledStatement(label, pn, begin);
7329}
7330
7331template <class ParseHandler, typename Unit>
7332typename ParseHandler::UnaryNodeResult
7333GeneralParser<ParseHandler, Unit>::throwStatement(YieldHandling yieldHandling) {
7334 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"
, 7334); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Throw)"
")"); do { *((volatile int*)__null) = 7334; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7335 uint32_t begin = pos().begin;
7336
7337 /* ECMA-262 Edition 3 says 'throw [no LineTerminator here] Expr'. */
7338 TokenKind tt = TokenKind::Eof;
7339 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7340 return errorResult();
7341 }
7342 if (tt == TokenKind::Eof || tt == TokenKind::Semi ||
7343 tt == TokenKind::RightCurly) {
7344 error(JSMSG_MISSING_EXPR_AFTER_THROW);
7345 return errorResult();
7346 }
7347 if (tt == TokenKind::Eol) {
7348 error(JSMSG_LINE_BREAK_AFTER_THROW);
7349 return errorResult();
7350 }
7351
7352 Node throwExpr;
7353 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)
;
7354
7355 if (!matchOrInsertSemicolon()) {
7356 return errorResult();
7357 }
7358
7359 return handler_.newThrowStatement(throwExpr, TokenPos(begin, pos().end));
7360}
7361
7362template <class ParseHandler, typename Unit>
7363typename ParseHandler::TernaryNodeResult
7364GeneralParser<ParseHandler, Unit>::tryStatement(YieldHandling yieldHandling) {
7365 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"
, 7365); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Try)"
")"); do { *((volatile int*)__null) = 7365; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7366 uint32_t begin = pos().begin;
7367
7368 /*
7369 * try nodes are ternary.
7370 * kid1 is the try statement
7371 * kid2 is the catch node list or null
7372 * kid3 is the finally statement
7373 *
7374 * catch nodes are binary.
7375 * left is the catch-name/pattern or null
7376 * right is the catch block
7377 *
7378 * catch lvalue nodes are either:
7379 * a single identifier
7380 * TokenKind::RightBracket for a destructuring left-hand side
7381 * TokenKind::RightCurly for a destructuring left-hand side
7382 *
7383 * finally nodes are TokenKind::LeftCurly statement lists.
7384 */
7385
7386 Node innerBlock;
7387 {
7388 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_TRY)) {
7389 return errorResult();
7390 }
7391
7392 uint32_t openedPos = pos().begin;
7393
7394 ParseContext::Statement stmt(pc_, StatementKind::Try);
7395 ParseContext::Scope scope(this);
7396 if (!scope.init(pc_)) {
7397 return errorResult();
7398 }
7399
7400 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)
;
7401
7402 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)
;
7403
7404 if (!mustMatchToken(
7405 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7406 this->reportMissingClosing(JSMSG_CURLY_AFTER_TRY,
7407 JSMSG_CURLY_OPENED, openedPos);
7408 })) {
7409 return errorResult();
7410 }
7411 }
7412
7413 LexicalScopeNodeType catchScope = null();
7414 TokenKind tt;
7415 if (!tokenStream.getToken(&tt)) {
7416 return errorResult();
7417 }
7418 if (tt == TokenKind::Catch) {
7419 /*
7420 * Create a lexical scope node around the whole catch clause,
7421 * including the head.
7422 */
7423 ParseContext::Statement stmt(pc_, StatementKind::Catch);
7424 ParseContext::Scope scope(this);
7425 if (!scope.init(pc_)) {
7426 return errorResult();
7427 }
7428
7429 /*
7430 * Legal catch forms are:
7431 * catch (lhs) {
7432 * catch {
7433 * where lhs is a name or a destructuring left-hand side.
7434 */
7435 bool omittedBinding;
7436 if (!tokenStream.matchToken(&omittedBinding, TokenKind::LeftCurly)) {
7437 return errorResult();
7438 }
7439
7440 Node catchName;
7441 if (omittedBinding) {
7442 catchName = null();
7443 } else {
7444 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_CATCH)) {
7445 return errorResult();
7446 }
7447
7448 if (!tokenStream.getToken(&tt)) {
7449 return errorResult();
7450 }
7451 switch (tt) {
7452 case TokenKind::LeftBracket:
7453 case TokenKind::LeftCurly:
7454 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)
7455 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)
7456 yieldHandling, tt))do { auto mozTryVarTempResult_ = (destructuringDeclaration(DeclarationKind
::CatchParameter, yieldHandling, tt)); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
;
7457 break;
7458
7459 default: {
7460 if (!TokenKindIsPossibleIdentifierName(tt)) {
7461 error(JSMSG_CATCH_IDENTIFIER);
7462 return errorResult();
7463 }
7464
7465 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)
7466 bindingIdentifier(DeclarationKind::SimpleCatchParameter,do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7467 yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
;
7468 break;
7469 }
7470 }
7471
7472 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_CATCH)) {
7473 return errorResult();
7474 }
7475
7476 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_CATCH)) {
7477 return errorResult();
7478 }
7479 }
7480
7481 LexicalScopeNodeType catchBody;
7482 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)
;
7483
7484 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)
;
7485
7486 if (!handler_.setupCatchScope(catchScope, catchName, catchBody)) {
7487 return errorResult();
7488 }
7489 handler_.setEndPosition(catchScope, pos().end);
7490
7491 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
7492 return errorResult();
7493 }
7494 }
7495
7496 Node finallyBlock = null();
7497
7498 if (tt == TokenKind::Finally) {
7499 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_FINALLY)) {
7500 return errorResult();
7501 }
7502
7503 uint32_t openedPos = pos().begin;
7504
7505 ParseContext::Statement stmt(pc_, StatementKind::Finally);
7506 ParseContext::Scope scope(this);
7507 if (!scope.init(pc_)) {
7508 return errorResult();
7509 }
7510
7511 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)
;
7512
7513 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)
;
7514
7515 if (!mustMatchToken(
7516 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7517 this->reportMissingClosing(JSMSG_CURLY_AFTER_FINALLY,
7518 JSMSG_CURLY_OPENED, openedPos);
7519 })) {
7520 return errorResult();
7521 }
7522 } else {
7523 anyChars.ungetToken();
7524 }
7525 if (!catchScope && !finallyBlock) {
7526 error(JSMSG_CATCH_OR_FINALLY);
7527 return errorResult();
7528 }
7529
7530 return handler_.newTryStatement(begin, innerBlock, catchScope, finallyBlock);
7531}
7532
7533template <class ParseHandler, typename Unit>
7534typename ParseHandler::LexicalScopeNodeResult
7535GeneralParser<ParseHandler, Unit>::catchBlockStatement(
7536 YieldHandling yieldHandling, ParseContext::Scope& catchParamScope) {
7537 uint32_t openedPos = pos().begin;
7538
7539 ParseContext::Statement stmt(pc_, StatementKind::Block);
7540
7541 // ES 13.15.7 CatchClauseEvaluation
7542 //
7543 // Step 8 means that the body of a catch block always has an additional
7544 // lexical scope.
7545 ParseContext::Scope scope(this);
7546 if (!scope.init(pc_)) {
7547 return errorResult();
7548 }
7549
7550 // The catch parameter names cannot be redeclared inside the catch
7551 // block, so declare the name in the inner scope.
7552 if (!scope.addCatchParameters(pc_, catchParamScope)) {
7553 return errorResult();
7554 }
7555
7556 ListNodeType list;
7557 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)
;
7558
7559 if (!mustMatchToken(
7560 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7561 this->reportMissingClosing(JSMSG_CURLY_AFTER_CATCH,
7562 JSMSG_CURLY_OPENED, openedPos);
7563 })) {
7564 return errorResult();
7565 }
7566
7567 // The catch parameter names are not bound in the body scope, so remove
7568 // them before generating bindings.
7569 scope.removeCatchParameters(pc_, catchParamScope);
7570 return finishLexicalScope(scope, list);
7571}
7572
7573template <class ParseHandler, typename Unit>
7574typename ParseHandler::DebuggerStatementResult
7575GeneralParser<ParseHandler, Unit>::debuggerStatement() {
7576 TokenPos p;
7577 p.begin = pos().begin;
7578 if (!matchOrInsertSemicolon()) {
7579 return errorResult();
7580 }
7581 p.end = pos().end;
7582
7583 return handler_.newDebuggerStatement(p);
7584}
7585
7586static AccessorType ToAccessorType(PropertyType propType) {
7587 switch (propType) {
7588 case PropertyType::Getter:
7589 return AccessorType::Getter;
7590 case PropertyType::Setter:
7591 return AccessorType::Setter;
7592 case PropertyType::Normal:
7593 case PropertyType::Method:
7594 case PropertyType::GeneratorMethod:
7595 case PropertyType::AsyncMethod:
7596 case PropertyType::AsyncGeneratorMethod:
7597 case PropertyType::Constructor:
7598 case PropertyType::DerivedConstructor:
7599 return AccessorType::None;
7600 default:
7601 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"
, 7601); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected property type"
")"); do { *((volatile int*)__null) = 7601; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
7602 }
7603}
7604
7605#ifdef ENABLE_DECORATORS
7606template <class ParseHandler, typename Unit>
7607typename ParseHandler::ListNodeResult
7608GeneralParser<ParseHandler, Unit>::decoratorList(YieldHandling yieldHandling) {
7609 ListNodeType decorators;
7610 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)
7611 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)
;
7612
7613 // Build a decorator list element. At each entry point to this loop we have
7614 // already consumed the |@| token
7615 TokenKind tt;
7616 for (;;) {
7617 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
7618 return errorResult();
7619 }
7620
7621 Node decorator;
7622 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)
;
7623
7624 handler_.addList(decorators, decorator);
7625
7626 if (!tokenStream.getToken(&tt)) {
7627 return errorResult();
7628 }
7629 if (tt != TokenKind::At) {
7630 anyChars.ungetToken();
7631 break;
7632 }
7633 }
7634 return decorators;
7635}
7636#endif
7637
7638template <class ParseHandler, typename Unit>
7639bool GeneralParser<ParseHandler, Unit>::classMember(
7640 YieldHandling yieldHandling, const ParseContext::ClassStatement& classStmt,
7641 TaggedParserAtomIndex className, uint32_t classStartOffset,
7642 HasHeritage hasHeritage, ClassInitializedMembers& classInitializedMembers,
7643 ListNodeType& classMembers, bool* done) {
7644 *done = false;
7645
7646 TokenKind tt;
7647 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
1
Assuming the condition is false
2
Taking false branch
7648 return false;
7649 }
7650 if (tt == TokenKind::RightCurly) {
3
Assuming 'tt' is not equal to RightCurly
4
Taking false branch
7651 *done = true;
7652 return true;
7653 }
7654
7655 if (tt == TokenKind::Semi) {
5
Assuming 'tt' is not equal to Semi
6
Taking false branch
7656 return true;
7657 }
7658
7659#ifdef ENABLE_DECORATORS
7660 ListNodeType decorators = null();
7661 if (tt == TokenKind::At) {
7662 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)
;
7663
7664 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
7665 return false;
7666 }
7667 }
7668#endif
7669
7670 bool isStatic = false;
7671 if (tt == TokenKind::Static) {
7
Assuming 'tt' is not equal to Static
8
Taking false branch
7672 if (!tokenStream.peekToken(&tt)) {
7673 return false;
7674 }
7675
7676 if (tt == TokenKind::LeftCurly) {
7677 /* Parsing static class block: static { ... } */
7678 FunctionNodeType staticBlockBody;
7679 MOZ_TRY_VAR_OR_RETURN(staticBlockBody,do { auto parserTryVarTempResult_ = (staticClassBlock(classInitializedMembers
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (staticBlockBody) = parserTryVarTempResult_
.unwrap(); } while (0)
7680 staticClassBlock(classInitializedMembers), false)do { auto parserTryVarTempResult_ = (staticClassBlock(classInitializedMembers
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (staticBlockBody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7681
7682 StaticClassBlockType classBlock;
7683 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newStaticClassBlock
(staticBlockBody)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (classBlock) = parserTryVarTempResult_
.unwrap(); } while (0)
7684 classBlock, handler_.newStaticClassBlock(staticBlockBody), false)do { auto parserTryVarTempResult_ = (handler_.newStaticClassBlock
(staticBlockBody)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (classBlock) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7685
7686 return handler_.addClassMemberDefinition(classMembers, classBlock);
7687 }
7688
7689 if (tt != TokenKind::LeftParen && tt != TokenKind::Assign &&
7690 tt != TokenKind::Semi && tt != TokenKind::RightCurly) {
7691 isStatic = true;
7692 } else {
7693 anyChars.ungetToken();
7694 }
7695 } else {
7696 anyChars.ungetToken();
7697 }
7698
7699 uint32_t propNameOffset;
7700 if (!tokenStream.peekOffset(&propNameOffset, TokenStream::SlashIsInvalid)) {
9
Taking false branch
7701 return false;
7702 }
7703
7704 TaggedParserAtomIndex propAtom;
7705 PropertyType propType;
7706 Node propName;
7707 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)
10
Taking false branch
7708 propName,do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7709 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)
7710 /* 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)
7711 &propAtom),do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7712 false)do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7713
7714 if (propType
10.1
'propType' is not equal to Field
10.1
'propType' is not equal to Field
10.1
'propType' is not equal to Field
10.1
'propType' is not equal to Field
10.1
'propType' is not equal to Field
== PropertyType::Field ||
7715 propType
10.2
'propType' is not equal to FieldWithAccessor
10.2
'propType' is not equal to FieldWithAccessor
10.2
'propType' is not equal to FieldWithAccessor
10.2
'propType' is not equal to FieldWithAccessor
10.2
'propType' is not equal to FieldWithAccessor
== PropertyType::FieldWithAccessor) {
7716 if (isStatic) {
7717 if (propAtom == TaggedParserAtomIndex::WellKnown::prototype()) {
7718 errorAt(propNameOffset, JSMSG_CLASS_STATIC_PROTO);
7719 return false;
7720 }
7721 }
7722
7723 if (propAtom == TaggedParserAtomIndex::WellKnown::constructor()) {
7724 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7725 return false;
7726 }
7727
7728 if (handler_.isPrivateName(propName)) {
7729 if (propAtom == TaggedParserAtomIndex::WellKnown::hash_constructor_()) {
7730 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7731 return false;
7732 }
7733
7734 auto privateName = propAtom;
7735 if (!noteDeclaredPrivateName(
7736 propName, privateName, propType,
7737 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7738 pos())) {
7739 return false;
7740 }
7741 }
7742
7743#ifdef ENABLE_DECORATORS
7744 ClassMethodType accessorGetterNode = null();
7745 ClassMethodType accessorSetterNode = null();
7746 if (propType == PropertyType::FieldWithAccessor) {
7747 // Decorators Proposal
7748 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-runtime-semantics-classfielddefinitionevaluation
7749 //
7750 // FieldDefinition : accessor ClassElementName Initializeropt
7751 //
7752 // Step 1. Let name be the result of evaluating ClassElementName.
7753 // ...
7754 // Step 3. Let privateStateDesc be the string-concatenation of name
7755 // and " accessor storage".
7756 StringBuilder privateStateDesc(fc_);
7757 if (!privateStateDesc.append(this->parserAtoms(), propAtom)) {
7758 return false;
7759 }
7760 if (!privateStateDesc.append(" accessor storage")) {
7761 return false;
7762 }
7763 // Step 4. Let privateStateName be a new Private Name whose
7764 // [[Description]] value is privateStateDesc.
7765 TokenPos propNamePos(propNameOffset, pos().end);
7766 auto privateStateName =
7767 privateStateDesc.finishParserAtom(this->parserAtoms(), fc_);
7768 if (!noteDeclaredPrivateName(
7769 propName, privateStateName, propType,
7770 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7771 propNamePos)) {
7772 return false;
7773 }
7774
7775 // Step 5. Let getter be MakeAutoAccessorGetter(homeObject, name,
7776 // privateStateName).
7777 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)
7778 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)
7779 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)
7780 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)
7781 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)
7782 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)
;
7783
7784 // If the accessor is not decorated or is a non-static private field,
7785 // add it to the class here. Otherwise, we'll handle this when the
7786 // decorators are called. We don't need to keep a reference to the node
7787 // after this except for non-static private accessors. Please see the
7788 // comment in the definition of ClassField for details.
7789 bool addAccessorImmediately =
7790 !decorators || (!isStatic && handler_.isPrivateName(propName));
7791 if (addAccessorImmediately) {
7792 if (!handler_.addClassMemberDefinition(classMembers,
7793 accessorGetterNode)) {
7794 return false;
7795 }
7796 if (!handler_.isPrivateName(propName)) {
7797 accessorGetterNode = null();
7798 }
7799 }
7800
7801 // Step 6. Let setter be MakeAutoAccessorSetter(homeObject, name,
7802 // privateStateName).
7803 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)
7804 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)
7805 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)
7806 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)
7807 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)
7808 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)
;
7809
7810 if (addAccessorImmediately) {
7811 if (!handler_.addClassMemberDefinition(classMembers,
7812 accessorSetterNode)) {
7813 return false;
7814 }
7815 if (!handler_.isPrivateName(propName)) {
7816 accessorSetterNode = null();
7817 }
7818 }
7819
7820 // Step 10. Return ClassElementDefinition Record { [[Key]]: name,
7821 // [[Kind]]: accessor, [[Get]]: getter, [[Set]]: setter,
7822 // [[BackingStorageKey]]: privateStateName, [[Initializers]]:
7823 // initializers, [[Decorators]]: empty }.
7824 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)
7825 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)
;
7826 propAtom = privateStateName;
7827 // We maintain `decorators` here to perform this step at the same time:
7828 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-static-semantics-classelementevaluation
7829 // 4. Set fieldDefinition.[[Decorators]] to decorators.
7830 }
7831#endif
7832 if (isStatic) {
7833 classInitializedMembers.staticFields++;
7834 } else {
7835 classInitializedMembers.instanceFields++;
7836#ifdef ENABLE_DECORATORS
7837 if (decorators) {
7838 classInitializedMembers.hasInstanceDecorators = true;
7839 }
7840#endif
7841 }
7842
7843 TokenPos propNamePos(propNameOffset, pos().end);
7844 FunctionNodeType initializer;
7845 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)
7846 initializer,do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7847 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)
7848 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)
7849 false)do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7850
7851 if (!matchOrInsertSemicolon(TokenStream::SlashIsInvalid)) {
7852 return false;
7853 }
7854
7855 ClassFieldType field;
7856 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)
7857 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)
7858 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)
7859#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)
7860 ,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)
7861 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)
7862#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)
7863 ),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 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)
;
7865
7866 return handler_.addClassMemberDefinition(classMembers, field);
7867 }
7868
7869 if (propType
10.3
'propType' is not equal to Getter
10.3
'propType' is not equal to Getter
10.3
'propType' is not equal to Getter
10.3
'propType' is not equal to Getter
10.3
'propType' is not equal to Getter
!= PropertyType::Getter && propType
10.4
'propType' is not equal to Setter
10.4
'propType' is not equal to Setter
10.4
'propType' is not equal to Setter
10.4
'propType' is not equal to Setter
10.4
'propType' is not equal to Setter
!= PropertyType::Setter &&
7870 propType
10.5
'propType' is equal to Method
10.5
'propType' is equal to Method
10.5
'propType' is equal to Method
10.5
'propType' is equal to Method
10.5
'propType' is equal to Method
!= PropertyType::Method &&
7871 propType != PropertyType::GeneratorMethod &&
7872 propType != PropertyType::AsyncMethod &&
7873 propType != PropertyType::AsyncGeneratorMethod) {
7874 errorAt(propNameOffset, JSMSG_BAD_CLASS_MEMBER_DEF);
7875 return false;
7876 }
7877
7878 bool isConstructor =
7879 !isStatic
10.6
'isStatic' is false
10.6
'isStatic' is false
10.6
'isStatic' is false
10.6
'isStatic' is false
10.6
'isStatic' is false
&& propAtom == TaggedParserAtomIndex::WellKnown::constructor();
7880 if (isConstructor
10.7
'isConstructor' is false
10.7
'isConstructor' is false
10.7
'isConstructor' is false
10.7
'isConstructor' is false
10.7
'isConstructor' is false
) {
7881 if (propType != PropertyType::Method) {
7882 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7883 return false;
7884 }
7885 if (classStmt.constructorBox) {
7886 errorAt(propNameOffset, JSMSG_DUPLICATE_CONSTRUCTOR);
7887 return false;
7888 }
7889 propType = hasHeritage == HasHeritage::Yes
7890 ? PropertyType::DerivedConstructor
7891 : PropertyType::Constructor;
7892 } else if (isStatic
10.8
'isStatic' is false
10.8
'isStatic' is false
10.8
'isStatic' is false
10.8
'isStatic' is false
10.8
'isStatic' is false
&&
11
Taking false branch
7893 propAtom == TaggedParserAtomIndex::WellKnown::prototype()) {
7894 errorAt(propNameOffset, JSMSG_CLASS_STATIC_PROTO);
7895 return false;
7896 }
7897
7898 TaggedParserAtomIndex funName;
7899 switch (propType) {
12
Control jumps to the 'default' case at line 7916
7900 case PropertyType::Getter:
7901 case PropertyType::Setter: {
7902 bool hasStaticName =
7903 !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom;
7904 if (hasStaticName) {
7905 funName = prefixAccessorName(propType, propAtom);
7906 if (!funName) {
7907 return false;
7908 }
7909 }
7910 break;
7911 }
7912 case PropertyType::Constructor:
7913 case PropertyType::DerivedConstructor:
7914 funName = className;
7915 break;
7916 default:
7917 if (!anyChars.isCurrentTokenType(TokenKind::RightBracket)) {
13
Taking false branch
7918 funName = propAtom;
7919 }
7920 }
7921
7922 // When |super()| is invoked, we search for the nearest scope containing
7923 // |.initializers| to initialize the class fields. This set-up precludes
7924 // declaring |.initializers| in the class scope, because in some syntactic
7925 // contexts |super()| can appear nested in a class, while actually belonging
7926 // to an outer class definition.
7927 //
7928 // Example:
7929 // class Outer extends Base {
7930 // field = 1;
7931 // constructor() {
7932 // class Inner {
7933 // field = 2;
7934 //
7935 // // The super() call in the computed property name mustn't access
7936 // // Inner's |.initializers| array, but instead Outer's.
7937 // [super()]() {}
7938 // }
7939 // }
7940 // }
7941 Maybe<ParseContext::Scope> dotInitializersScope;
7942 if (isConstructor
13.1
'isConstructor' is false
13.1
'isConstructor' is false
13.1
'isConstructor' is false
13.1
'isConstructor' is false
13.1
'isConstructor' is false
&& !options().selfHostingMode) {
7943 dotInitializersScope.emplace(this);
7944 if (!dotInitializersScope->init(pc_)) {
7945 return false;
7946 }
7947
7948 if (!noteDeclaredName(TaggedParserAtomIndex::WellKnown::dot_initializers_(),
7949 DeclarationKind::Let, pos())) {
7950 return false;
7951 }
7952
7953#ifdef ENABLE_DECORATORS
7954 if (!noteDeclaredName(
7955 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
7956 DeclarationKind::Let, pos())) {
7957 return false;
7958 }
7959#endif
7960 }
7961
7962 // Calling toString on constructors need to return the source text for
7963 // the entire class. The end offset is unknown at this point in
7964 // parsing and will be amended when class parsing finishes below.
7965 FunctionNodeType funNode;
7966 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)
14
'?' condition is false
15
Taking true branch
16
Calling implicit destructor for 'Maybe<js::frontend::ParseContext::Scope>'
17
Calling '~MaybeStorage'
7967 funNode,do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7968 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)
7969 propType, funName),do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7970 false)do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
;
7971
7972 AccessorType atype = ToAccessorType(propType);
7973
7974 Maybe<FunctionNodeType> initializerIfPrivate = Nothing();
7975 if (handler_.isPrivateName(propName)) {
7976 if (propAtom == TaggedParserAtomIndex::WellKnown::hash_constructor_()) {
7977 // #constructor is an invalid private name.
7978 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7979 return false;
7980 }
7981
7982 TaggedParserAtomIndex privateName = propAtom;
7983 if (!noteDeclaredPrivateName(
7984 propName, privateName, propType,
7985 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7986 pos())) {
7987 return false;
7988 }
7989
7990 // Private non-static methods are stored in the class body environment.
7991 // Private non-static accessors are stamped onto every instance using
7992 // initializers. Private static methods are stamped onto the constructor
7993 // during class evaluation; see BytecodeEmitter::emitPropertyList.
7994 if (!isStatic) {
7995 if (atype == AccessorType::Getter || atype == AccessorType::Setter) {
7996 classInitializedMembers.privateAccessors++;
7997 TokenPos propNamePos(propNameOffset, pos().end);
7998 FunctionNodeType initializerNode;
7999 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)
8000 initializerNode,do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8001 synthesizePrivateMethodInitializer(propAtom, atype, propNamePos),do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8002 false)do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8003 initializerIfPrivate = Some(initializerNode);
8004 } else {
8005 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"
, 8005); AnnotateMozCrashReason("MOZ_ASSERT" "(" "atype == AccessorType::None"
")"); do { *((volatile int*)__null) = 8005; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8006 classInitializedMembers.privateMethods++;
8007 }
8008 }
8009 }
8010
8011#ifdef ENABLE_DECORATORS
8012 if (decorators) {
8013 classInitializedMembers.hasInstanceDecorators = true;
8014 }
8015#endif
8016
8017 Node method;
8018 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)
8019 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)
8020 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)
8021 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)
8022#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)
8023 ,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)
8024 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)
8025#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)
8026 ),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 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)
;
8028
8029 if (dotInitializersScope.isSome()) {
8030 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(*dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (method) = parserTryVarTempResult_
.unwrap(); } while (0)
8031 method, finishLexicalScope(*dotInitializersScope, method), false)do { auto parserTryVarTempResult_ = (finishLexicalScope(*dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (method) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8032 dotInitializersScope.reset();
8033 }
8034
8035 return handler_.addClassMemberDefinition(classMembers, method);
8036}
8037
8038template <class ParseHandler, typename Unit>
8039bool GeneralParser<ParseHandler, Unit>::finishClassConstructor(
8040 const ParseContext::ClassStatement& classStmt,
8041 TaggedParserAtomIndex className, HasHeritage hasHeritage,
8042 uint32_t classStartOffset, uint32_t classEndOffset,
8043 const ClassInitializedMembers& classInitializedMembers,
8044 ListNodeType& classMembers) {
8045 if (classStmt.constructorBox == nullptr) {
8046 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"
, 8046); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 8046; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8047 // Unconditionally create the scope here, because it's always the
8048 // constructor.
8049 ParseContext::Scope dotInitializersScope(this);
8050 if (!dotInitializersScope.init(pc_)) {
8051 return false;
8052 }
8053
8054 if (!noteDeclaredName(TaggedParserAtomIndex::WellKnown::dot_initializers_(),
8055 DeclarationKind::Let, pos())) {
8056 return false;
8057 }
8058
8059#ifdef ENABLE_DECORATORS
8060 if (!noteDeclaredName(
8061 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
8062 DeclarationKind::Let, pos(), ClosedOver::Yes)) {
8063 return false;
8064 }
8065#endif
8066
8067 // synthesizeConstructor assigns to classStmt.constructorBox
8068 TokenPos synthesizedBodyPos(classStartOffset, classEndOffset);
8069 FunctionNodeType synthesizedCtor;
8070 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)
8071 synthesizedCtor,do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8072 synthesizeConstructor(className, synthesizedBodyPos, hasHeritage),do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8073 false)do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
;
8074
8075 // Note: the *function* has the name of the class, but the *property*
8076 // containing the function has the name "constructor"
8077 Node constructorNameNode;
8078 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)
8079 constructorNameNode,do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8080 handler_.newObjectLiteralPropertyName(do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8081 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)
8082 false)do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8083 ClassMethodType method;
8084 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)
8085 handler_.newDefaultClassConstructor(do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8086 constructorNameNode, synthesizedCtor),do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8087 false)do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
;
8088 LexicalScopeNodeType scope;
8089 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (scope) = parserTryVarTempResult_
.unwrap(); } while (0)
8090 scope, finishLexicalScope(dotInitializersScope, method), false)do { auto parserTryVarTempResult_ = (finishLexicalScope(dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (scope) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8091 if (!handler_.addClassMemberDefinition(classMembers, scope)) {
8092 return false;
8093 }
8094 }
8095
8096 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"
, 8096); AnnotateMozCrashReason("MOZ_ASSERT" "(" "classStmt.constructorBox"
")"); do { *((volatile int*)__null) = 8096; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8097 FunctionBox* ctorbox = classStmt.constructorBox;
8098
8099 // Amend the toStringEnd offset for the constructor now that we've
8100 // finished parsing the class.
8101 ctorbox->setCtorToStringEnd(classEndOffset);
8102
8103 size_t numMemberInitializers = classInitializedMembers.privateAccessors +
8104 classInitializedMembers.instanceFields;
8105 bool hasPrivateBrand = classInitializedMembers.hasPrivateBrand();
8106 if (hasPrivateBrand || numMemberInitializers > 0) {
8107 // Now that we have full set of initializers, update the constructor.
8108 MemberInitializers initializers(
8109 hasPrivateBrand,
8110#ifdef ENABLE_DECORATORS
8111 classInitializedMembers.hasInstanceDecorators,
8112#endif
8113 numMemberInitializers);
8114 ctorbox->setMemberInitializers(initializers);
8115
8116 // Field initialization need access to `this`.
8117 ctorbox->setCtorFunctionHasThisBinding();
8118 }
8119
8120 return true;
8121}
8122
8123template <class ParseHandler, typename Unit>
8124typename ParseHandler::ClassNodeResult
8125GeneralParser<ParseHandler, Unit>::classDefinition(
8126 YieldHandling yieldHandling, ClassContext classContext,
8127 DefaultHandling defaultHandling) {
8128#ifdef ENABLE_DECORATORS
8129 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"
, 8130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8130; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
8130 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"
, 8130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8130; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8131
8132 ListNodeType decorators = null();
8133 FunctionNodeType addInitializerFunction = null();
8134 if (anyChars.isCurrentTokenType(TokenKind::At)) {
8135 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)
;
8136 TokenKind next;
8137 if (!tokenStream.getToken(&next)) {
8138 return errorResult();
8139 }
8140 if (next != TokenKind::Class) {
8141 error(JSMSG_CLASS_EXPECTED);
8142 return errorResult();
8143 }
8144 }
8145#else
8146 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"
, 8146); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8146; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8147#endif
8148
8149 uint32_t classStartOffset = pos().begin;
8150 bool savedStrictness = setLocalStrictMode(true);
8151
8152 // Classes are quite broken in self-hosted code.
8153 if (options().selfHostingMode) {
8154 error(JSMSG_SELFHOSTED_CLASS);
8155 return errorResult();
8156 }
8157
8158 TokenKind tt;
8159 if (!tokenStream.getToken(&tt)) {
8160 return errorResult();
8161 }
8162
8163 TaggedParserAtomIndex className;
8164 if (TokenKindIsPossibleIdentifier(tt)) {
8165 className = bindingIdentifier(yieldHandling);
8166 if (!className) {
8167 return errorResult();
8168 }
8169 } else if (classContext == ClassStatement) {
8170 if (defaultHandling == AllowDefaultName) {
8171 className = TaggedParserAtomIndex::WellKnown::default_();
8172 anyChars.ungetToken();
8173 } else {
8174 // Class statements must have a bound name
8175 error(JSMSG_UNNAMED_CLASS_STMT);
8176 return errorResult();
8177 }
8178 } else {
8179 // Make sure to put it back, whatever it was
8180 anyChars.ungetToken();
8181 }
8182
8183 // Because the binding definitions keep track of their blockId, we need to
8184 // create at least the inner binding later. Keep track of the name's
8185 // position in order to provide it for the nodes created later.
8186 TokenPos namePos = pos();
8187
8188 auto isClass = [](ParseContext::Statement* stmt) {
8189 return stmt->kind() == StatementKind::Class;
8190 };
8191
8192 bool isInClass = pc_->sc()->inClass() || pc_->findInnermostStatement(isClass);
8193
8194 // Push a ParseContext::ClassStatement to keep track of the constructor
8195 // funbox.
8196 ParseContext::ClassStatement classStmt(pc_);
8197
8198 NameNodeType innerName;
8199 Node nameNode = null();
8200 Node classHeritage = null();
8201 LexicalScopeNodeType classBlock = null();
8202 ClassBodyScopeNodeType classBodyBlock = null();
8203 uint32_t classEndOffset;
8204 {
8205 // A named class creates a new lexical scope with a const binding of the
8206 // class name for the "inner name".
8207 ParseContext::Statement innerScopeStmt(pc_, StatementKind::Block);
8208 ParseContext::Scope innerScope(this);
8209 if (!innerScope.init(pc_)) {
8210 return errorResult();
8211 }
8212
8213 bool hasHeritageBool;
8214 if (!tokenStream.matchToken(&hasHeritageBool, TokenKind::Extends)) {
8215 return errorResult();
8216 }
8217 HasHeritage hasHeritage =
8218 hasHeritageBool ? HasHeritage::Yes : HasHeritage::No;
8219 if (hasHeritage == HasHeritage::Yes) {
8220 if (!tokenStream.getToken(&tt)) {
8221 return errorResult();
8222 }
8223 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)
8224 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)
;
8225 }
8226
8227 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_CLASS)) {
8228 return errorResult();
8229 }
8230
8231 {
8232 ParseContext::Statement bodyScopeStmt(pc_, StatementKind::Block);
8233 ParseContext::Scope bodyScope(this);
8234 if (!bodyScope.init(pc_)) {
8235 return errorResult();
8236 }
8237
8238 ListNodeType classMembers;
8239 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
)
;
8240
8241 ClassInitializedMembers classInitializedMembers{};
8242 for (;;) {
8243 bool done;
8244 if (!classMember(yieldHandling, classStmt, className, classStartOffset,
8245 hasHeritage, classInitializedMembers, classMembers,
8246 &done)) {
8247 return errorResult();
8248 }
8249 if (done) {
8250 break;
8251 }
8252 }
8253#ifdef ENABLE_DECORATORS
8254 if (classInitializedMembers.hasInstanceDecorators) {
8255 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)
8256 synthesizeAddInitializerFunction(do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8257 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)
8258 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)
8259 yieldHandling))do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
;
8260 }
8261#endif
8262
8263 if (classInitializedMembers.privateMethods +
8264 classInitializedMembers.privateAccessors >
8265 0) {
8266 // We declare `.privateBrand` as ClosedOver because the constructor
8267 // always uses it, even a default constructor. We could equivalently
8268 // `noteUsedName` when parsing the constructor, except that at that
8269 // time, we don't necessarily know if the class has a private brand.
8270 if (!noteDeclaredName(
8271 TaggedParserAtomIndex::WellKnown::dot_privateBrand_(),
8272 DeclarationKind::Synthetic, namePos, ClosedOver::Yes)) {
8273 return errorResult();
8274 }
8275 }
8276
8277 if (classInitializedMembers.instanceFieldKeys > 0) {
8278 if (!noteDeclaredName(
8279 TaggedParserAtomIndex::WellKnown::dot_fieldKeys_(),
8280 DeclarationKind::Synthetic, namePos)) {
8281 return errorResult();
8282 }
8283 }
8284
8285 if (classInitializedMembers.staticFields > 0) {
8286 if (!noteDeclaredName(
8287 TaggedParserAtomIndex::WellKnown::dot_staticInitializers_(),
8288 DeclarationKind::Synthetic, namePos)) {
8289 return errorResult();
8290 }
8291 }
8292
8293 if (classInitializedMembers.staticFieldKeys > 0) {
8294 if (!noteDeclaredName(
8295 TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_(),
8296 DeclarationKind::Synthetic, namePos)) {
8297 return errorResult();
8298 }
8299 }
8300
8301 classEndOffset = pos().end;
8302 if (!finishClassConstructor(classStmt, className, hasHeritage,
8303 classStartOffset, classEndOffset,
8304 classInitializedMembers, classMembers)) {
8305 return errorResult();
8306 }
8307
8308 MOZ_TRY_VAR(classBodyBlock,do { auto mozTryVarTempResult_ = (finishClassBodyScope(bodyScope
, classMembers)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBodyBlock) = mozTryVarTempResult_.unwrap(); } while (
0)
8309 finishClassBodyScope(bodyScope, classMembers))do { auto mozTryVarTempResult_ = (finishClassBodyScope(bodyScope
, classMembers)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBodyBlock) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8310
8311 // Pop the class body scope
8312 }
8313
8314 if (className) {
8315 // The inner name is immutable.
8316 if (!noteDeclaredName(className, DeclarationKind::Const, namePos)) {
8317 return errorResult();
8318 }
8319
8320 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)
;
8321 }
8322
8323 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)
;
8324
8325 // Pop the inner scope.
8326 }
8327
8328 if (className) {
8329 NameNodeType outerName = null();
8330 if (classContext == ClassStatement) {
8331 // The outer name is mutable.
8332 if (!noteDeclaredName(className, DeclarationKind::Class, namePos)) {
8333 return errorResult();
8334 }
8335
8336 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)
;
8337 }
8338
8339 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)
8340 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)
;
8341 }
8342 MOZ_ALWAYS_TRUE(setLocalStrictMode(savedStrictness))do { if ((__builtin_expect(!!(setLocalStrictMode(savedStrictness
)), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "setLocalStrictMode(savedStrictness)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8342); AnnotateMozCrashReason("MOZ_CRASH(" "setLocalStrictMode(savedStrictness)"
")"); do { *((volatile int*)__null) = 8342; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
8343 // We're leaving a class definition that was not itself nested within a class
8344 if (!isInClass) {
8345 mozilla::Maybe<UnboundPrivateName> maybeUnboundName;
8346 if (!usedNames_.hasUnboundPrivateNames(fc_, maybeUnboundName)) {
8347 return errorResult();
8348 }
8349 if (maybeUnboundName) {
8350 UniqueChars str =
8351 this->parserAtoms().toPrintableString(maybeUnboundName->atom);
8352 if (!str) {
8353 ReportOutOfMemory(this->fc_);
8354 return errorResult();
8355 }
8356
8357 errorAt(maybeUnboundName->position.begin, JSMSG_MISSING_PRIVATE_DECL,
8358 str.get());
8359 return errorResult();
8360 }
8361 }
8362
8363 return handler_.newClass(nameNode, classHeritage, classBlock,
8364#ifdef ENABLE_DECORATORS
8365 decorators, addInitializerFunction,
8366#endif
8367 TokenPos(classStartOffset, classEndOffset));
8368}
8369
8370template <class ParseHandler, typename Unit>
8371typename ParseHandler::FunctionNodeResult
8372GeneralParser<ParseHandler, Unit>::synthesizeConstructor(
8373 TaggedParserAtomIndex className, TokenPos synthesizedBodyPos,
8374 HasHeritage hasHeritage) {
8375 FunctionSyntaxKind functionSyntaxKind =
8376 hasHeritage == HasHeritage::Yes
8377 ? FunctionSyntaxKind::DerivedClassConstructor
8378 : FunctionSyntaxKind::ClassConstructor;
8379
8380 bool isSelfHosting = options().selfHostingMode;
8381 FunctionFlags flags =
8382 InitialFunctionFlags(functionSyntaxKind, GeneratorKind::NotGenerator,
8383 FunctionAsyncKind::SyncFunction, isSelfHosting);
8384
8385 // Create the top-level field initializer node.
8386 FunctionNodeType funNode;
8387 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)
8388 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)
;
8389
8390 // If we see any inner function, note it on our current context. The bytecode
8391 // emitter may eliminate the function later, but we use a conservative
8392 // definition for consistency between lazy and full parsing.
8393 pc_->sc()->setHasInnerFunctions();
8394
8395 // When fully parsing a lazy script, we do not fully reparse its inner
8396 // functions, which are also lazy. Instead, their free variables and source
8397 // extents are recorded and may be skipped.
8398 if (handler_.reuseLazyInnerFunctions()) {
8399 if (!skipLazyInnerFunction(funNode, synthesizedBodyPos.begin,
8400 /* tryAnnexB = */ false)) {
8401 return errorResult();
8402 }
8403
8404 return funNode;
8405 }
8406
8407 // Create the FunctionBox and link it to the function object.
8408 Directives directives(true);
8409 FunctionBox* funbox = newFunctionBox(
8410 funNode, className, flags, synthesizedBodyPos.begin, directives,
8411 GeneratorKind::NotGenerator, FunctionAsyncKind::SyncFunction);
8412 if (!funbox) {
8413 return errorResult();
8414 }
8415 funbox->initWithEnclosingParseContext(pc_, functionSyntaxKind);
8416 setFunctionEndFromCurrentToken(funbox);
8417
8418 // Mark this function as being synthesized by the parser. This means special
8419 // handling in delazification will be used since we don't have typical
8420 // function syntax.
8421 funbox->setSyntheticFunction();
8422
8423 // Push a SourceParseContext on to the stack.
8424 ParseContext* outerpc = pc_;
8425 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8426 if (!funpc.init()) {
8427 return errorResult();
8428 }
8429
8430 if (!synthesizeConstructorBody(synthesizedBodyPos, hasHeritage, funNode,
8431 funbox)) {
8432 return errorResult();
8433 }
8434
8435 if (!leaveInnerFunction(outerpc)) {
8436 return errorResult();
8437 }
8438
8439 return funNode;
8440}
8441
8442template <class ParseHandler, typename Unit>
8443bool GeneralParser<ParseHandler, Unit>::synthesizeConstructorBody(
8444 TokenPos synthesizedBodyPos, HasHeritage hasHeritage,
8445 FunctionNodeType funNode, FunctionBox* funbox) {
8446 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"
, 8446); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isClassConstructor()"
")"); do { *((volatile int*)__null) = 8446; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8447
8448 // Create a ParamsBodyNode for the parameters + body (there are no
8449 // parameters).
8450 ParamsBodyNodeType argsbody;
8451 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)
8452 false)do { auto parserTryVarTempResult_ = (handler_.newParamsBody(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8453 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8454 setFunctionStartAtPosition(funbox, synthesizedBodyPos);
8455
8456 if (hasHeritage == HasHeritage::Yes) {
8457 // Synthesize the equivalent to `function f(...args)`
8458 funbox->setHasRest();
8459 if (!notePositionalFormalParameter(
8460 funNode, TaggedParserAtomIndex::WellKnown::dot_args_(),
8461 synthesizedBodyPos.begin,
8462 /* disallowDuplicateParams = */ false,
8463 /* duplicatedParam = */ nullptr)) {
8464 return false;
8465 }
8466 funbox->setArgCount(1);
8467 } else {
8468 funbox->setArgCount(0);
8469 }
8470
8471 pc_->functionScope().useAsVarScope(pc_);
8472
8473 ListNodeType stmtList;
8474 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)
8475 false)do { auto parserTryVarTempResult_ = (handler_.newStatementList
(synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (stmtList) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8476
8477 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_this_())) {
8478 return false;
8479 }
8480
8481 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
8482 return false;
8483 }
8484
8485#ifdef ENABLE_DECORATORS
8486 if (!noteUsedName(
8487 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_())) {
8488 return false;
8489 }
8490#endif
8491
8492 if (hasHeritage == HasHeritage::Yes) {
8493 // |super()| implicitly reads |new.target|.
8494 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
8495 return false;
8496 }
8497
8498 NameNodeType thisName;
8499 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)
;
8500
8501 UnaryNodeType superBase;
8502 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)
8503 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)
;
8504
8505 ListNodeType arguments;
8506 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)
8507 false)do { auto parserTryVarTempResult_ = (handler_.newArguments(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (arguments) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8508
8509 NameNodeType argsNameNode;
8510 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)
8511 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)
8512 synthesizedBodyPos),do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
8513 false)do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
;
8514 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_args_())) {
8515 return false;
8516 }
8517
8518 UnaryNodeType spreadArgs;
8519 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)
8520 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)
8521 false)do { auto parserTryVarTempResult_ = (handler_.newSpread(synthesizedBodyPos
.begin, argsNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (spreadArgs) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8522 handler_.addList(arguments, spreadArgs);
8523
8524 CallNodeType superCall;
8525 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)
8526 superCall,do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
8527 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)
8528 false)do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8529
8530 BinaryNodeType setThis;
8531 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)
8532 false)do { auto parserTryVarTempResult_ = (handler_.newSetThis(thisName
, superCall)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (setThis) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8533
8534 UnaryNodeType exprStatement;
8535 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)
8536 exprStatement,do { auto parserTryVarTempResult_ = (handler_.newExprStatement
(setThis, synthesizedBodyPos.end)); if ((__builtin_expect(!!(
parserTryVarTempResult_.isErr()), 0))) { return (false); } (exprStatement
) = parserTryVarTempResult_.unwrap(); } while (0)
8537 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)
;
8538
8539 handler_.addStatementToList(stmtList, exprStatement);
8540 }
8541
8542 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8543 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8544 return false;
8545 }
8546 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8547 return false;
8548 }
8549
8550 LexicalScopeNodeType initializerBody;
8551 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)
8552 initializerBody,do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
8553 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)
8554 false)do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
;
8555 handler_.setBeginPosition(initializerBody, stmtList);
8556 handler_.setEndPosition(initializerBody, stmtList);
8557
8558 handler_.setFunctionBody(funNode, initializerBody);
8559
8560 return finishFunction();
8561}
8562
8563template <class ParseHandler, typename Unit>
8564typename ParseHandler::FunctionNodeResult
8565GeneralParser<ParseHandler, Unit>::privateMethodInitializer(
8566 TokenPos propNamePos, TaggedParserAtomIndex propAtom,
8567 TaggedParserAtomIndex storedMethodAtom) {
8568 if (!abortIfSyntaxParser()) {
8569 return errorResult();
8570 }
8571
8572 // Synthesize an initializer function that the constructor can use to stamp a
8573 // private method onto an instance object.
8574 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer;
8575 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8576 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8577 bool isSelfHosting = options().selfHostingMode;
8578 FunctionFlags flags =
8579 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8580
8581 FunctionNodeType funNode;
8582 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)
;
8583
8584 Directives directives(true);
8585 FunctionBox* funbox =
8586 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
8587 propNamePos.begin, directives, generatorKind, asyncKind);
8588 if (!funbox) {
8589 return errorResult();
8590 }
8591 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8592
8593 // Push a SourceParseContext on to the stack.
8594 ParseContext* outerpc = pc_;
8595 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8596 if (!funpc.init()) {
8597 return errorResult();
8598 }
8599 pc_->functionScope().useAsVarScope(pc_);
8600
8601 // Add empty parameter list.
8602 ParamsBodyNodeType argsbody;
8603 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)
;
8604 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8605 setFunctionStartAtCurrentToken(funbox);
8606 funbox->setArgCount(0);
8607
8608 // Note both the stored private method body and it's private name as being
8609 // used in the initializer. They will be emitted into the method body in the
8610 // BCE.
8611 if (!noteUsedName(storedMethodAtom)) {
8612 return errorResult();
8613 }
8614 MOZ_TRY(privateNameReference(propAtom))do { auto mozTryTempResult_ = ::mozilla::ToResult(privateNameReference
(propAtom)); if ((__builtin_expect(!!(mozTryTempResult_.isErr
()), 0))) { return mozTryTempResult_.propagateErr(); } } while
(0)
;
8615
8616 // Unlike field initializers, private method initializers are not created with
8617 // a body of synthesized AST nodes. Instead, the body is left empty and the
8618 // initializer is synthesized at the bytecode level.
8619 // See BytecodeEmitter::emitPrivateMethodInitializer.
8620 ListNodeType stmtList;
8621 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)
;
8622
8623 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8624 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8625 return errorResult();
8626 }
8627 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8628 return errorResult();
8629 }
8630
8631 LexicalScopeNodeType initializerBody;
8632 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)
8633 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)
;
8634 handler_.setBeginPosition(initializerBody, stmtList);
8635 handler_.setEndPosition(initializerBody, stmtList);
8636 handler_.setFunctionBody(funNode, initializerBody);
8637
8638 // Set field-initializer lambda boundary to start at property name and end
8639 // after method body.
8640 setFunctionStartAtPosition(funbox, propNamePos);
8641 setFunctionEndFromCurrentToken(funbox);
8642
8643 if (!finishFunction()) {
8644 return errorResult();
8645 }
8646
8647 if (!leaveInnerFunction(outerpc)) {
8648 return errorResult();
8649 }
8650
8651 return funNode;
8652}
8653
8654template <class ParseHandler, typename Unit>
8655typename ParseHandler::FunctionNodeResult
8656GeneralParser<ParseHandler, Unit>::staticClassBlock(
8657 ClassInitializedMembers& classInitializedMembers) {
8658 // Both for getting-this-done, and because this will invariably be executed,
8659 // syntax parsing should be aborted.
8660 if (!abortIfSyntaxParser()) {
8661 return errorResult();
8662 }
8663
8664 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::StaticClassBlock;
8665 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8666 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8667 bool isSelfHosting = options().selfHostingMode;
8668 FunctionFlags flags =
8669 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8670
8671 AutoAwaitIsKeyword awaitIsKeyword(this, AwaitHandling::AwaitIsDisallowed);
8672
8673 // Create the function node for the static class body.
8674 FunctionNodeType funNode;
8675 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)
;
8676
8677 // Create the FunctionBox and link it to the function object.
8678 Directives directives(true);
8679 FunctionBox* funbox =
8680 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags, pos().begin,
8681 directives, generatorKind, asyncKind);
8682 if (!funbox) {
8683 return errorResult();
8684 }
8685 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8686 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"
, 8686); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isSyntheticFunction()"
")"); do { *((volatile int*)__null) = 8686; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8687 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"
, 8687); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowSuperCall()"
")"); do { *((volatile int*)__null) = 8687; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8688 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"
, 8688); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowArguments()"
")"); do { *((volatile int*)__null) = 8688; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8689 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"
, 8689); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowReturn()"
")"); do { *((volatile int*)__null) = 8689; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8690
8691 // Set start at `static` token.
8692 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"
, 8692); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Static)"
")"); do { *((volatile int*)__null) = 8692; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8693 setFunctionStartAtCurrentToken(funbox);
8694
8695 // Push a SourceParseContext on to the stack.
8696 ParseContext* outerpc = pc_;
8697 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8698 if (!funpc.init()) {
8699 return errorResult();
8700 }
8701
8702 pc_->functionScope().useAsVarScope(pc_);
8703
8704 uint32_t start = pos().begin;
8705
8706 tokenStream.consumeKnownToken(TokenKind::LeftCurly);
8707
8708 // Static class blocks are code-generated as if they were static field
8709 // initializers, so we bump the staticFields count here, which ensures
8710 // .staticInitializers is noted as used.
8711 classInitializedMembers.staticFields++;
8712
8713 LexicalScopeNodeType body;
8714 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)
8715 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)
8716 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)
;
8717
8718 if (anyChars.isEOF()) {
8719 error(JSMSG_UNTERMINATED_STATIC_CLASS_BLOCK);
8720 return errorResult();
8721 }
8722
8723 tokenStream.consumeKnownToken(TokenKind::RightCurly,
8724 TokenStream::Modifier::SlashIsRegExp);
8725
8726 TokenPos wholeBodyPos(start, pos().end);
8727
8728 handler_.setEndPosition(funNode, wholeBodyPos.end);
8729 setFunctionEndFromCurrentToken(funbox);
8730
8731 // Create a ParamsBodyNode for the parameters + body (there are no
8732 // parameters).
8733 ParamsBodyNodeType argsbody;
8734 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)
;
8735
8736 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8737 funbox->setArgCount(0);
8738
8739 if (pc_->superScopeNeedsHomeObject()) {
8740 funbox->setNeedsHomeObject();
8741 }
8742
8743 handler_.setEndPosition(body, pos().begin);
8744 handler_.setEndPosition(funNode, pos().end);
8745 handler_.setFunctionBody(funNode, body);
8746
8747 if (!finishFunction()) {
8748 return errorResult();
8749 }
8750
8751 if (!leaveInnerFunction(outerpc)) {
8752 return errorResult();
8753 }
8754
8755 return funNode;
8756}
8757
8758template <class ParseHandler, typename Unit>
8759typename ParseHandler::FunctionNodeResult
8760GeneralParser<ParseHandler, Unit>::fieldInitializerOpt(
8761 TokenPos propNamePos, Node propName, TaggedParserAtomIndex propAtom,
8762 ClassInitializedMembers& classInitializedMembers, bool isStatic,
8763 HasHeritage hasHeritage) {
8764 if (!abortIfSyntaxParser()) {
8765 return errorResult();
8766 }
8767
8768 bool hasInitializer = false;
8769 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
8770 TokenStream::SlashIsDiv)) {
8771 return errorResult();
8772 }
8773
8774 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer;
8775 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8776 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8777 bool isSelfHosting = options().selfHostingMode;
8778 FunctionFlags flags =
8779 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8780
8781 // Create the top-level field initializer node.
8782 FunctionNodeType funNode;
8783 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)
;
8784
8785 // Create the FunctionBox and link it to the function object.
8786 Directives directives(true);
8787 FunctionBox* funbox =
8788 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
8789 propNamePos.begin, directives, generatorKind, asyncKind);
8790 if (!funbox) {
8791 return errorResult();
8792 }
8793 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8794 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"
, 8794); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isSyntheticFunction()"
")"); do { *((volatile int*)__null) = 8794; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8795
8796 // We can't use setFunctionStartAtCurrentToken because that uses pos().begin,
8797 // which is incorrect for fields without initializers (pos() points to the
8798 // field identifier)
8799 setFunctionStartAtPosition(funbox, propNamePos);
8800
8801 // Push a SourceParseContext on to the stack.
8802 ParseContext* outerpc = pc_;
8803 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8804 if (!funpc.init()) {
8805 return errorResult();
8806 }
8807
8808 pc_->functionScope().useAsVarScope(pc_);
8809
8810 Node initializerExpr;
8811 if (hasInitializer) {
8812 // Parse the expression for the field initializer.
8813 {
8814 AutoAwaitIsKeyword awaitHandling(this, AwaitIsName);
8815 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)
8816 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)
;
8817 }
8818
8819 handler_.checkAndSetIsDirectRHSAnonFunction(initializerExpr);
8820 } else {
8821 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)
;
8822 }
8823
8824 TokenPos wholeInitializerPos(propNamePos.begin, pos().end);
8825
8826 // Update the end position of the parse node.
8827 handler_.setEndPosition(funNode, wholeInitializerPos.end);
8828 setFunctionEndFromCurrentToken(funbox);
8829
8830 // Create a ParamsBodyNode for the parameters + body (there are no
8831 // parameters).
8832 ParamsBodyNodeType argsbody;
8833 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)
;
8834 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8835 funbox->setArgCount(0);
8836
8837 NameNodeType thisName;
8838 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
8839
8840 // Build `this.field` expression.
8841 ThisLiteralType propAssignThis;
8842 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)
8843 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)
;
8844
8845 Node propAssignFieldAccess;
8846 uint32_t indexValue;
8847 if (!propAtom) {
8848 // See BytecodeEmitter::emitCreateFieldKeys for an explanation of what
8849 // .fieldKeys means and its purpose.
8850 NameNodeType fieldKeysName;
8851 if (isStatic) {
8852 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)
8853 fieldKeysName,do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8854 newInternalDotName(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8855 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)
;
8856 } else {
8857 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)
8858 newInternalDotName(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_fieldKeys_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fieldKeysName) = mozTryVarTempResult_.unwrap(); } while (
0)
8859 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)
;
8860 }
8861 if (!fieldKeysName) {
8862 return errorResult();
8863 }
8864
8865 double fieldKeyIndex;
8866 if (isStatic) {
8867 fieldKeyIndex = classInitializedMembers.staticFieldKeys++;
8868 } else {
8869 fieldKeyIndex = classInitializedMembers.instanceFieldKeys++;
8870 }
8871 Node fieldKeyIndexNode;
8872 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)
8873 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)
8874 wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newNumber(fieldKeyIndex
, DecimalPoint::NoDecimal, wholeInitializerPos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeyIndexNode) = mozTryVarTempResult_
.unwrap(); } while (0)
;
8875
8876 Node fieldKeyValue;
8877 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)
8878 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)
8879 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)
;
8880
8881 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)
8882 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)
8883 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)
;
8884 } else if (handler_.isPrivateName(propName)) {
8885 // It would be nice if we could tweak this here such that only if
8886 // HasHeritage::Yes we end up emitting CheckPrivateField, but otherwise we
8887 // emit InitElem -- this is an optimization to minimize HasOwn checks
8888 // in InitElem for classes without heritage.
8889 //
8890 // Further tweaking would be to ultimately only do CheckPrivateField for the
8891 // -first- field in a derived class, which would suffice to match the
8892 // semantic check.
8893
8894 NameNodeType privateNameNode;
8895 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)
;
8896
8897 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)
8898 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)
8899 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)
;
8900 } else if (this->parserAtoms().isIndex(propAtom, &indexValue)) {
8901 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)
8902 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)
8903 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)
;
8904 } else {
8905 NameNodeType propAssignName;
8906 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)
8907 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)
;
8908
8909 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)
8910 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)
;
8911 }
8912
8913 // Synthesize an property init.
8914 BinaryNodeType initializerPropInit;
8915 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)
8916 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)
;
8917
8918 UnaryNodeType exprStatement;
8919 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)
8920 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)
;
8921
8922 ListNodeType statementList;
8923 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)
;
8924 handler_.addStatementToList(statementList, exprStatement);
8925
8926 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8927 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8928 return errorResult();
8929 }
8930 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8931 return errorResult();
8932 }
8933
8934 // Set the function's body to the field assignment.
8935 LexicalScopeNodeType initializerBody;
8936 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)
8937 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)
8938 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)
;
8939
8940 handler_.setFunctionBody(funNode, initializerBody);
8941
8942 if (pc_->superScopeNeedsHomeObject()) {
8943 funbox->setNeedsHomeObject();
8944 }
8945
8946 if (!finishFunction()) {
8947 return errorResult();
8948 }
8949
8950 if (!leaveInnerFunction(outerpc)) {
8951 return errorResult();
8952 }
8953
8954 return funNode;
8955}
8956
8957template <class ParseHandler, typename Unit>
8958typename ParseHandler::FunctionNodeResult
8959GeneralParser<ParseHandler, Unit>::synthesizePrivateMethodInitializer(
8960 TaggedParserAtomIndex propAtom, AccessorType accessorType,
8961 TokenPos propNamePos) {
8962 if (!abortIfSyntaxParser()) {
8963 return errorResult();
8964 }
8965
8966 // Synthesize a name for the lexical variable that will store the
8967 // accessor body.
8968 StringBuilder storedMethodName(fc_);
8969 if (!storedMethodName.append(this->parserAtoms(), propAtom)) {
8970 return errorResult();
8971 }
8972 if (!storedMethodName.append(
8973 accessorType == AccessorType::Getter ? ".getter" : ".setter")) {
8974 return errorResult();
8975 }
8976 auto storedMethodProp =
8977 storedMethodName.finishParserAtom(this->parserAtoms(), fc_);
8978 if (!storedMethodProp) {
8979 return errorResult();
8980 }
8981 if (!noteDeclaredName(storedMethodProp, DeclarationKind::Synthetic, pos())) {
8982 return errorResult();
8983 }
8984
8985 return privateMethodInitializer(propNamePos, propAtom, storedMethodProp);
8986}
8987
8988#ifdef ENABLE_DECORATORS
8989template <class ParseHandler, typename Unit>
8990typename ParseHandler::FunctionNodeResult
8991GeneralParser<ParseHandler, Unit>::synthesizeAddInitializerFunction(
8992 TaggedParserAtomIndex initializers, YieldHandling yieldHandling) {
8993 if (!abortIfSyntaxParser()) {
8994 return errorResult();
8995 }
8996
8997 // TODO: Add support for static and class extra initializers, see bug 1868220
8998 // and bug 1868221.
8999 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"
, 9001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9001; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9000 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"
, 9001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9001; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9001 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"
, 9001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9001; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9002
9003 TokenPos propNamePos = pos();
9004
9005 // Synthesize an addInitializer function that can be used to append to
9006 // .initializers
9007 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
9008 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
9009 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
9010 bool isSelfHosting = options().selfHostingMode;
9011 FunctionFlags flags =
9012 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
9013
9014 FunctionNodeType funNode;
9015 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)
;
9016
9017 Directives directives(true);
9018 FunctionBox* funbox =
9019 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
9020 propNamePos.begin, directives, generatorKind, asyncKind);
9021 if (!funbox) {
9022 return errorResult();
9023 }
9024 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
9025
9026 ParseContext* outerpc = pc_;
9027 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
9028 if (!funpc.init()) {
9029 return errorResult();
9030 }
9031 pc_->functionScope().useAsVarScope(pc_);
9032
9033 // Takes a single parameter, `initializer`.
9034 ParamsBodyNodeType params;
9035 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)
;
9036
9037 handler_.setFunctionFormalParametersAndBody(funNode, params);
9038
9039 constexpr bool disallowDuplicateParams = true;
9040 bool duplicatedParam = false;
9041 if (!notePositionalFormalParameter(
9042 funNode, TaggedParserAtomIndex::WellKnown::initializer(), pos().begin,
9043 disallowDuplicateParams, &duplicatedParam)) {
9044 return null();
9045 }
9046 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"
, 9046); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!duplicatedParam"
")"); do { *((volatile int*)__null) = 9046; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9047 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"
, 9047); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->positionalFormalParameterNames().length() == 1"
")"); do { *((volatile int*)__null) = 9047; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9048
9049 funbox->setLength(1);
9050 funbox->setArgCount(1);
9051 setFunctionStartAtCurrentToken(funbox);
9052
9053 // Like private method initializers, the addInitializer method is not created
9054 // with a body of synthesized AST nodes. Instead, the body is left empty and
9055 // the initializer is synthesized at the bytecode level. See
9056 // DecoratorEmitter::emitCreateAddInitializerFunction.
9057 ListNodeType stmtList;
9058 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)
;
9059
9060 if (!noteUsedName(initializers)) {
9061 return null();
9062 }
9063
9064 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
9065 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
9066 return null();
9067 }
9068 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
9069 return null();
9070 }
9071
9072 LexicalScopeNodeType addInitializerBody;
9073 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)
9074 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)
9075 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)
;
9076 handler_.setBeginPosition(addInitializerBody, stmtList);
9077 handler_.setEndPosition(addInitializerBody, stmtList);
9078 handler_.setFunctionBody(funNode, addInitializerBody);
9079
9080 // Set field-initializer lambda boundary to start at property name and end
9081 // after method body.
9082 setFunctionStartAtPosition(funbox, propNamePos);
9083 setFunctionEndFromCurrentToken(funbox);
9084
9085 if (!finishFunction()) {
9086 return errorResult();
9087 }
9088
9089 if (!leaveInnerFunction(outerpc)) {
9090 return errorResult();
9091 }
9092
9093 return funNode;
9094}
9095
9096template <class ParseHandler, typename Unit>
9097typename ParseHandler::ClassMethodResult
9098GeneralParser<ParseHandler, Unit>::synthesizeAccessor(
9099 Node propName, TokenPos propNamePos, TaggedParserAtomIndex propAtom,
9100 TaggedParserAtomIndex privateStateNameAtom, bool isStatic,
9101 FunctionSyntaxKind syntaxKind,
9102 ClassInitializedMembers& classInitializedMembers) {
9103 // Decorators Proposal
9104 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9105 // The abstract operation MakeAutoAccessorGetter takes arguments homeObject
9106 // (an Object), name (a property key or Private Name), and privateStateName (a
9107 // Private Name) and returns a function object.
9108 //
9109 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9110 // The abstract operation MakeAutoAccessorSetter takes arguments homeObject
9111 // (an Object), name (a property key or Private Name), and privateStateName (a
9112 // Private Name) and returns a function object.
9113 if (!abortIfSyntaxParser()) {
9114 return errorResult();
9115 }
9116
9117 AccessorType accessorType = syntaxKind == FunctionSyntaxKind::Getter
9118 ? AccessorType::Getter
9119 : AccessorType::Setter;
9120
9121 mozilla::Maybe<FunctionNodeType> initializerIfPrivate = Nothing();
9122 if (!isStatic && handler_.isPrivateName(propName)) {
9123 classInitializedMembers.privateAccessors++;
9124 FunctionNodeType initializerNode;
9125 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)
9126 propAtom, accessorType, propNamePos))do { auto mozTryVarTempResult_ = (synthesizePrivateMethodInitializer
( propAtom, accessorType, propNamePos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerNode) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9127 initializerIfPrivate = Some(initializerNode);
9128 handler_.setPrivateNameKind(propName, PrivateNameKind::GetterSetter);
9129 }
9130
9131 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9132 // 2. Let getter be CreateBuiltinFunction(getterClosure, 0, "get", « »).
9133 //
9134 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9135 // 2. Let setter be CreateBuiltinFunction(setterClosure, 1, "set", « »).
9136 StringBuilder storedMethodName(fc_);
9137 if (!storedMethodName.append(accessorType == AccessorType::Getter ? "get"
9138 : "set")) {
9139 return errorResult();
9140 }
9141 TaggedParserAtomIndex funNameAtom =
9142 storedMethodName.finishParserAtom(this->parserAtoms(), fc_);
9143
9144 FunctionNodeType funNode;
9145 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)
9146 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)
9147 privateStateNameAtom, syntaxKind))do { auto mozTryVarTempResult_ = (synthesizeAccessorBody(funNameAtom
, propNamePos, privateStateNameAtom, syntaxKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (funNode) = mozTryVarTempResult_.unwrap();
} while (0)
;
9148
9149 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9150 // 3. Perform MakeMethod(getter, homeObject).
9151 // 4. Return getter.
9152 //
9153 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9154 // 3. Perform MakeMethod(setter, homeObject).
9155 // 4. Return setter.
9156 return handler_.newClassMethodDefinition(
9157 propName, funNode, accessorType, isStatic, initializerIfPrivate, null());
9158}
9159
9160template <class ParseHandler, typename Unit>
9161typename ParseHandler::FunctionNodeResult
9162GeneralParser<ParseHandler, Unit>::synthesizeAccessorBody(
9163 TaggedParserAtomIndex funNameAtom, TokenPos propNamePos,
9164 TaggedParserAtomIndex propNameAtom, FunctionSyntaxKind syntaxKind) {
9165 if (!abortIfSyntaxParser()) {
9166 return errorResult();
9167 }
9168
9169 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
9170 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
9171 bool isSelfHosting = options().selfHostingMode;
9172 FunctionFlags flags =
9173 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
9174
9175 // Create the top-level function node.
9176 FunctionNodeType funNode;
9177 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)
;
9178
9179 // Create the FunctionBox and link it to the function object.
9180 Directives directives(true);
9181 FunctionBox* funbox =
9182 newFunctionBox(funNode, funNameAtom, flags, propNamePos.begin, directives,
9183 generatorKind, asyncKind);
9184 if (!funbox) {
9185 return errorResult();
9186 }
9187 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
9188 funbox->setSyntheticFunction();
9189
9190 // Push a SourceParseContext on to the stack.
9191 ParseContext* outerpc = pc_;
9192 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
9193 if (!funpc.init()) {
9194 return errorResult();
9195 }
9196
9197 pc_->functionScope().useAsVarScope(pc_);
9198
9199 // The function we synthesize is located at the field with the
9200 // accessor.
9201 setFunctionStartAtCurrentToken(funbox);
9202 setFunctionEndFromCurrentToken(funbox);
9203
9204 // Create a ListNode for the parameters + body
9205 ParamsBodyNodeType paramsbody;
9206 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)
;
9207 handler_.setFunctionFormalParametersAndBody(funNode, paramsbody);
9208
9209 if (syntaxKind == FunctionSyntaxKind::Getter) {
9210 funbox->setArgCount(0);
9211 } else {
9212 funbox->setArgCount(1);
9213 }
9214
9215 // Build `this` expression to access the privateStateName for use in the
9216 // operations to create the getter and setter below.
9217 NameNodeType thisName;
9218 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
9219
9220 ThisLiteralType propThis;
9221 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)
;
9222
9223 NameNodeType privateNameNode;
9224 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)
;
9225
9226 Node propFieldAccess;
9227 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)
9228 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)
;
9229
9230 Node accessorBody;
9231 if (syntaxKind == FunctionSyntaxKind::Getter) {
9232 // Decorators Proposal
9233 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9234 // 1. Let getterClosure be a new Abstract Closure with no parameters that
9235 // captures privateStateName and performs the following steps when called:
9236 // 1.a. Let o be the this value.
9237 // 1.b. Return ? PrivateGet(privateStateName, o).
9238 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
)
9239 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
)
;
9240 } else {
9241 // Decorators Proposal
9242 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9243 // The abstract operation MakeAutoAccessorSetter takes arguments homeObject
9244 // (an Object), name (a property key or Private Name), and privateStateName
9245 // (a Private Name) and returns a function object.
9246 // 1. Let setterClosure be a new Abstract Closure with parameters (value)
9247 // that captures privateStateName and performs the following steps when
9248 // called:
9249 // 1.a. Let o be the this value.
9250 notePositionalFormalParameter(funNode,
9251 TaggedParserAtomIndex::WellKnown::value(),
9252 /* pos = */ 0, false,
9253 /* duplicatedParam = */ nullptr);
9254
9255 Node initializerExpr;
9256 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)
9257 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)
9258 propNamePos))do { auto mozTryVarTempResult_ = (handler_.newName(TaggedParserAtomIndex
::WellKnown::value(), propNamePos)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerExpr) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9259
9260 // 1.b. Perform ? PrivateSet(privateStateName, o, value).
9261 Node assignment;
9262 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)
9263 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)
9264 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)
;
9265
9266 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
)
9267 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
)
;
9268
9269 // 1.c. Return undefined.
9270 }
9271
9272 ListNodeType statementList;
9273 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)
;
9274 handler_.addStatementToList(statementList, accessorBody);
9275
9276 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
9277 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
9278 return errorResult();
9279 }
9280 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
9281 return errorResult();
9282 }
9283
9284 LexicalScopeNodeType initializerBody;
9285 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)
9286 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)
9287 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)
;
9288
9289 handler_.setFunctionBody(funNode, initializerBody);
9290
9291 if (pc_->superScopeNeedsHomeObject()) {
9292 funbox->setNeedsHomeObject();
9293 }
9294
9295 if (!finishFunction()) {
9296 return errorResult();
9297 }
9298
9299 if (!leaveInnerFunction(outerpc)) {
9300 return errorResult();
9301 }
9302
9303 return funNode;
9304}
9305
9306#endif
9307
9308bool ParserBase::nextTokenContinuesLetDeclaration(TokenKind next) {
9309 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"
, 9309); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 9309; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9310 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"
, 9310); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.nextToken().type == next"
")"); do { *((volatile int*)__null) = 9310; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9311
9312 TokenStreamShared::verifyConsistentModifier(TokenStreamShared::SlashIsDiv,
9313 anyChars.nextToken());
9314
9315 // Destructuring continues a let declaration.
9316 if (next == TokenKind::LeftBracket || next == TokenKind::LeftCurly) {
9317 return true;
9318 }
9319
9320 // A "let" edge case deserves special comment. Consider this:
9321 //
9322 // let // not an ASI opportunity
9323 // let;
9324 //
9325 // Static semantics in §13.3.1.1 turn a LexicalDeclaration that binds
9326 // "let" into an early error. Does this retroactively permit ASI so
9327 // that we should parse this as two ExpressionStatements? No. ASI
9328 // resolves during parsing. Static semantics only apply to the full
9329 // parse tree with ASI applied. No backsies!
9330
9331 // Otherwise a let declaration must have a name.
9332 return TokenKindIsPossibleIdentifier(next);
9333}
9334
9335template <class ParseHandler, typename Unit>
9336typename ParseHandler::DeclarationListNodeResult
9337GeneralParser<ParseHandler, Unit>::variableStatement(
9338 YieldHandling yieldHandling) {
9339 DeclarationListNodeType vars;
9340 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)
;
9341 if (!matchOrInsertSemicolon()) {
9342 return errorResult();
9343 }
9344 return vars;
9345}
9346
9347template <class ParseHandler, typename Unit>
9348typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::statement(
9349 YieldHandling yieldHandling) {
9350 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"
, 9350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 9350; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9351
9352 AutoCheckRecursionLimit recursion(this->fc_);
9353 if (!recursion.check(this->fc_)) {
9354 return errorResult();
9355 }
9356
9357 TokenKind tt;
9358 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
9359 return errorResult();
9360 }
9361
9362 switch (tt) {
9363 // BlockStatement[?Yield, ?Return]
9364 case TokenKind::LeftCurly:
9365 return blockStatement(yieldHandling);
9366
9367 // VariableStatement[?Yield]
9368 case TokenKind::Var:
9369 return variableStatement(yieldHandling);
9370
9371 // EmptyStatement
9372 case TokenKind::Semi:
9373 return handler_.newEmptyStatement(pos());
9374
9375 // ExpressionStatement[?Yield].
9376
9377 case TokenKind::Yield: {
9378 // Don't use a ternary operator here due to obscure linker issues
9379 // around using static consts in the arms of a ternary.
9380 Modifier modifier;
9381 if (yieldExpressionsSupported()) {
9382 modifier = TokenStream::SlashIsRegExp;
9383 } else {
9384 modifier = TokenStream::SlashIsDiv;
9385 }
9386
9387 TokenKind next;
9388 if (!tokenStream.peekToken(&next, modifier)) {
9389 return errorResult();
9390 }
9391
9392 if (next == TokenKind::Colon) {
9393 return labeledStatement(yieldHandling);
9394 }
9395
9396 return expressionStatement(yieldHandling);
9397 }
9398
9399 default: {
9400 // If we encounter an await in a module, and the module is not marked
9401 // as async, mark the module as async.
9402 if (tt == TokenKind::Await && !pc_->isAsync()) {
9403 if (pc_->atModuleTopLevel()) {
9404 if (!options().topLevelAwait) {
9405 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
9406 return errorResult();
9407 }
9408 pc_->sc()->asModuleContext()->setIsAsync();
9409 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"
, 9409); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 9409; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9410 }
9411 }
9412
9413 // Avoid getting next token with SlashIsDiv.
9414 if (tt == TokenKind::Await && pc_->isAsync()) {
9415 return expressionStatement(yieldHandling);
9416 }
9417
9418 if (!TokenKindIsPossibleIdentifier(tt)) {
9419 return expressionStatement(yieldHandling);
9420 }
9421
9422 TokenKind next;
9423 if (!tokenStream.peekToken(&next)) {
9424 return errorResult();
9425 }
9426
9427 // |let| here can only be an Identifier, not a declaration. Give nicer
9428 // errors for declaration-looking typos.
9429 if (tt == TokenKind::Let) {
9430 bool forbiddenLetDeclaration = false;
9431
9432 if (next == TokenKind::LeftBracket) {
9433 // Enforce ExpressionStatement's 'let [' lookahead restriction.
9434 forbiddenLetDeclaration = true;
9435 } else if (next == TokenKind::LeftCurly ||
9436 TokenKindIsPossibleIdentifier(next)) {
9437 // 'let {' and 'let foo' aren't completely forbidden, if ASI
9438 // causes 'let' to be the entire Statement. But if they're
9439 // same-line, we can aggressively give a better error message.
9440 //
9441 // Note that this ignores 'yield' as TokenKind::Yield: we'll handle it
9442 // correctly but with a worse error message.
9443 TokenKind nextSameLine;
9444 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
9445 return errorResult();
9446 }
9447
9448 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"
, 9450); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9450; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9449 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"
, 9450); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9450; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9450 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"
, 9450); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9450; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9451
9452 forbiddenLetDeclaration = nextSameLine != TokenKind::Eol;
9453 }
9454
9455 if (forbiddenLetDeclaration) {
9456 error(JSMSG_FORBIDDEN_AS_STATEMENT, "lexical declarations");
9457 return errorResult();
9458 }
9459 } else if (tt == TokenKind::Async) {
9460 // Peek only on the same line: ExpressionStatement's lookahead
9461 // restriction is phrased as
9462 //
9463 // [lookahead ∉ { '{',
9464 // function,
9465 // async [no LineTerminator here] function,
9466 // class,
9467 // let '[' }]
9468 //
9469 // meaning that code like this is valid:
9470 //
9471 // if (true)
9472 // async // ASI opportunity
9473 // function clownshoes() {}
9474 TokenKind maybeFunction;
9475 if (!tokenStream.peekTokenSameLine(&maybeFunction)) {
9476 return errorResult();
9477 }
9478
9479 if (maybeFunction == TokenKind::Function) {
9480 error(JSMSG_FORBIDDEN_AS_STATEMENT, "async function declarations");
9481 return errorResult();
9482 }
9483
9484 // Otherwise this |async| begins an ExpressionStatement or is a
9485 // label name.
9486 }
9487
9488 // NOTE: It's unfortunately allowed to have a label named 'let' in
9489 // non-strict code. 💯
9490 if (next == TokenKind::Colon) {
9491 return labeledStatement(yieldHandling);
9492 }
9493
9494 return expressionStatement(yieldHandling);
9495 }
9496
9497 case TokenKind::New:
9498 return expressionStatement(yieldHandling, PredictInvoked);
9499
9500 // IfStatement[?Yield, ?Return]
9501 case TokenKind::If:
9502 return ifStatement(yieldHandling);
9503
9504 // BreakableStatement[?Yield, ?Return]
9505 //
9506 // BreakableStatement[Yield, Return]:
9507 // IterationStatement[?Yield, ?Return]
9508 // SwitchStatement[?Yield, ?Return]
9509 case TokenKind::Do:
9510 return doWhileStatement(yieldHandling);
9511
9512 case TokenKind::While:
9513 return whileStatement(yieldHandling);
9514
9515 case TokenKind::For:
9516 return forStatement(yieldHandling);
9517
9518 case TokenKind::Switch:
9519 return switchStatement(yieldHandling);
9520
9521 // ContinueStatement[?Yield]
9522 case TokenKind::Continue:
9523 return continueStatement(yieldHandling);
9524
9525 // BreakStatement[?Yield]
9526 case TokenKind::Break:
9527 return breakStatement(yieldHandling);
9528
9529 // [+Return] ReturnStatement[?Yield]
9530 case TokenKind::Return:
9531 // The Return parameter is only used here, and the effect is easily
9532 // detected this way, so don't bother passing around an extra parameter
9533 // everywhere.
9534 if (!pc_->allowReturn()) {
9535 error(JSMSG_BAD_RETURN_OR_YIELD, "return");
9536 return errorResult();
9537 }
9538 return returnStatement(yieldHandling);
9539
9540 // WithStatement[?Yield, ?Return]
9541 case TokenKind::With:
9542 return withStatement(yieldHandling);
9543
9544 // LabelledStatement[?Yield, ?Return]
9545 // This is really handled by default and TokenKind::Yield cases above.
9546
9547 // ThrowStatement[?Yield]
9548 case TokenKind::Throw:
9549 return throwStatement(yieldHandling);
9550
9551 // TryStatement[?Yield, ?Return]
9552 case TokenKind::Try:
9553 return tryStatement(yieldHandling);
9554
9555 // DebuggerStatement
9556 case TokenKind::Debugger:
9557 return debuggerStatement();
9558
9559 // |function| is forbidden by lookahead restriction (unless as child
9560 // statement of |if| or |else|, but Parser::consequentOrAlternative
9561 // handles that).
9562 case TokenKind::Function:
9563 error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
9564 return errorResult();
9565
9566 // |class| is also forbidden by lookahead restriction.
9567 case TokenKind::Class:
9568 error(JSMSG_FORBIDDEN_AS_STATEMENT, "classes");
9569 return errorResult();
9570
9571 // ImportDeclaration (only inside modules)
9572 case TokenKind::Import:
9573 return importDeclarationOrImportExpr(yieldHandling);
9574
9575 // ExportDeclaration (only inside modules)
9576 case TokenKind::Export:
9577 return exportDeclaration();
9578
9579 // Miscellaneous error cases arguably better caught here than elsewhere.
9580
9581 case TokenKind::Catch:
9582 error(JSMSG_CATCH_WITHOUT_TRY);
9583 return errorResult();
9584
9585 case TokenKind::Finally:
9586 error(JSMSG_FINALLY_WITHOUT_TRY);
9587 return errorResult();
9588
9589 // NOTE: default case handled in the ExpressionStatement section.
9590 }
9591}
9592
9593template <class ParseHandler, typename Unit>
9594typename ParseHandler::NodeResult
9595GeneralParser<ParseHandler, Unit>::statementListItem(
9596 YieldHandling yieldHandling, bool canHaveDirectives /* = false */) {
9597 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"
, 9597); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 9597; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9598
9599 AutoCheckRecursionLimit recursion(this->fc_);
9600 if (!recursion.check(this->fc_)) {
9601 return errorResult();
9602 }
9603
9604 TokenKind tt;
9605 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
9606 return errorResult();
9607 }
9608
9609 switch (tt) {
9610 // BlockStatement[?Yield, ?Return]
9611 case TokenKind::LeftCurly:
9612 return blockStatement(yieldHandling);
9613
9614 // VariableStatement[?Yield]
9615 case TokenKind::Var:
9616 return variableStatement(yieldHandling);
9617
9618 // EmptyStatement
9619 case TokenKind::Semi:
9620 return handler_.newEmptyStatement(pos());
9621
9622 // ExpressionStatement[?Yield].
9623 //
9624 // These should probably be handled by a single ExpressionStatement
9625 // function in a default, not split up this way.
9626 case TokenKind::String:
9627 if (!canHaveDirectives &&
9628 anyChars.currentToken().atom() ==
9629 TaggedParserAtomIndex::WellKnown::use_asm_()) {
9630 if (!warning(JSMSG_USE_ASM_DIRECTIVE_FAIL)) {
9631 return errorResult();
9632 }
9633 }
9634 return expressionStatement(yieldHandling);
9635
9636 case TokenKind::Yield: {
9637 // Don't use a ternary operator here due to obscure linker issues
9638 // around using static consts in the arms of a ternary.
9639 Modifier modifier;
9640 if (yieldExpressionsSupported()) {
9641 modifier = TokenStream::SlashIsRegExp;
9642 } else {
9643 modifier = TokenStream::SlashIsDiv;
9644 }
9645
9646 TokenKind next;
9647 if (!tokenStream.peekToken(&next, modifier)) {
9648 return errorResult();
9649 }
9650
9651 if (next == TokenKind::Colon) {
9652 return labeledStatement(yieldHandling);
9653 }
9654
9655 return expressionStatement(yieldHandling);
9656 }
9657
9658 default: {
9659 // If we encounter an await in a module, and the module is not marked
9660 // as async, mark the module as async.
9661 if (tt == TokenKind::Await && !pc_->isAsync()) {
9662 if (pc_->atModuleTopLevel()) {
9663 if (!options().topLevelAwait) {
9664 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
9665 return errorResult();
9666 }
9667 pc_->sc()->asModuleContext()->setIsAsync();
9668 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"
, 9668); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 9668; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9669 }
9670 }
9671
9672 if (tt == TokenKind::Await && pc_->isAsync()) {
9673#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
9674 if (options().explicitResourceManagement()) {
9675 // Try finding evidence of a AwaitUsingDeclaration the syntax for
9676 // which
9677 // would be:
9678 // await [no LineTerminator here] using [no LineTerminator here]
9679 // identifier
9680
9681 TokenKind nextTokUsing = TokenKind::Eof;
9682 // Scan with regex modifier because when its await expression, `/`
9683 // should be treated as a regexp.
9684 if (!tokenStream.peekTokenSameLine(&nextTokUsing,
9685 TokenStream::SlashIsRegExp)) {
9686 return errorResult();
9687 }
9688
9689 if (nextTokUsing == TokenKind::Using &&
9690 this->pc_->isUsingSyntaxAllowed()) {
9691 tokenStream.consumeKnownToken(nextTokUsing,
9692 TokenStream::SlashIsRegExp);
9693 TokenKind nextTokIdentifier = TokenKind::Eof;
9694 // Here we can use the Div modifier because if the next token is
9695 // using then a `/` as the next token can only be considered a
9696 // division.
9697 if (!tokenStream.peekTokenSameLine(&nextTokIdentifier)) {
9698 return errorResult();
9699 }
9700 if (TokenKindIsPossibleIdentifier(nextTokIdentifier)) {
9701 return lexicalDeclaration(yieldHandling,
9702 DeclarationKind::AwaitUsing);
9703 }
9704 anyChars.ungetToken(); // put back using.
9705 }
9706 }
9707#endif
9708 return expressionStatement(yieldHandling);
9709 }
9710
9711 if (!TokenKindIsPossibleIdentifier(tt)) {
9712 return expressionStatement(yieldHandling);
9713 }
9714
9715 TokenKind next;
9716 if (!tokenStream.peekToken(&next)) {
9717 return errorResult();
9718 }
9719
9720 if (tt == TokenKind::Let && nextTokenContinuesLetDeclaration(next)) {
9721 return lexicalDeclaration(yieldHandling, DeclarationKind::Let);
9722 }
9723
9724 if (tt == TokenKind::Async) {
9725 TokenKind nextSameLine = TokenKind::Eof;
9726 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
9727 return errorResult();
9728 }
9729 if (nextSameLine == TokenKind::Function) {
9730 uint32_t toStringStart = pos().begin;
9731 tokenStream.consumeKnownToken(TokenKind::Function);
9732 return functionStmt(toStringStart, yieldHandling, NameRequired,
9733 FunctionAsyncKind::AsyncFunction);
9734 }
9735 }
9736
9737 if (next == TokenKind::Colon) {
9738 return labeledStatement(yieldHandling);
9739 }
9740
9741 return expressionStatement(yieldHandling);
9742 }
9743
9744 case TokenKind::New:
9745 return expressionStatement(yieldHandling, PredictInvoked);
9746
9747 // IfStatement[?Yield, ?Return]
9748 case TokenKind::If:
9749 return ifStatement(yieldHandling);
9750
9751 // BreakableStatement[?Yield, ?Return]
9752 //
9753 // BreakableStatement[Yield, Return]:
9754 // IterationStatement[?Yield, ?Return]
9755 // SwitchStatement[?Yield, ?Return]
9756 case TokenKind::Do:
9757 return doWhileStatement(yieldHandling);
9758
9759 case TokenKind::While:
9760 return whileStatement(yieldHandling);
9761
9762 case TokenKind::For:
9763 return forStatement(yieldHandling);
9764
9765 case TokenKind::Switch:
9766 return switchStatement(yieldHandling);
9767
9768 // ContinueStatement[?Yield]
9769 case TokenKind::Continue:
9770 return continueStatement(yieldHandling);
9771
9772 // BreakStatement[?Yield]
9773 case TokenKind::Break:
9774 return breakStatement(yieldHandling);
9775
9776 // [+Return] ReturnStatement[?Yield]
9777 case TokenKind::Return:
9778 // The Return parameter is only used here, and the effect is easily
9779 // detected this way, so don't bother passing around an extra parameter
9780 // everywhere.
9781 if (!pc_->allowReturn()) {
9782 error(JSMSG_BAD_RETURN_OR_YIELD, "return");
9783 return errorResult();
9784 }
9785 return returnStatement(yieldHandling);
9786
9787 // WithStatement[?Yield, ?Return]
9788 case TokenKind::With:
9789 return withStatement(yieldHandling);
9790
9791 // LabelledStatement[?Yield, ?Return]
9792 // This is really handled by default and TokenKind::Yield cases above.
9793
9794 // ThrowStatement[?Yield]
9795 case TokenKind::Throw:
9796 return throwStatement(yieldHandling);
9797
9798 // TryStatement[?Yield, ?Return]
9799 case TokenKind::Try:
9800 return tryStatement(yieldHandling);
9801
9802 // DebuggerStatement
9803 case TokenKind::Debugger:
9804 return debuggerStatement();
9805
9806 // Declaration[Yield]:
9807
9808 // HoistableDeclaration[?Yield, ~Default]
9809 case TokenKind::Function:
9810 return functionStmt(pos().begin, yieldHandling, NameRequired);
9811
9812 // DecoratorList[?Yield, ?Await] opt ClassDeclaration[?Yield, ~Default]
9813#ifdef ENABLE_DECORATORS
9814 case TokenKind::At:
9815 return classDefinition(yieldHandling, ClassStatement, NameRequired);
9816#endif
9817
9818 case TokenKind::Class:
9819 return classDefinition(yieldHandling, ClassStatement, NameRequired);
9820
9821 // LexicalDeclaration[In, ?Yield]
9822 // LetOrConst BindingList[?In, ?Yield]
9823 case TokenKind::Const:
9824 // [In] is the default behavior, because for-loops specially parse
9825 // their heads to handle |in| in this situation.
9826 return lexicalDeclaration(yieldHandling, DeclarationKind::Const);
9827
9828#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
9829 case TokenKind::Using: {
9830 TokenKind nextTok = TokenKind::Eol;
9831 if (!tokenStream.peekTokenSameLine(&nextTok)) {
9832 return errorResult();
9833 }
9834 if (!options().explicitResourceManagement() ||
9835 !TokenKindIsPossibleIdentifier(nextTok) ||
9836 !this->pc_->isUsingSyntaxAllowed()) {
9837 if (!tokenStream.peekToken(&nextTok)) {
9838 return errorResult();
9839 }
9840 // labelled statement could be like using\n:\nexpr
9841 if (nextTok == TokenKind::Colon) {
9842 return labeledStatement(yieldHandling);
9843 }
9844 return expressionStatement(yieldHandling);
9845 }
9846 return lexicalDeclaration(yieldHandling, DeclarationKind::Using);
9847 }
9848#endif
9849
9850 // ImportDeclaration (only inside modules)
9851 case TokenKind::Import:
9852 return importDeclarationOrImportExpr(yieldHandling);
9853
9854 // ExportDeclaration (only inside modules)
9855 case TokenKind::Export:
9856 return exportDeclaration();
9857
9858 // Miscellaneous error cases arguably better caught here than elsewhere.
9859
9860 case TokenKind::Catch:
9861 error(JSMSG_CATCH_WITHOUT_TRY);
9862 return errorResult();
9863
9864 case TokenKind::Finally:
9865 error(JSMSG_FINALLY_WITHOUT_TRY);
9866 return errorResult();
9867
9868 // NOTE: default case handled in the ExpressionStatement section.
9869 }
9870}
9871
9872template <class ParseHandler, typename Unit>
9873typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::expr(
9874 InHandling inHandling, YieldHandling yieldHandling,
9875 TripledotHandling tripledotHandling,
9876 PossibleError* possibleError /* = nullptr */,
9877 InvokedPrediction invoked /* = PredictUninvoked */) {
9878 Node pn;
9879 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)
9880 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)
;
9881
9882 bool matched;
9883 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
9884 TokenStream::SlashIsRegExp)) {
9885 return errorResult();
9886 }
9887 if (!matched) {
9888 return pn;
9889 }
9890
9891 ListNodeType seq;
9892 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)
;
9893 while (true) {
9894 // Trailing comma before the closing parenthesis is valid in an arrow
9895 // function parameters list: `(a, b, ) => body`. Check if we are
9896 // directly under CoverParenthesizedExpressionAndArrowParameterList,
9897 // and the next two tokens are closing parenthesis and arrow. If all
9898 // are present allow the trailing comma.
9899 if (tripledotHandling == TripledotAllowed) {
9900 TokenKind tt;
9901 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
9902 return errorResult();
9903 }
9904
9905 if (tt == TokenKind::RightParen) {
9906 tokenStream.consumeKnownToken(TokenKind::RightParen,
9907 TokenStream::SlashIsRegExp);
9908
9909 if (!tokenStream.peekToken(&tt)) {
9910 return errorResult();
9911 }
9912 if (tt != TokenKind::Arrow) {
9913 error(JSMSG_UNEXPECTED_TOKEN, "expression",
9914 TokenKindToDesc(TokenKind::RightParen));
9915 return errorResult();
9916 }
9917
9918 anyChars.ungetToken(); // put back right paren
9919 break;
9920 }
9921 }
9922
9923 // Additional calls to assignExpr should not reuse the possibleError
9924 // which had been passed into the function. Otherwise we would lose
9925 // information needed to determine whether or not we're dealing with
9926 // a non-recoverable situation.
9927 PossibleError possibleErrorInner(*this);
9928 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)
9929 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
;
9930
9931 if (!possibleError) {
9932 // Report any pending expression error.
9933 if (!possibleErrorInner.checkForExpressionError()) {
9934 return errorResult();
9935 }
9936 } else {
9937 possibleErrorInner.transferErrorsTo(possibleError);
9938 }
9939
9940 handler_.addList(seq, pn);
9941
9942 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
9943 TokenStream::SlashIsRegExp)) {
9944 return errorResult();
9945 }
9946 if (!matched) {
9947 break;
9948 }
9949 }
9950 return seq;
9951}
9952
9953static ParseNodeKind BinaryOpTokenKindToParseNodeKind(TokenKind tok) {
9954 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"
, 9954); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsBinaryOp(tok)"
")"); do { *((volatile int*)__null) = 9954; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9955 return ParseNodeKind(size_t(ParseNodeKind::BinOpFirst) +
9956 (size_t(tok) - size_t(TokenKind::BinOpFirst)));
9957}
9958
9959// This list must be kept in the same order in several places:
9960// - The binary operators in ParseNode.h ,
9961// - the binary operators in TokenKind.h
9962// - the JSOp code list in BytecodeEmitter.cpp
9963static const int PrecedenceTable[] = {
9964 1, /* ParseNodeKind::Coalesce */
9965 2, /* ParseNodeKind::Or */
9966 3, /* ParseNodeKind::And */
9967 4, /* ParseNodeKind::BitOr */
9968 5, /* ParseNodeKind::BitXor */
9969 6, /* ParseNodeKind::BitAnd */
9970 7, /* ParseNodeKind::StrictEq */
9971 7, /* ParseNodeKind::Eq */
9972 7, /* ParseNodeKind::StrictNe */
9973 7, /* ParseNodeKind::Ne */
9974 8, /* ParseNodeKind::Lt */
9975 8, /* ParseNodeKind::Le */
9976 8, /* ParseNodeKind::Gt */
9977 8, /* ParseNodeKind::Ge */
9978 8, /* ParseNodeKind::InstanceOf */
9979 8, /* ParseNodeKind::In */
9980 8, /* ParseNodeKind::PrivateIn */
9981 9, /* ParseNodeKind::Lsh */
9982 9, /* ParseNodeKind::Rsh */
9983 9, /* ParseNodeKind::Ursh */
9984 10, /* ParseNodeKind::Add */
9985 10, /* ParseNodeKind::Sub */
9986 11, /* ParseNodeKind::Star */
9987 11, /* ParseNodeKind::Div */
9988 11, /* ParseNodeKind::Mod */
9989 12 /* ParseNodeKind::Pow */
9990};
9991
9992static const int PRECEDENCE_CLASSES = 12;
9993
9994static int Precedence(ParseNodeKind pnk) {
9995 // Everything binds tighter than ParseNodeKind::Limit, because we want
9996 // to reduce all nodes to a single node when we reach a token that is not
9997 // another binary operator.
9998 if (pnk == ParseNodeKind::Limit) {
9999 return 0;
10000 }
10001
10002 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"
, 10002); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pnk >= ParseNodeKind::BinOpFirst"
")"); do { *((volatile int*)__null) = 10002; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10003 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"
, 10003); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pnk <= ParseNodeKind::BinOpLast"
")"); do { *((volatile int*)__null) = 10003; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10004 return PrecedenceTable[size_t(pnk) - size_t(ParseNodeKind::BinOpFirst)];
10005}
10006
10007enum class EnforcedParentheses : uint8_t { CoalesceExpr, AndOrExpr, None };
10008
10009template <class ParseHandler, typename Unit>
10010MOZ_ALWAYS_INLINEinline typename ParseHandler::NodeResult
10011GeneralParser<ParseHandler, Unit>::orExpr(InHandling inHandling,
10012 YieldHandling yieldHandling,
10013 TripledotHandling tripledotHandling,
10014 PossibleError* possibleError,
10015 InvokedPrediction invoked) {
10016 // Shift-reduce parser for the binary operator part of the JS expression
10017 // syntax.
10018
10019 // Conceptually there's just one stack, a stack of pairs (lhs, op).
10020 // It's implemented using two separate arrays, though.
10021 Node nodeStack[PRECEDENCE_CLASSES];
10022 ParseNodeKind kindStack[PRECEDENCE_CLASSES];
10023 int depth = 0;
10024 Node pn;
10025 EnforcedParentheses unparenthesizedExpression = EnforcedParentheses::None;
10026 for (;;) {
10027 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)
10028 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)
10029 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)
;
10030
10031 // If a binary operator follows, consume it and compute the
10032 // corresponding operator.
10033 TokenKind tok;
10034 if (!tokenStream.getToken(&tok)) {
10035 return errorResult();
10036 }
10037
10038 // Ensure that if we have a private name lhs we are legally constructing a
10039 // `#x in obj` expessions:
10040 if (handler_.isPrivateName(pn)) {
10041 if (tok != TokenKind::In || inHandling != InAllowed) {
10042 error(JSMSG_ILLEGAL_PRIVATE_NAME);
10043 return errorResult();
10044 }
10045 }
10046
10047 ParseNodeKind pnk;
10048 if (tok == TokenKind::In ? inHandling == InAllowed
10049 : TokenKindIsBinaryOp(tok)) {
10050 // We're definitely not in a destructuring context, so report any
10051 // pending expression error now.
10052 if (possibleError && !possibleError->checkForExpressionError()) {
10053 return errorResult();
10054 }
10055
10056 bool isErgonomicBrandCheck = false;
10057 switch (tok) {
10058 // Report an error for unary expressions on the LHS of **.
10059 case TokenKind::Pow:
10060 if (handler_.isUnparenthesizedUnaryExpression(pn)) {
10061 error(JSMSG_BAD_POW_LEFTSIDE);
10062 return errorResult();
10063 }
10064 break;
10065
10066 case TokenKind::Or:
10067 case TokenKind::And:
10068 // In the case that the `??` is on the left hand side of the
10069 // expression: Disallow Mixing of ?? and other logical operators (||
10070 // and &&) unless one expression is parenthesized
10071 if (unparenthesizedExpression == EnforcedParentheses::CoalesceExpr) {
10072 error(JSMSG_BAD_COALESCE_MIXING);
10073 return errorResult();
10074 }
10075 // If we have not detected a mixing error at this point, record that
10076 // we have an unparenthesized expression, in case we have one later.
10077 unparenthesizedExpression = EnforcedParentheses::AndOrExpr;
10078 break;
10079
10080 case TokenKind::Coalesce:
10081 if (unparenthesizedExpression == EnforcedParentheses::AndOrExpr) {
10082 error(JSMSG_BAD_COALESCE_MIXING);
10083 return errorResult();
10084 }
10085 // If we have not detected a mixing error at this point, record that
10086 // we have an unparenthesized expression, in case we have one later.
10087 unparenthesizedExpression = EnforcedParentheses::CoalesceExpr;
10088 break;
10089
10090 case TokenKind::In:
10091 // if the LHS is a private name, and the operator is In,
10092 // ensure we're construcing an ergonomic brand check of
10093 // '#x in y', rather than having a higher precedence operator
10094 // like + cause a different reduction, such as
10095 // 1 + #x in y.
10096 if (handler_.isPrivateName(pn)) {
10097 if (depth > 0 && Precedence(kindStack[depth - 1]) >=
10098 Precedence(ParseNodeKind::InExpr)) {
10099 error(JSMSG_INVALID_PRIVATE_NAME_PRECEDENCE);
10100 return errorResult();
10101 }
10102
10103 isErgonomicBrandCheck = true;
10104 }
10105 break;
10106
10107 default:
10108 // do nothing in other cases
10109 break;
10110 }
10111
10112 if (isErgonomicBrandCheck) {
10113 pnk = ParseNodeKind::PrivateInExpr;
10114 } else {
10115 pnk = BinaryOpTokenKindToParseNodeKind(tok);
10116 }
10117
10118 } else {
10119 tok = TokenKind::Eof;
10120 pnk = ParseNodeKind::Limit;
10121 }
10122
10123 // From this point on, destructuring defaults are definitely an error.
10124 possibleError = nullptr;
10125
10126 // If pnk has precedence less than or equal to another operator on the
10127 // stack, reduce. This combines nodes on the stack until we form the
10128 // actual lhs of pnk.
10129 //
10130 // The >= in this condition works because it is appendOrCreateList's
10131 // job to decide if the operator in question is left- or
10132 // right-associative, and build the corresponding tree.
10133 while (depth > 0 && Precedence(kindStack[depth - 1]) >= Precedence(pnk)) {
10134 depth--;
10135 ParseNodeKind combiningPnk = kindStack[depth];
10136 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)
10137 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)
;
10138 }
10139
10140 if (pnk == ParseNodeKind::Limit) {
10141 break;
10142 }
10143
10144 nodeStack[depth] = pn;
10145 kindStack[depth] = pnk;
10146 depth++;
10147 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"
, 10147); AnnotateMozCrashReason("MOZ_ASSERT" "(" "depth <= PRECEDENCE_CLASSES"
")"); do { *((volatile int*)__null) = 10147; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10148 }
10149
10150 anyChars.ungetToken();
10151
10152 // Had the next token been a Div, we would have consumed it. So there's no
10153 // ambiguity if we later (after ASI) re-get this token with SlashIsRegExp.
10154 anyChars.allowGettingNextTokenWithSlashIsRegExp();
10155
10156 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"
, 10156); AnnotateMozCrashReason("MOZ_ASSERT" "(" "depth == 0"
")"); do { *((volatile int*)__null) = 10156; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10157 return pn;
10158}
10159
10160template <class ParseHandler, typename Unit>
10161MOZ_ALWAYS_INLINEinline typename ParseHandler::NodeResult
10162GeneralParser<ParseHandler, Unit>::condExpr(InHandling inHandling,
10163 YieldHandling yieldHandling,
10164 TripledotHandling tripledotHandling,
10165 PossibleError* possibleError,
10166 InvokedPrediction invoked) {
10167 Node condition;
10168 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)
10169 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)
;
10170
10171 bool matched;
10172 if (!tokenStream.matchToken(&matched, TokenKind::Hook,
10173 TokenStream::SlashIsInvalid)) {
10174 return errorResult();
10175 }
10176 if (!matched) {
10177 return condition;
10178 }
10179
10180 Node thenExpr;
10181 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)
10182 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)
;
10183
10184 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_IN_COND)) {
10185 return errorResult();
10186 }
10187
10188 Node elseExpr;
10189 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)
10190 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)
;
10191
10192 return handler_.newConditional(condition, thenExpr, elseExpr);
10193}
10194
10195template <class ParseHandler, typename Unit>
10196typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::assignExpr(
10197 InHandling inHandling, YieldHandling yieldHandling,
10198 TripledotHandling tripledotHandling,
10199 PossibleError* possibleError /* = nullptr */,
10200 InvokedPrediction invoked /* = PredictUninvoked */) {
10201 AutoCheckRecursionLimit recursion(this->fc_);
10202 if (!recursion.check(this->fc_)) {
10203 return errorResult();
10204 }
10205
10206 // It's very common at this point to have a "detectably simple" expression,
10207 // i.e. a name/number/string token followed by one of the following tokens
10208 // that obviously isn't part of an expression: , ; : ) ] }
10209 //
10210 // (In Parsemark this happens 81.4% of the time; in code with large
10211 // numeric arrays, such as some Kraken benchmarks, it happens more often.)
10212 //
10213 // In such cases, we can avoid the full expression parsing route through
10214 // assignExpr(), condExpr(), orExpr(), unaryExpr(), memberExpr(), and
10215 // primaryExpr().
10216
10217 TokenKind firstToken;
10218 if (!tokenStream.getToken(&firstToken, TokenStream::SlashIsRegExp)) {
10219 return errorResult();
10220 }
10221
10222 TokenPos exprPos = pos();
10223
10224 bool endsExpr;
10225
10226 // This only handles identifiers that *never* have special meaning anywhere
10227 // in the language. Contextual keywords, reserved words in strict mode,
10228 // and other hard cases are handled outside this fast path.
10229 if (firstToken == TokenKind::Name) {
10230 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10231 return errorResult();
10232 }
10233 if (endsExpr) {
10234 TaggedParserAtomIndex name = identifierReference(yieldHandling);
10235 if (!name) {
10236 return errorResult();
10237 }
10238
10239 return identifierReference(name);
10240 }
10241 }
10242
10243 if (firstToken == TokenKind::Number) {
10244 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10245 return errorResult();
10246 }
10247 if (endsExpr) {
10248 return newNumber(anyChars.currentToken());
10249 }
10250 }
10251
10252 if (firstToken == TokenKind::String) {
10253 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10254 return errorResult();
10255 }
10256 if (endsExpr) {
10257 return stringLiteral();
10258 }
10259 }
10260
10261 if (firstToken == TokenKind::Yield && yieldExpressionsSupported()) {
10262 return yieldExpression(inHandling);
10263 }
10264
10265 bool maybeAsyncArrow = false;
10266 if (firstToken == TokenKind::Async) {
10267 TokenKind nextSameLine = TokenKind::Eof;
10268 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
10269 return errorResult();
10270 }
10271
10272 if (TokenKindIsPossibleIdentifier(nextSameLine)) {
10273 maybeAsyncArrow = true;
10274 }
10275 }
10276
10277 anyChars.ungetToken();
10278
10279 // Save the tokenizer state in case we find an arrow function and have to
10280 // rewind.
10281 Position start(tokenStream);
10282 auto ghostToken = this->compilationState_.getPosition();
10283
10284 PossibleError possibleErrorInner(*this);
10285 Node lhs;
10286 TokenKind tokenAfterLHS;
10287 bool isArrow;
10288 if (maybeAsyncArrow) {
10289 tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::SlashIsRegExp);
10290
10291 TokenKind tokenAfterAsync;
10292 if (!tokenStream.getToken(&tokenAfterAsync)) {
10293 return errorResult();
10294 }
10295 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"
, 10295); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(tokenAfterAsync)"
")"); do { *((volatile int*)__null) = 10295; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10296
10297 // Check yield validity here.
10298 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
10299 if (!name) {
10300 return errorResult();
10301 }
10302
10303 if (!tokenStream.peekToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)) {
10304 return errorResult();
10305 }
10306
10307 isArrow = tokenAfterLHS == TokenKind::Arrow;
10308
10309 // |async [no LineTerminator] of| without being followed by => is only
10310 // possible in for-await-of loops, e.g. |for await (async of [])|. Pretend
10311 // the |async| token was parsed an identifier reference and then proceed
10312 // with the rest of this function.
10313 if (!isArrow) {
10314 anyChars.ungetToken(); // unget the binding identifier
10315
10316 // The next token is guaranteed to never be a Div (, because it's an
10317 // identifier), so it's okay to re-get the token with SlashIsRegExp.
10318 anyChars.allowGettingNextTokenWithSlashIsRegExp();
10319
10320 TaggedParserAtomIndex asyncName = identifierReference(yieldHandling);
10321 if (!asyncName) {
10322 return errorResult();
10323 }
10324
10325 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)
;
10326 }
10327 } else {
10328 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)
10329 &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)
;
10330
10331 // Use SlashIsRegExp here because the ConditionalExpression parsed above
10332 // could be the entirety of this AssignmentExpression, and then ASI
10333 // permits this token to be a regular expression.
10334 if (!tokenStream.peekToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)) {
10335 return errorResult();
10336 }
10337
10338 isArrow = tokenAfterLHS == TokenKind::Arrow;
10339 }
10340
10341 if (isArrow) {
10342 // Rewind to reparse as an arrow function.
10343 //
10344 // Note: We do not call CompilationState::rewind here because parsing
10345 // during delazification will see the same rewind and need the same sequence
10346 // of inner functions to skip over.
10347 // Instead, we mark inner functions as "ghost".
10348 //
10349 // See GHOST_FUNCTION in FunctionFlags.h for more details.
10350 tokenStream.rewind(start);
10351 this->compilationState_.markGhost(ghostToken);
10352
10353 TokenKind next;
10354 if (!tokenStream.getToken(&next, TokenStream::SlashIsRegExp)) {
10355 return errorResult();
10356 }
10357 TokenPos startPos = pos();
10358 uint32_t toStringStart = startPos.begin;
10359 anyChars.ungetToken();
10360
10361 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
10362
10363 if (next == TokenKind::Async) {
10364 tokenStream.consumeKnownToken(next, TokenStream::SlashIsRegExp);
10365
10366 TokenKind nextSameLine = TokenKind::Eof;
10367 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
10368 return errorResult();
10369 }
10370
10371 // The AsyncArrowFunction production are
10372 // async [no LineTerminator here] AsyncArrowBindingIdentifier ...
10373 // async [no LineTerminator here] ArrowFormalParameters ...
10374 if (TokenKindIsPossibleIdentifier(nextSameLine) ||
10375 nextSameLine == TokenKind::LeftParen) {
10376 asyncKind = FunctionAsyncKind::AsyncFunction;
10377 } else {
10378 anyChars.ungetToken();
10379 }
10380 }
10381
10382 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Arrow;
10383 FunctionNodeType funNode;
10384 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)
;
10385
10386 return functionDefinition(funNode, toStringStart, inHandling, yieldHandling,
10387 TaggedParserAtomIndex::null(), syntaxKind,
10388 GeneratorKind::NotGenerator, asyncKind);
10389 }
10390
10391 MOZ_ALWAYS_TRUE(do { if ((__builtin_expect(!!(tokenStream.getToken(&tokenAfterLHS
, TokenStream::SlashIsRegExp)), 1))) { } else { do { do { } while
(false); MOZ_ReportCrash("" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10392); AnnotateMozCrashReason("MOZ_CRASH(" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")"); do { *((volatile int*)__null) = 10392; __attribute__((
nomerge)) ::abort(); } while (false); } while (false); } } while
(false)
10392 tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp))do { if ((__builtin_expect(!!(tokenStream.getToken(&tokenAfterLHS
, TokenStream::SlashIsRegExp)), 1))) { } else { do { do { } while
(false); MOZ_ReportCrash("" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10392); AnnotateMozCrashReason("MOZ_CRASH(" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")"); do { *((volatile int*)__null) = 10392; __attribute__((
nomerge)) ::abort(); } while (false); } while (false); } } while
(false)
;
10393
10394 ParseNodeKind kind;
10395 switch (tokenAfterLHS) {
10396 case TokenKind::Assign:
10397 kind = ParseNodeKind::AssignExpr;
10398 break;
10399 case TokenKind::AddAssign:
10400 kind = ParseNodeKind::AddAssignExpr;
10401 break;
10402 case TokenKind::SubAssign:
10403 kind = ParseNodeKind::SubAssignExpr;
10404 break;
10405 case TokenKind::CoalesceAssign:
10406 kind = ParseNodeKind::CoalesceAssignExpr;
10407 break;
10408 case TokenKind::OrAssign:
10409 kind = ParseNodeKind::OrAssignExpr;
10410 break;
10411 case TokenKind::AndAssign:
10412 kind = ParseNodeKind::AndAssignExpr;
10413 break;
10414 case TokenKind::BitOrAssign:
10415 kind = ParseNodeKind::BitOrAssignExpr;
10416 break;
10417 case TokenKind::BitXorAssign:
10418 kind = ParseNodeKind::BitXorAssignExpr;
10419 break;
10420 case TokenKind::BitAndAssign:
10421 kind = ParseNodeKind::BitAndAssignExpr;
10422 break;
10423 case TokenKind::LshAssign:
10424 kind = ParseNodeKind::LshAssignExpr;
10425 break;
10426 case TokenKind::RshAssign:
10427 kind = ParseNodeKind::RshAssignExpr;
10428 break;
10429 case TokenKind::UrshAssign:
10430 kind = ParseNodeKind::UrshAssignExpr;
10431 break;
10432 case TokenKind::MulAssign:
10433 kind = ParseNodeKind::MulAssignExpr;
10434 break;
10435 case TokenKind::DivAssign:
10436 kind = ParseNodeKind::DivAssignExpr;
10437 break;
10438 case TokenKind::ModAssign:
10439 kind = ParseNodeKind::ModAssignExpr;
10440 break;
10441 case TokenKind::PowAssign:
10442 kind = ParseNodeKind::PowAssignExpr;
10443 break;
10444
10445 default:
10446 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"
, 10446); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!anyChars.isCurrentTokenAssignment()"
")"); do { *((volatile int*)__null) = 10446; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10447 if (!possibleError) {
10448 if (!possibleErrorInner.checkForExpressionError()) {
10449 return errorResult();
10450 }
10451 } else {
10452 possibleErrorInner.transferErrorsTo(possibleError);
10453 }
10454
10455 anyChars.ungetToken();
10456 return lhs;
10457 }
10458
10459 // Verify the left-hand side expression doesn't have a forbidden form.
10460 if (handler_.isUnparenthesizedDestructuringPattern(lhs)) {
10461 if (kind != ParseNodeKind::AssignExpr) {
10462 error(JSMSG_BAD_DESTRUCT_ASS);
10463 return errorResult();
10464 }
10465
10466 if (!possibleErrorInner.checkForDestructuringErrorOrWarning()) {
10467 return errorResult();
10468 }
10469 } else if (handler_.isName(lhs)) {
10470 if (const char* chars = nameIsArgumentsOrEval(lhs)) {
10471 // |chars| is "arguments" or "eval" here.
10472 if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_STRICT_ASSIGN, chars)) {
10473 return errorResult();
10474 }
10475 }
10476 } else if (handler_.isArgumentsLength(lhs)) {
10477 pc_->sc()->setIneligibleForArgumentsLength();
10478 } else if (handler_.isPropertyOrPrivateMemberAccess(lhs)) {
10479 // Permitted: no additional testing/fixup needed.
10480 } else if (handler_.isFunctionCall(lhs)) {
10481 // We don't have to worry about backward compatibility issues with the new
10482 // compound assignment operators, so we always throw here. Also that way we
10483 // don't have to worry if |f() &&= expr| should always throw an error or
10484 // only if |f()| returns true.
10485 if (kind == ParseNodeKind::CoalesceAssignExpr ||
10486 kind == ParseNodeKind::OrAssignExpr ||
10487 kind == ParseNodeKind::AndAssignExpr) {
10488 errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
10489 return errorResult();
10490 }
10491
10492 if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS)) {
10493 return errorResult();
10494 }
10495
10496 if (possibleError) {
10497 possibleError->setPendingDestructuringErrorAt(exprPos,
10498 JSMSG_BAD_DESTRUCT_TARGET);
10499 }
10500 } else {
10501 errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
10502 return errorResult();
10503 }
10504
10505 if (!possibleErrorInner.checkForExpressionError()) {
10506 return errorResult();
10507 }
10508
10509 Node rhs;
10510 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)
;
10511
10512 return handler_.newAssignment(kind, lhs, rhs);
10513}
10514
10515template <class ParseHandler>
10516const char* PerHandlerParser<ParseHandler>::nameIsArgumentsOrEval(Node node) {
10517 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"
, 10518); AnnotateMozCrashReason("MOZ_ASSERT" "(" "handler_.isName(node)"
") (" "must only call this function on known names" ")"); do
{ *((volatile int*)__null) = 10518; __attribute__((nomerge))
::abort(); } while (false); } } while (false)
10518 "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"
, 10518); AnnotateMozCrashReason("MOZ_ASSERT" "(" "handler_.isName(node)"
") (" "must only call this function on known names" ")"); do
{ *((volatile int*)__null) = 10518; __attribute__((nomerge))
::abort(); } while (false); } } while (false)
;
10519
10520 if (handler_.isEvalName(node)) {
10521 return "eval";
10522 }
10523 if (handler_.isArgumentsName(node)) {
10524 return "arguments";
10525 }
10526 return nullptr;
10527}
10528
10529template <class ParseHandler, typename Unit>
10530bool GeneralParser<ParseHandler, Unit>::checkIncDecOperand(
10531 Node operand, uint32_t operandOffset) {
10532 if (handler_.isName(operand)) {
10533 if (const char* chars = nameIsArgumentsOrEval(operand)) {
10534 if (!strictModeErrorAt(operandOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) {
10535 return false;
10536 }
10537 }
10538 } else if (handler_.isArgumentsLength(operand)) {
10539 pc_->sc()->setIneligibleForArgumentsLength();
10540 } else if (handler_.isPropertyOrPrivateMemberAccess(operand)) {
10541 // Permitted: no additional testing/fixup needed.
10542 } else if (handler_.isFunctionCall(operand)) {
10543 // Assignment to function calls is forbidden in ES6. We're still
10544 // somewhat concerned about sites using this in dead code, so forbid it
10545 // only in strict mode code.
10546 if (!strictModeErrorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND)) {
10547 return false;
10548 }
10549 } else {
10550 errorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND);
10551 return false;
10552 }
10553 return true;
10554}
10555
10556template <class ParseHandler, typename Unit>
10557typename ParseHandler::UnaryNodeResult
10558GeneralParser<ParseHandler, Unit>::unaryOpExpr(YieldHandling yieldHandling,
10559 ParseNodeKind kind,
10560 uint32_t begin) {
10561 Node kid;
10562 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)
;
10563 return handler_.newUnary(kind, begin, kid);
10564}
10565
10566template <class ParseHandler, typename Unit>
10567typename ParseHandler::NodeResult
10568GeneralParser<ParseHandler, Unit>::optionalExpr(
10569 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10570 TokenKind tt, PossibleError* possibleError /* = nullptr */,
10571 InvokedPrediction invoked /* = PredictUninvoked */) {
10572 AutoCheckRecursionLimit recursion(this->fc_);
10573 if (!recursion.check(this->fc_)) {
10574 return errorResult();
10575 }
10576
10577 uint32_t begin = pos().begin;
10578
10579 Node lhs;
10580 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)
10581 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)
10582 /* 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)
;
10583
10584 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsDiv)) {
10585 return errorResult();
10586 }
10587
10588 if (tt != TokenKind::OptionalChain) {
10589 return lhs;
10590 }
10591
10592 while (true) {
10593 if (!tokenStream.getToken(&tt)) {
10594 return errorResult();
10595 }
10596
10597 if (tt == TokenKind::Eof) {
10598 anyChars.ungetToken();
10599 break;
10600 }
10601
10602 Node nextMember;
10603 if (tt == TokenKind::OptionalChain) {
10604 if (!tokenStream.getToken(&tt)) {
10605 return errorResult();
10606 }
10607 if (TokenKindIsPossibleIdentifierName(tt)) {
10608 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)
10609 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)
;
10610 } else if (tt == TokenKind::PrivateName) {
10611 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)
10612 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)
;
10613 } else if (tt == TokenKind::LeftBracket) {
10614 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)
10615 OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
, OptionalKind::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
;
10616 } else if (tt == TokenKind::LeftParen) {
10617 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)
10618 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)
10619 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)
;
10620 } else {
10621 error(JSMSG_NAME_AFTER_DOT);
10622 return errorResult();
10623 }
10624 } else if (tt == TokenKind::Dot) {
10625 if (!tokenStream.getToken(&tt)) {
10626 return errorResult();
10627 }
10628 if (TokenKindIsPossibleIdentifierName(tt)) {
10629 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)
;
10630 } else if (tt == TokenKind::PrivateName) {
10631 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)
;
10632 } else {
10633 error(JSMSG_NAME_AFTER_DOT);
10634 return errorResult();
10635 }
10636 } else if (tt == TokenKind::LeftBracket) {
10637 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)
;
10638 } else if (tt == TokenKind::LeftParen) {
10639 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)
10640 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)
;
10641 } else if (tt == TokenKind::TemplateHead ||
10642 tt == TokenKind::NoSubsTemplate) {
10643 error(JSMSG_BAD_OPTIONAL_TEMPLATE);
10644 return errorResult();
10645 } else {
10646 anyChars.ungetToken();
10647 break;
10648 }
10649
10650 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"
, 10650); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nextMember"
")"); do { *((volatile int*)__null) = 10650; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10651 lhs = nextMember;
10652 }
10653
10654 return handler_.newOptionalChain(begin, lhs);
10655}
10656
10657template <class ParseHandler, typename Unit>
10658typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::unaryExpr(
10659 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10660 PossibleError* possibleError /* = nullptr */,
10661 InvokedPrediction invoked /* = PredictUninvoked */,
10662 PrivateNameHandling privateNameHandling /* = PrivateNameProhibited */) {
10663 AutoCheckRecursionLimit recursion(this->fc_);
10664 if (!recursion.check(this->fc_)) {
10665 return errorResult();
10666 }
10667
10668 TokenKind tt;
10669 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
10670 return errorResult();
10671 }
10672 uint32_t begin = pos().begin;
10673 switch (tt) {
10674 case TokenKind::Void:
10675 return unaryOpExpr(yieldHandling, ParseNodeKind::VoidExpr, begin);
10676 case TokenKind::Not:
10677 return unaryOpExpr(yieldHandling, ParseNodeKind::NotExpr, begin);
10678 case TokenKind::BitNot:
10679 return unaryOpExpr(yieldHandling, ParseNodeKind::BitNotExpr, begin);
10680 case TokenKind::Add:
10681 return unaryOpExpr(yieldHandling, ParseNodeKind::PosExpr, begin);
10682 case TokenKind::Sub:
10683 return unaryOpExpr(yieldHandling, ParseNodeKind::NegExpr, begin);
10684
10685 case TokenKind::TypeOf: {
10686 // The |typeof| operator is specially parsed to distinguish its
10687 // application to a name, from its application to a non-name
10688 // expression:
10689 //
10690 // // Looks up the name, doesn't find it and so evaluates to
10691 // // "undefined".
10692 // assertEq(typeof nonExistentName, "undefined");
10693 //
10694 // // Evaluates expression, triggering a runtime ReferenceError for
10695 // // the undefined name.
10696 // typeof (1, nonExistentName);
10697 Node kid;
10698 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)
;
10699
10700 return handler_.newTypeof(begin, kid);
10701 }
10702
10703 case TokenKind::Inc:
10704 case TokenKind::Dec: {
10705 TokenKind tt2;
10706 if (!tokenStream.getToken(&tt2, TokenStream::SlashIsRegExp)) {
10707 return errorResult();
10708 }
10709
10710 uint32_t operandOffset = pos().begin;
10711 Node operand;
10712 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)
10713 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)
;
10714 if (!checkIncDecOperand(operand, operandOffset)) {
10715 return errorResult();
10716 }
10717 ParseNodeKind pnk = (tt == TokenKind::Inc)
10718 ? ParseNodeKind::PreIncrementExpr
10719 : ParseNodeKind::PreDecrementExpr;
10720 return handler_.newUpdate(pnk, begin, operand);
10721 }
10722 case TokenKind::PrivateName: {
10723 if (privateNameHandling == PrivateNameHandling::PrivateNameAllowed) {
10724 TaggedParserAtomIndex field = anyChars.currentName();
10725 return privateNameReference(field);
10726 }
10727 error(JSMSG_INVALID_PRIVATE_NAME_IN_UNARY_EXPR);
10728 return errorResult();
10729 }
10730
10731 case TokenKind::Delete: {
10732 uint32_t exprOffset;
10733 if (!tokenStream.peekOffset(&exprOffset, TokenStream::SlashIsRegExp)) {
10734 return errorResult();
10735 }
10736
10737 Node expr;
10738 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)
;
10739
10740 // Per spec, deleting most unary expressions is valid -- it simply
10741 // returns true -- except for two cases:
10742 // 1. `var x; ...; delete x` is a syntax error in strict mode.
10743 // 2. Private fields cannot be deleted.
10744 if (handler_.isName(expr)) {
10745 if (!strictModeErrorAt(exprOffset, JSMSG_DEPRECATED_DELETE_OPERAND)) {
10746 return errorResult();
10747 }
10748
10749 pc_->sc()->setBindingsAccessedDynamically();
10750 }
10751
10752 if (handler_.isPrivateMemberAccess(expr)) {
10753 errorAt(exprOffset, JSMSG_PRIVATE_DELETE);
10754 return errorResult();
10755 }
10756
10757 return handler_.newDelete(begin, expr);
10758 }
10759 case TokenKind::Await: {
10760 // If we encounter an await in a module, mark it as async.
10761 if (!pc_->isAsync() && pc_->sc()->isModule()) {
10762 if (!options().topLevelAwait) {
10763 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
10764 return errorResult();
10765 }
10766 pc_->sc()->asModuleContext()->setIsAsync();
10767 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"
, 10767); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 10767; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10768 }
10769
10770 if (pc_->isAsync()) {
10771 if (inParametersOfAsyncFunction()) {
10772 error(JSMSG_AWAIT_IN_PARAMETER);
10773 return errorResult();
10774 }
10775 Node kid;
10776 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)
10777 possibleError, invoked))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
10778 pc_->lastAwaitOffset = begin;
10779 return handler_.newAwaitExpression(begin, kid);
10780 }
10781 }
10782
10783 [[fallthrough]];
10784
10785 default: {
10786 Node expr;
10787 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)
10788 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)
;
10789
10790 /* Don't look across a newline boundary for a postfix incop. */
10791 if (!tokenStream.peekTokenSameLine(&tt)) {
10792 return errorResult();
10793 }
10794
10795 if (tt != TokenKind::Inc && tt != TokenKind::Dec) {
10796 return expr;
10797 }
10798
10799 tokenStream.consumeKnownToken(tt);
10800 if (!checkIncDecOperand(expr, begin)) {
10801 return errorResult();
10802 }
10803
10804 ParseNodeKind pnk = (tt == TokenKind::Inc)
10805 ? ParseNodeKind::PostIncrementExpr
10806 : ParseNodeKind::PostDecrementExpr;
10807 return handler_.newUpdate(pnk, begin, expr);
10808 }
10809 }
10810}
10811
10812template <class ParseHandler, typename Unit>
10813typename ParseHandler::NodeResult
10814GeneralParser<ParseHandler, Unit>::assignExprWithoutYieldOrAwait(
10815 YieldHandling yieldHandling) {
10816 uint32_t startYieldOffset = pc_->lastYieldOffset;
10817 uint32_t startAwaitOffset = pc_->lastAwaitOffset;
10818
10819 Node res;
10820 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)
;
10821
10822 if (pc_->lastYieldOffset != startYieldOffset) {
10823 errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
10824 return errorResult();
10825 }
10826 if (pc_->lastAwaitOffset != startAwaitOffset) {
10827 errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
10828 return errorResult();
10829 }
10830 return res;
10831}
10832
10833template <class ParseHandler, typename Unit>
10834typename ParseHandler::ListNodeResult
10835GeneralParser<ParseHandler, Unit>::argumentList(
10836 YieldHandling yieldHandling, bool* isSpread,
10837 PossibleError* possibleError /* = nullptr */) {
10838 ListNodeType argsList;
10839 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)
;
10840
10841 bool matched;
10842 if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
10843 TokenStream::SlashIsRegExp)) {
10844 return errorResult();
10845 }
10846 if (matched) {
10847 handler_.setEndPosition(argsList, pos().end);
10848 return argsList;
10849 }
10850
10851 while (true) {
10852 bool spread = false;
10853 uint32_t begin = 0;
10854 if (!tokenStream.matchToken(&matched, TokenKind::TripleDot,
10855 TokenStream::SlashIsRegExp)) {
10856 return errorResult();
10857 }
10858 if (matched) {
10859 spread = true;
10860 begin = pos().begin;
10861 *isSpread = true;
10862 }
10863
10864 Node argNode;
10865 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)
10866 TripledotProhibited, possibleError))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, possibleError)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (argNode) = mozTryVarTempResult_.unwrap();
} while (0)
;
10867 if (spread) {
10868 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)
;
10869 }
10870
10871 handler_.addList(argsList, argNode);
10872
10873 bool matched;
10874 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
10875 TokenStream::SlashIsRegExp)) {
10876 return errorResult();
10877 }
10878 if (!matched) {
10879 break;
10880 }
10881
10882 TokenKind tt;
10883 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
10884 return errorResult();
10885 }
10886 if (tt == TokenKind::RightParen) {
10887 break;
10888 }
10889 }
10890
10891 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_ARGS)) {
10892 return errorResult();
10893 }
10894
10895 handler_.setEndPosition(argsList, pos().end);
10896 return argsList;
10897}
10898
10899bool ParserBase::checkAndMarkSuperScope() {
10900 if (!pc_->sc()->allowSuperProperty()) {
10901 return false;
10902 }
10903
10904 pc_->setSuperScopeNeedsHomeObject();
10905 return true;
10906}
10907
10908template <class ParseHandler, typename Unit>
10909bool GeneralParser<ParseHandler, Unit>::computeErrorMetadata(
10910 ErrorMetadata* err, const ErrorReportMixin::ErrorOffset& offset) const {
10911 if (offset.is<ErrorReportMixin::Current>()) {
10912 return tokenStream.computeErrorMetadata(err, AsVariant(pos().begin));
10913 }
10914 return tokenStream.computeErrorMetadata(err, offset);
10915}
10916
10917template <class ParseHandler, typename Unit>
10918typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::memberExpr(
10919 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10920 TokenKind tt, bool allowCallSyntax, PossibleError* possibleError,
10921 InvokedPrediction invoked) {
10922 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"
, 10922); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 10922; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10923
10924 Node lhs;
10925
10926 AutoCheckRecursionLimit recursion(this->fc_);
10927 if (!recursion.check(this->fc_)) {
10928 return errorResult();
10929 }
10930
10931 /* Check for new expression first. */
10932 if (tt == TokenKind::New) {
10933 uint32_t newBegin = pos().begin;
10934 // Make sure this wasn't a |new.target| in disguise.
10935 NewTargetNodeType newTarget;
10936 if (!tryNewTarget(&newTarget)) {
10937 return errorResult();
10938 }
10939 if (newTarget) {
10940 lhs = newTarget;
10941 } else {
10942 // Gotten by tryNewTarget
10943 tt = anyChars.currentToken().type;
10944 Node ctorExpr;
10945 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)
10946 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)
10947 /* 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)
10948 /* 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)
;
10949
10950 // If we have encountered an optional chain, in the form of `new
10951 // ClassName?.()` then we need to throw, as this is disallowed by the
10952 // spec.
10953 bool optionalToken;
10954 if (!tokenStream.matchToken(&optionalToken, TokenKind::OptionalChain)) {
10955 return errorResult();
10956 }
10957 if (optionalToken) {
10958 errorAt(newBegin, JSMSG_BAD_NEW_OPTIONAL);
10959 return errorResult();
10960 }
10961
10962 bool matched;
10963 if (!tokenStream.matchToken(&matched, TokenKind::LeftParen)) {
10964 return errorResult();
10965 }
10966
10967 bool isSpread = false;
10968 ListNodeType args;
10969 if (matched) {
10970 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)
;
10971 } else {
10972 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)
;
10973 }
10974
10975 if (!args) {
10976 return errorResult();
10977 }
10978
10979 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)
10980 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)
;
10981 }
10982 } else if (tt == TokenKind::Super) {
10983 NameNodeType thisName;
10984 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
10985 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)
;
10986 } else if (tt == TokenKind::Import) {
10987 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)
;
10988 } else {
10989 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)
10990 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)
;
10991 }
10992
10993 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"
, 10994); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Super)"
")"); do { *((volatile int*)__null) = 10994; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
10994 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"
, 10994); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Super)"
")"); do { *((volatile int*)__null) = 10994; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
;
10995
10996 while (true) {
10997 if (!tokenStream.getToken(&tt)) {
10998 return errorResult();
10999 }
11000 if (tt == TokenKind::Eof) {
11001 anyChars.ungetToken();
11002 break;
11003 }
11004
11005 Node nextMember;
11006 if (tt == TokenKind::Dot) {
11007 if (!tokenStream.getToken(&tt)) {
11008 return errorResult();
11009 }
11010
11011 if (TokenKindIsPossibleIdentifierName(tt)) {
11012 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)
;
11013 } else if (tt == TokenKind::PrivateName) {
11014 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)
;
11015 } else {
11016 error(JSMSG_NAME_AFTER_DOT);
11017 return errorResult();
11018 }
11019 } else if (tt == TokenKind::LeftBracket) {
11020 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)
;
11021 } else if ((allowCallSyntax && tt == TokenKind::LeftParen) ||
11022 tt == TokenKind::TemplateHead ||
11023 tt == TokenKind::NoSubsTemplate) {
11024 if (handler_.isSuperBase(lhs)) {
11025 if (!pc_->sc()->allowSuperCall()) {
11026 error(JSMSG_BAD_SUPERCALL);
11027 return errorResult();
11028 }
11029
11030 if (tt != TokenKind::LeftParen) {
11031 error(JSMSG_BAD_SUPER);
11032 return errorResult();
11033 }
11034
11035 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)
;
11036
11037 if (!noteUsedName(
11038 TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
11039 return errorResult();
11040 }
11041#ifdef ENABLE_DECORATORS
11042 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
11043 dot_instanceExtraInitializers_())) {
11044 return null();
11045 }
11046#endif
11047 } else {
11048 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)
11049 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)
;
11050 }
11051 } else {
11052 anyChars.ungetToken();
11053 if (handler_.isSuperBase(lhs)) {
11054 break;
11055 }
11056 return lhs;
11057 }
11058
11059 lhs = nextMember;
11060 }
11061
11062 if (handler_.isSuperBase(lhs)) {
11063 error(JSMSG_BAD_SUPER);
11064 return errorResult();
11065 }
11066
11067 return lhs;
11068}
11069
11070template <class ParseHandler, typename Unit>
11071typename ParseHandler::NodeResult
11072GeneralParser<ParseHandler, Unit>::decoratorExpr(YieldHandling yieldHandling,
11073 TokenKind tt) {
11074 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"
, 11074); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 11074; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11075
11076 AutoCheckRecursionLimit recursion(this->fc_);
11077 if (!recursion.check(this->fc_)) {
11078 return errorResult();
11079 }
11080
11081 if (tt == TokenKind::LeftParen) {
11082 // DecoratorParenthesizedExpression
11083 Node expr;
11084 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)
11085 /* possibleError*/ nullptr))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (expr) = mozTryVarTempResult_.unwrap(); } while (0)
;
11086 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_DECORATOR)) {
11087 return errorResult();
11088 }
11089
11090 return handler_.parenthesize(expr);
11091 }
11092
11093 if (!TokenKindIsPossibleIdentifier(tt)) {
11094 error(JSMSG_DECORATOR_NAME_EXPECTED);
11095 return errorResult();
11096 }
11097
11098 TaggedParserAtomIndex name = identifierReference(yieldHandling);
11099 if (!name) {
11100 return errorResult();
11101 }
11102
11103 Node lhs;
11104 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)
;
11105
11106 while (true) {
11107 if (!tokenStream.getToken(&tt)) {
11108 return errorResult();
11109 }
11110 if (tt == TokenKind::Eof) {
11111 anyChars.ungetToken();
11112 break;
11113 }
11114
11115 Node nextMember;
11116 if (tt == TokenKind::Dot) {
11117 if (!tokenStream.getToken(&tt)) {
11118 return errorResult();
11119 }
11120
11121 if (TokenKindIsPossibleIdentifierName(tt)) {
11122 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)
;
11123 } else if (tt == TokenKind::PrivateName) {
11124 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)
;
11125 } else {
11126 error(JSMSG_NAME_AFTER_DOT);
11127 return errorResult();
11128 }
11129 } else if (tt == TokenKind::LeftParen) {
11130 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)
11131 /* possibleError */ nullptr))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11132 lhs = nextMember;
11133 // This is a `DecoratorCallExpression` and it's defined at the top level
11134 // of `Decorator`, no other `DecoratorMemberExpression` is allowed to
11135 // follow after the arguments.
11136 break;
11137 } else {
11138 anyChars.ungetToken();
11139 break;
11140 }
11141
11142 lhs = nextMember;
11143 }
11144
11145 return lhs;
11146}
11147
11148template <class ParseHandler>
11149inline typename ParseHandler::NameNodeResult
11150PerHandlerParser<ParseHandler>::newName(TaggedParserAtomIndex name) {
11151 return newName(name, pos());
11152}
11153
11154template <class ParseHandler>
11155inline typename ParseHandler::NameNodeResult
11156PerHandlerParser<ParseHandler>::newName(TaggedParserAtomIndex name,
11157 TokenPos pos) {
11158 if (name == TaggedParserAtomIndex::WellKnown::arguments()) {
11159 this->pc_->numberOfArgumentsNames++;
11160 }
11161 return handler_.newName(name, pos);
11162}
11163
11164template <class ParseHandler>
11165inline typename ParseHandler::NameNodeResult
11166PerHandlerParser<ParseHandler>::newPrivateName(TaggedParserAtomIndex name) {
11167 return handler_.newPrivateName(name, pos());
11168}
11169
11170template <class ParseHandler, typename Unit>
11171typename ParseHandler::NodeResult
11172GeneralParser<ParseHandler, Unit>::memberPropertyAccess(
11173 Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11174 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"
, 11175); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11175; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
11175 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"
, 11175); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11175; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11176 TaggedParserAtomIndex field = anyChars.currentName();
11177 if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
11178 error(JSMSG_BAD_SUPERPROP, "property");
11179 return errorResult();
11180 }
11181
11182 NameNodeType name;
11183 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)
;
11184
11185 if (optionalKind == OptionalKind::Optional) {
11186 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"
, 11186); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11186; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11187 return handler_.newOptionalPropertyAccess(lhs, name);
11188 }
11189
11190 if (handler_.isArgumentsName(lhs) && handler_.isLengthName(name)) {
11191 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"
, 11191); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->numberOfArgumentsNames > 0"
")"); do { *((volatile int*)__null) = 11191; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11192 pc_->numberOfArgumentsNames--;
11193 // Currently when resuming Generators don't get their argument length set
11194 // in the interpreter frame (see InterpreterStack::resumeGeneratorCallFrame,
11195 // and its call to initCallFrame).
11196 if (pc_->isGeneratorOrAsync()) {
11197 pc_->sc()->setIneligibleForArgumentsLength();
11198 }
11199 return handler_.newArgumentsLength(lhs, name);
11200 }
11201
11202 return handler_.newPropertyAccess(lhs, name);
11203}
11204
11205template <class ParseHandler, typename Unit>
11206typename ParseHandler::NodeResult
11207GeneralParser<ParseHandler, Unit>::memberPrivateAccess(
11208 Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11209 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"
, 11209); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11209; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11210
11211 TaggedParserAtomIndex field = anyChars.currentName();
11212 // Cannot access private fields on super.
11213 if (handler_.isSuperBase(lhs)) {
11214 error(JSMSG_BAD_SUPERPRIVATE);
11215 return errorResult();
11216 }
11217
11218 NameNodeType privateName;
11219 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)
;
11220
11221 if (optionalKind == OptionalKind::Optional) {
11222 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"
, 11222); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11222; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11223 return handler_.newOptionalPrivateMemberAccess(lhs, privateName, pos().end);
11224 }
11225 return handler_.newPrivateMemberAccess(lhs, privateName, pos().end);
11226}
11227
11228template <class ParseHandler, typename Unit>
11229typename ParseHandler::NodeResult
11230GeneralParser<ParseHandler, Unit>::memberElemAccess(
11231 Node lhs, YieldHandling yieldHandling,
11232 OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11233 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"
, 11233); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::LeftBracket"
")"); do { *((volatile int*)__null) = 11233; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11234 Node propExpr;
11235 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)
;
11236
11237 if (!mustMatchToken(TokenKind::RightBracket, JSMSG_BRACKET_IN_INDEX)) {
11238 return errorResult();
11239 }
11240
11241 if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
11242 error(JSMSG_BAD_SUPERPROP, "member");
11243 return errorResult();
11244 }
11245 if (optionalKind == OptionalKind::Optional) {
11246 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"
, 11246); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11246; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11247 return handler_.newOptionalPropertyByValue(lhs, propExpr, pos().end);
11248 }
11249 return handler_.newPropertyByValue(lhs, propExpr, pos().end);
11250}
11251
11252template <class ParseHandler, typename Unit>
11253typename ParseHandler::NodeResult
11254GeneralParser<ParseHandler, Unit>::memberSuperCall(
11255 Node lhs, YieldHandling yieldHandling) {
11256 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"
, 11256); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::LeftParen"
")"); do { *((volatile int*)__null) = 11256; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11257 // Despite the fact that it's impossible to have |super()| in a
11258 // generator, we still inherit the yieldHandling of the
11259 // memberExpression, per spec. Curious.
11260 bool isSpread = false;
11261 ListNodeType args;
11262 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)
;
11263
11264 CallNodeType superCall;
11265 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)
;
11266
11267 // |super()| implicitly reads |new.target|.
11268 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
11269 return errorResult();
11270 }
11271
11272 NameNodeType thisName;
11273 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
11274
11275 return handler_.newSetThis(thisName, superCall);
11276}
11277
11278template <class ParseHandler, typename Unit>
11279typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::memberCall(
11280 TokenKind tt, Node lhs, YieldHandling yieldHandling,
11281 PossibleError* possibleError /* = nullptr */,
11282 OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11283 if (options().selfHostingMode &&
11284 (handler_.isPropertyOrPrivateMemberAccess(lhs) ||
11285 handler_.isOptionalPropertyOrPrivateMemberAccess(lhs))) {
11286 error(JSMSG_SELFHOSTED_METHOD_CALL);
11287 return errorResult();
11288 }
11289
11290 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"
, 11292); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11292; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
11291 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"
, 11292); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11292; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
11292 "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"
, 11292); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11292; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
11293
11294 JSOp op = JSOp::Call;
11295 bool maybeAsyncArrow = false;
11296 if (tt == TokenKind::LeftParen && optionalKind == OptionalKind::NonOptional) {
11297 if (handler_.isAsyncKeyword(lhs)) {
11298 // |async (| can be the start of an async arrow
11299 // function, so we need to defer reporting possible
11300 // errors from destructuring syntax. To give better
11301 // error messages, we only allow the AsyncArrowHead
11302 // part of the CoverCallExpressionAndAsyncArrowHead
11303 // syntax when the initial name is "async".
11304 maybeAsyncArrow = true;
11305 } else if (handler_.isEvalName(lhs)) {
11306 // Select the right Eval op and flag pc_ as having a
11307 // direct eval.
11308 op = pc_->sc()->strict() ? JSOp::StrictEval : JSOp::Eval;
11309 pc_->sc()->setBindingsAccessedDynamically();
11310 pc_->sc()->setHasDirectEval();
11311
11312 // In non-strict mode code, direct calls to eval can
11313 // add variables to the call object.
11314 if (pc_->isFunctionBox() && !pc_->sc()->strict()) {
11315 pc_->functionBox()->setFunHasExtensibleScope();
11316 }
11317
11318 // If we're in a method, mark the method as requiring
11319 // support for 'super', since direct eval code can use
11320 // it. (If we're not in a method, that's fine, so
11321 // ignore the return value.)
11322 checkAndMarkSuperScope();
11323 }
11324 }
11325
11326 if (tt == TokenKind::LeftParen) {
11327 bool isSpread = false;
11328 PossibleError* asyncPossibleError =
11329 maybeAsyncArrow ? possibleError : nullptr;
11330 ListNodeType args;
11331 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)
11332 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)
;
11333 if (isSpread) {
11334 if (op == JSOp::Eval) {
11335 op = JSOp::SpreadEval;
11336 } else if (op == JSOp::StrictEval) {
11337 op = JSOp::StrictSpreadEval;
11338 } else {
11339 op = JSOp::SpreadCall;
11340 }
11341 }
11342
11343 if (optionalKind == OptionalKind::Optional) {
11344 return handler_.newOptionalCall(lhs, args, op);
11345 }
11346 return handler_.newCall(lhs, args, op);
11347 }
11348
11349 ListNodeType args;
11350 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)
;
11351
11352 if (!taggedTemplate(yieldHandling, args, tt)) {
11353 return errorResult();
11354 }
11355
11356 if (optionalKind == OptionalKind::Optional) {
11357 error(JSMSG_BAD_OPTIONAL_TEMPLATE);
11358 return errorResult();
11359 }
11360
11361 return handler_.newTaggedTemplate(lhs, args, op);
11362}
11363
11364template <class ParseHandler, typename Unit>
11365bool GeneralParser<ParseHandler, Unit>::checkLabelOrIdentifierReference(
11366 TaggedParserAtomIndex ident, uint32_t offset, YieldHandling yieldHandling,
11367 TokenKind hint /* = TokenKind::Limit */) {
11368 TokenKind tt;
11369 if (hint == TokenKind::Limit) {
11370 tt = ReservedWordTokenKind(ident);
11371 } else {
11372 // All non-reserved word kinds are folded into TokenKind::Limit in
11373 // ReservedWordTokenKind and the following code.
11374 if (hint == TokenKind::Name || hint == TokenKind::PrivateName) {
11375 hint = TokenKind::Limit;
11376 }
11377 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"
, 11378); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hint == ReservedWordTokenKind(ident)"
") (" "hint doesn't match actual token kind" ")"); do { *((volatile
int*)__null) = 11378; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
11378 "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"
, 11378); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hint == ReservedWordTokenKind(ident)"
") (" "hint doesn't match actual token kind" ")"); do { *((volatile
int*)__null) = 11378; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
11379 tt = hint;
11380 }
11381
11382 if (!pc_->sc()->allowArguments() &&
11383 ident == TaggedParserAtomIndex::WellKnown::arguments()) {
11384 error(JSMSG_BAD_ARGUMENTS);
11385 return false;
11386 }
11387
11388 if (tt == TokenKind::Limit) {
11389 // Either TokenKind::Name or TokenKind::PrivateName
11390 return true;
11391 }
11392 if (TokenKindIsContextualKeyword(tt)) {
11393 if (tt == TokenKind::Yield) {
11394 if (yieldHandling == YieldIsKeyword) {
11395 errorAt(offset, JSMSG_RESERVED_ID, "yield");
11396 return false;
11397 }
11398 if (pc_->sc()->strict()) {
11399 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "yield")) {
11400 return false;
11401 }
11402 }
11403 return true;
11404 }
11405 if (tt == TokenKind::Await) {
11406 if (awaitIsKeyword() || awaitIsDisallowed()) {
11407 errorAt(offset, JSMSG_RESERVED_ID, "await");
11408 return false;
11409 }
11410 return true;
11411 }
11412 if (pc_->sc()->strict()) {
11413 if (tt == TokenKind::Let) {
11414 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "let")) {
11415 return false;
11416 }
11417 return true;
11418 }
11419 if (tt == TokenKind::Static) {
11420 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "static")) {
11421 return false;
11422 }
11423 return true;
11424 }
11425 }
11426 return true;
11427 }
11428 if (TokenKindIsStrictReservedWord(tt)) {
11429 if (pc_->sc()->strict()) {
11430 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID,
11431 ReservedWordToCharZ(tt))) {
11432 return false;
11433 }
11434 }
11435 return true;
11436 }
11437 if (TokenKindIsKeyword(tt) || TokenKindIsReservedWordLiteral(tt)) {
11438 errorAt(offset, JSMSG_INVALID_ID, ReservedWordToCharZ(tt));
11439 return false;
11440 }
11441 if (TokenKindIsFutureReservedWord(tt)) {
11442 errorAt(offset, JSMSG_RESERVED_ID, ReservedWordToCharZ(tt));
11443 return false;
11444 }
11445 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"
, 11445); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected reserved word kind." ")"
); do { *((volatile int*)__null) = 11445; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
11446 return false;
11447}
11448
11449template <class ParseHandler, typename Unit>
11450bool GeneralParser<ParseHandler, Unit>::checkBindingIdentifier(
11451 TaggedParserAtomIndex ident, uint32_t offset, YieldHandling yieldHandling,
11452 TokenKind hint /* = TokenKind::Limit */) {
11453 if (pc_->sc()->strict()) {
11454 if (ident == TaggedParserAtomIndex::WellKnown::arguments()) {
11455 if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "arguments")) {
11456 return false;
11457 }
11458 return true;
11459 }
11460
11461 if (ident == TaggedParserAtomIndex::WellKnown::eval()) {
11462 if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "eval")) {
11463 return false;
11464 }
11465 return true;
11466 }
11467 }
11468
11469 return checkLabelOrIdentifierReference(ident, offset, yieldHandling, hint);
11470}
11471
11472template <class ParseHandler, typename Unit>
11473TaggedParserAtomIndex
11474GeneralParser<ParseHandler, Unit>::labelOrIdentifierReference(
11475 YieldHandling yieldHandling) {
11476 // ES 2017 draft 12.1.1.
11477 // StringValue of IdentifierName normalizes any Unicode escape sequences
11478 // in IdentifierName hence such escapes cannot be used to write an
11479 // Identifier whose code point sequence is the same as a ReservedWord.
11480 //
11481 // Use const ParserName* instead of TokenKind to reflect the normalization.
11482
11483 // Unless the name contains escapes, we can reuse the current TokenKind
11484 // to determine if the name is a restricted identifier.
11485 TokenKind hint = !anyChars.currentNameHasEscapes(this->parserAtoms())
11486 ? anyChars.currentToken().type
11487 : TokenKind::Limit;
11488 TaggedParserAtomIndex ident = anyChars.currentName();
11489 if (!checkLabelOrIdentifierReference(ident, pos().begin, yieldHandling,
11490 hint)) {
11491 return TaggedParserAtomIndex::null();
11492 }
11493 return ident;
11494}
11495
11496template <class ParseHandler, typename Unit>
11497TaggedParserAtomIndex GeneralParser<ParseHandler, Unit>::bindingIdentifier(
11498 YieldHandling yieldHandling) {
11499 TokenKind hint = !anyChars.currentNameHasEscapes(this->parserAtoms())
11500 ? anyChars.currentToken().type
11501 : TokenKind::Limit;
11502 TaggedParserAtomIndex ident = anyChars.currentName();
11503 if (!checkBindingIdentifier(ident, pos().begin, yieldHandling, hint)) {
11504 return TaggedParserAtomIndex::null();
11505 }
11506 return ident;
11507}
11508
11509template <class ParseHandler>
11510typename ParseHandler::NameNodeResult
11511PerHandlerParser<ParseHandler>::identifierReference(
11512 TaggedParserAtomIndex name) {
11513 NameNodeType id;
11514 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)
;
11515
11516 if (!noteUsedName(name)) {
11517 return errorResult();
11518 }
11519
11520 return id;
11521}
11522
11523template <class ParseHandler>
11524typename ParseHandler::NameNodeResult
11525PerHandlerParser<ParseHandler>::privateNameReference(
11526 TaggedParserAtomIndex name) {
11527 NameNodeType id;
11528 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)
;
11529
11530 if (!noteUsedName(name, NameVisibility::Private, Some(pos()))) {
11531 return errorResult();
11532 }
11533
11534 return id;
11535}
11536
11537template <class ParseHandler>
11538typename ParseHandler::NameNodeResult
11539PerHandlerParser<ParseHandler>::stringLiteral() {
11540 return handler_.newStringLiteral(anyChars.currentToken().atom(), pos());
11541}
11542
11543template <class ParseHandler>
11544typename ParseHandler::NodeResult
11545PerHandlerParser<ParseHandler>::noSubstitutionTaggedTemplate() {
11546 if (anyChars.hasInvalidTemplateEscape()) {
11547 anyChars.clearInvalidTemplateEscape();
11548 return handler_.newRawUndefinedLiteral(pos());
11549 }
11550
11551 return handler_.newTemplateStringLiteral(anyChars.currentToken().atom(),
11552 pos());
11553}
11554
11555template <class ParseHandler, typename Unit>
11556typename ParseHandler::NameNodeResult
11557GeneralParser<ParseHandler, Unit>::noSubstitutionUntaggedTemplate() {
11558 if (!tokenStream.checkForInvalidTemplateEscapeError()) {
11559 return errorResult();
11560 }
11561
11562 return handler_.newTemplateStringLiteral(anyChars.currentToken().atom(),
11563 pos());
11564}
11565
11566template <typename Unit>
11567FullParseHandler::RegExpLiteralResult
11568Parser<FullParseHandler, Unit>::newRegExp() {
11569 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"
, 11569); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 11569; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11570
11571 // Create the regexp and check its syntax.
11572 const auto& chars = tokenStream.getCharBuffer();
11573 mozilla::Range<const char16_t> range(chars.begin(), chars.length());
11574 RegExpFlags flags = anyChars.currentToken().regExpFlags();
11575
11576 uint32_t offset = anyChars.currentToken().pos.begin;
11577 uint32_t line;
11578 JS::LimitedColumnNumberOneOrigin column;
11579 tokenStream.computeLineAndColumn(offset, &line, &column);
11580
11581 if (!handler_.reuseRegexpSyntaxParse()) {
11582 // Verify that the Regexp will syntax parse when the time comes to
11583 // instantiate it. If we have already done a syntax parse, we can
11584 // skip this.
11585 if (!irregexp::CheckPatternSyntax(
11586 this->alloc_, this->fc_->stackLimit(), anyChars, range, flags,
11587 Some(line), Some(JS::ColumnNumberOneOrigin(column)))) {
11588 return errorResult();
11589 }
11590 }
11591
11592 auto atom =
11593 this->parserAtoms().internChar16(fc_, chars.begin(), chars.length());
11594 if (!atom) {
11595 return errorResult();
11596 }
11597 // RegExp patterm must be atomized.
11598 this->parserAtoms().markUsedByStencil(atom, ParserAtom::Atomize::Yes);
11599
11600 RegExpIndex index(this->compilationState_.regExpData.length());
11601 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
11602 ReportAllocationOverflow(fc_);
11603 return errorResult();
11604 }
11605 if (!this->compilationState_.regExpData.emplaceBack(atom, flags)) {
11606 js::ReportOutOfMemory(this->fc_);
11607 return errorResult();
11608 }
11609
11610 return handler_.newRegExp(index, pos());
11611}
11612
11613template <typename Unit>
11614SyntaxParseHandler::RegExpLiteralResult
11615Parser<SyntaxParseHandler, Unit>::newRegExp() {
11616 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"
, 11616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 11616; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11617
11618 // Only check the regexp's syntax, but don't create a regexp object.
11619 const auto& chars = tokenStream.getCharBuffer();
11620 RegExpFlags flags = anyChars.currentToken().regExpFlags();
11621
11622 uint32_t offset = anyChars.currentToken().pos.begin;
11623 uint32_t line;
11624 JS::LimitedColumnNumberOneOrigin column;
11625 tokenStream.computeLineAndColumn(offset, &line, &column);
11626
11627 mozilla::Range<const char16_t> source(chars.begin(), chars.length());
11628 if (!irregexp::CheckPatternSyntax(this->alloc_, this->fc_->stackLimit(),
11629 anyChars, source, flags, Some(line),
11630 Some(JS::ColumnNumberOneOrigin(column)))) {
11631 return errorResult();
11632 }
11633
11634 return handler_.newRegExp(SyntaxParseHandler::Node::NodeGeneric, pos());
11635}
11636
11637template <class ParseHandler, typename Unit>
11638typename ParseHandler::RegExpLiteralResult
11639GeneralParser<ParseHandler, Unit>::newRegExp() {
11640 return asFinalParser()->newRegExp();
11641}
11642
11643template <typename Unit>
11644FullParseHandler::BigIntLiteralResult
11645Parser<FullParseHandler, Unit>::newBigInt() {
11646 // The token's charBuffer contains the DecimalIntegerLiteral or
11647 // NonDecimalIntegerLiteral production, and as such does not include the
11648 // BigIntLiteralSuffix (the trailing "n"). Note that NonDecimalIntegerLiteral
11649 // productions start with 0[bBoOxX], indicating binary/octal/hex.
11650 const auto& chars = tokenStream.getCharBuffer();
11651 if (chars.length() > UINT32_MAX(4294967295U)) {
11652 ReportAllocationOverflow(fc_);
11653 return errorResult();
11654 }
11655
11656 BigIntIndex index(this->bigInts().length());
11657 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
11658 ReportAllocationOverflow(fc_);
11659 return errorResult();
11660 }
11661 if (!this->bigInts().emplaceBack()) {
11662 js::ReportOutOfMemory(this->fc_);
11663 return errorResult();
11664 }
11665
11666 if (!this->bigInts()[index].init(this->fc_, this->stencilAlloc(), chars)) {
11667 return errorResult();
11668 }
11669
11670 // Should the operations below fail, the buffer held by data will
11671 // be cleaned up by the CompilationState destructor.
11672 return handler_.newBigInt(index, pos());
11673}
11674
11675template <typename Unit>
11676SyntaxParseHandler::BigIntLiteralResult
11677Parser<SyntaxParseHandler, Unit>::newBigInt() {
11678 // The tokenizer has already checked the syntax of the bigint.
11679
11680 return handler_.newBigInt();
11681}
11682
11683template <class ParseHandler, typename Unit>
11684typename ParseHandler::BigIntLiteralResult
11685GeneralParser<ParseHandler, Unit>::newBigInt() {
11686 return asFinalParser()->newBigInt();
11687}
11688
11689// |exprPossibleError| is the PossibleError state within |expr|,
11690// |possibleError| is the surrounding PossibleError state.
11691template <class ParseHandler, typename Unit>
11692bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentTarget(
11693 Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
11694 PossibleError* possibleError, TargetBehavior behavior) {
11695 // Report any pending expression error if we're definitely not in a
11696 // destructuring context or the possible destructuring target is a
11697 // property accessor.
11698 if (!possibleError || handler_.isPropertyOrPrivateMemberAccess(expr)) {
11699 return exprPossibleError->checkForExpressionError();
11700 }
11701
11702 // |expr| may end up as a destructuring assignment target, so we need to
11703 // validate it's either a name or can be parsed as a nested destructuring
11704 // pattern. Property accessors are also valid assignment targets, but
11705 // those are already handled above.
11706
11707 exprPossibleError->transferErrorsTo(possibleError);
11708
11709 // Return early if a pending destructuring error is already present.
11710 if (possibleError->hasPendingDestructuringError()) {
11711 return true;
11712 }
11713
11714 if (handler_.isName(expr)) {
11715 checkDestructuringAssignmentName(handler_.asNameNode(expr), exprPos,
11716 possibleError);
11717 return true;
11718 }
11719
11720 if (handler_.isUnparenthesizedDestructuringPattern(expr)) {
11721 if (behavior == TargetBehavior::ForbidAssignmentPattern) {
11722 possibleError->setPendingDestructuringErrorAt(exprPos,
11723 JSMSG_BAD_DESTRUCT_TARGET);
11724 }
11725 return true;
11726 }
11727
11728 // Parentheses are forbidden around destructuring *patterns* (but allowed
11729 // around names). Use our nicer error message for parenthesized, nested
11730 // patterns if nested destructuring patterns are allowed.
11731 if (handler_.isParenthesizedDestructuringPattern(expr) &&
11732 behavior != TargetBehavior::ForbidAssignmentPattern) {
11733 possibleError->setPendingDestructuringErrorAt(exprPos,
11734 JSMSG_BAD_DESTRUCT_PARENS);
11735 } else {
11736 possibleError->setPendingDestructuringErrorAt(exprPos,
11737 JSMSG_BAD_DESTRUCT_TARGET);
11738 }
11739
11740 return true;
11741}
11742
11743template <class ParseHandler, typename Unit>
11744void GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentName(
11745 NameNodeType name, TokenPos namePos, PossibleError* possibleError) {
11746#ifdef DEBUG1
11747 // GCC 8.0.1 crashes if this is a one-liner.
11748 bool isName = handler_.isName(name);
11749 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"
, 11749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isName" ")"
); do { *((volatile int*)__null) = 11749; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
11750#endif
11751
11752 // Return early if a pending destructuring error is already present.
11753 if (possibleError->hasPendingDestructuringError()) {
11754 return;
11755 }
11756
11757 if (handler_.isArgumentsLength(name)) {
11758 pc_->sc()->setIneligibleForArgumentsLength();
11759 }
11760
11761 if (pc_->sc()->strict()) {
11762 if (handler_.isArgumentsName(name)) {
11763 if (pc_->sc()->strict()) {
11764 possibleError->setPendingDestructuringErrorAt(
11765 namePos, JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
11766 } else {
11767 possibleError->setPendingDestructuringWarningAt(
11768 namePos, JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
11769 }
11770 return;
11771 }
11772
11773 if (handler_.isEvalName(name)) {
11774 if (pc_->sc()->strict()) {
11775 possibleError->setPendingDestructuringErrorAt(
11776 namePos, JSMSG_BAD_STRICT_ASSIGN_EVAL);
11777 } else {
11778 possibleError->setPendingDestructuringWarningAt(
11779 namePos, JSMSG_BAD_STRICT_ASSIGN_EVAL);
11780 }
11781 return;
11782 }
11783 }
11784}
11785
11786template <class ParseHandler, typename Unit>
11787bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentElement(
11788 Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
11789 PossibleError* possibleError) {
11790 // ES2018 draft rev 0719f44aab93215ed9a626b2f45bd34f36916834
11791 // 12.15.5 Destructuring Assignment
11792 //
11793 // AssignmentElement[Yield, Await]:
11794 // DestructuringAssignmentTarget[?Yield, ?Await]
11795 // DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In,
11796 // ?Yield,
11797 // ?Await]
11798
11799 // If |expr| is an assignment element with an initializer expression, its
11800 // destructuring assignment target was already validated in assignExpr().
11801 // Otherwise we need to check that |expr| is a valid destructuring target.
11802 if (handler_.isUnparenthesizedAssignment(expr)) {
11803 // Report any pending expression error if we're definitely not in a
11804 // destructuring context.
11805 if (!possibleError) {
11806 return exprPossibleError->checkForExpressionError();
11807 }
11808
11809 exprPossibleError->transferErrorsTo(possibleError);
11810 return true;
11811 }
11812 return checkDestructuringAssignmentTarget(expr, exprPos, exprPossibleError,
11813 possibleError);
11814}
11815
11816template <class ParseHandler, typename Unit>
11817typename ParseHandler::ListNodeResult
11818GeneralParser<ParseHandler, Unit>::arrayInitializer(
11819 YieldHandling yieldHandling, PossibleError* possibleError) {
11820 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"
, 11820); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 11820; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11821
11822 uint32_t begin = pos().begin;
11823 ListNodeType literal;
11824 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)
;
11825
11826 TokenKind tt;
11827 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
11828 return errorResult();
11829 }
11830
11831 if (tt == TokenKind::RightBracket) {
11832 /*
11833 * Mark empty arrays as non-constant, since we cannot easily
11834 * determine their type.
11835 */
11836 handler_.setListHasNonConstInitializer(literal);
11837 } else {
11838 anyChars.ungetToken();
11839
11840 for (uint32_t index = 0;; index++) {
11841 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
11842 error(JSMSG_ARRAY_INIT_TOO_BIG);
11843 return errorResult();
11844 }
11845
11846 TokenKind tt;
11847 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
11848 return errorResult();
11849 }
11850 if (tt == TokenKind::RightBracket) {
11851 break;
11852 }
11853
11854 if (tt == TokenKind::Comma) {
11855 tokenStream.consumeKnownToken(TokenKind::Comma,
11856 TokenStream::SlashIsRegExp);
11857 if (!handler_.addElision(literal, pos())) {
11858 return errorResult();
11859 }
11860 continue;
11861 }
11862
11863 if (tt == TokenKind::TripleDot) {
11864 tokenStream.consumeKnownToken(TokenKind::TripleDot,
11865 TokenStream::SlashIsRegExp);
11866 uint32_t begin = pos().begin;
11867
11868 TokenPos innerPos;
11869 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
11870 return errorResult();
11871 }
11872
11873 PossibleError possibleErrorInner(*this);
11874 Node inner;
11875 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)
11876 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)
11877 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
;
11878 if (!checkDestructuringAssignmentTarget(
11879 inner, innerPos, &possibleErrorInner, possibleError)) {
11880 return errorResult();
11881 }
11882
11883 if (!handler_.addSpreadElement(literal, begin, inner)) {
11884 return errorResult();
11885 }
11886 } else {
11887 TokenPos elementPos;
11888 if (!tokenStream.peekTokenPos(&elementPos,
11889 TokenStream::SlashIsRegExp)) {
11890 return errorResult();
11891 }
11892
11893 PossibleError possibleErrorInner(*this);
11894 Node element;
11895 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)
11896 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)
11897 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (element) = mozTryVarTempResult_.unwrap();
} while (0)
;
11898 if (!checkDestructuringAssignmentElement(
11899 element, elementPos, &possibleErrorInner, possibleError)) {
11900 return errorResult();
11901 }
11902 handler_.addArrayElement(literal, element);
11903 }
11904
11905 bool matched;
11906 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
11907 TokenStream::SlashIsRegExp)) {
11908 return errorResult();
11909 }
11910 if (!matched) {
11911 break;
11912 }
11913
11914 if (tt == TokenKind::TripleDot && possibleError) {
11915 possibleError->setPendingDestructuringErrorAt(pos(),
11916 JSMSG_REST_WITH_COMMA);
11917 }
11918 }
11919
11920 if (!mustMatchToken(
11921 TokenKind::RightBracket, [this, begin](TokenKind actual) {
11922 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
11923 JSMSG_BRACKET_OPENED, begin);
11924 })) {
11925 return errorResult();
11926 }
11927 }
11928
11929 handler_.setEndPosition(literal, pos().end);
11930 return literal;
11931}
11932
11933template <class ParseHandler, typename Unit>
11934typename ParseHandler::NodeResult
11935GeneralParser<ParseHandler, Unit>::propertyName(
11936 YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
11937 const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
11938 TaggedParserAtomIndex* propAtomOut) {
11939 // PropertyName[Yield, Await]:
11940 // LiteralPropertyName
11941 // ComputedPropertyName[?Yield, ?Await]
11942 //
11943 // LiteralPropertyName:
11944 // IdentifierName
11945 // StringLiteral
11946 // NumericLiteral
11947 TokenKind ltok = anyChars.currentToken().type;
11948
11949 *propAtomOut = TaggedParserAtomIndex::null();
11950 switch (ltok) {
11951 case TokenKind::Number: {
11952 auto numAtom = NumberToParserAtom(fc_, this->parserAtoms(),
11953 anyChars.currentToken().number());
11954 if (!numAtom) {
11955 return errorResult();
11956 }
11957 *propAtomOut = numAtom;
11958 return newNumber(anyChars.currentToken());
11959 }
11960
11961 case TokenKind::BigInt: {
11962 Node biNode;
11963 MOZ_TRY_VAR(biNode, newBigInt())do { auto mozTryVarTempResult_ = (newBigInt()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (biNode) = mozTryVarTempResult_.unwrap(); }
while (0)
;
11964 return handler_.newSyntheticComputedName(biNode, pos().begin, pos().end);
11965 }
11966 case TokenKind::String: {
11967 auto str = anyChars.currentToken().atom();
11968 *propAtomOut = str;
11969 uint32_t index;
11970 if (this->parserAtoms().isIndex(str, &index)) {
11971 return handler_.newNumber(index, NoDecimal, pos());
11972 }
11973 return stringLiteral();
11974 }
11975
11976 case TokenKind::LeftBracket:
11977 return computedPropertyName(yieldHandling, maybeDecl, propertyNameContext,
11978 propList);
11979
11980 case TokenKind::PrivateName: {
11981 if (propertyNameContext != PropertyNameContext::PropertyNameInClass) {
11982 error(JSMSG_ILLEGAL_PRIVATE_FIELD);
11983 return errorResult();
11984 }
11985
11986 TaggedParserAtomIndex propName = anyChars.currentName();
11987 *propAtomOut = propName;
11988 return privateNameReference(propName);
11989 }
11990
11991 default: {
11992 if (!TokenKindIsPossibleIdentifierName(ltok)) {
11993 error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(ltok));
11994 return errorResult();
11995 }
11996
11997 TaggedParserAtomIndex name = anyChars.currentName();
11998 *propAtomOut = name;
11999 return handler_.newObjectLiteralPropertyName(name, pos());
12000 }
12001 }
12002}
12003
12004// True if `kind` can be the first token of a PropertyName.
12005static bool TokenKindCanStartPropertyName(TokenKind tt) {
12006 return TokenKindIsPossibleIdentifierName(tt) || tt == TokenKind::String ||
12007 tt == TokenKind::Number || tt == TokenKind::LeftBracket ||
12008 tt == TokenKind::BigInt || tt == TokenKind::PrivateName;
12009}
12010
12011template <class ParseHandler, typename Unit>
12012typename ParseHandler::NodeResult
12013GeneralParser<ParseHandler, Unit>::propertyOrMethodName(
12014 YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
12015 const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
12016 PropertyType* propType, TaggedParserAtomIndex* propAtomOut) {
12017 // We're parsing an object literal, class, or destructuring pattern;
12018 // propertyNameContext tells which one. This method parses any of the
12019 // following, storing the corresponding PropertyType in `*propType` to tell
12020 // the caller what we parsed:
12021 //
12022 // async [no LineTerminator here] PropertyName
12023 // ==> PropertyType::AsyncMethod
12024 // async [no LineTerminator here] * PropertyName
12025 // ==> PropertyType::AsyncGeneratorMethod
12026 // * PropertyName ==> PropertyType::GeneratorMethod
12027 // get PropertyName ==> PropertyType::Getter
12028 // set PropertyName ==> PropertyType::Setter
12029 // accessor PropertyName ==> PropertyType::FieldWithAccessor
12030 // PropertyName : ==> PropertyType::Normal
12031 // PropertyName ==> see below
12032 //
12033 // In the last case, where there's not a `:` token to consume, we peek at
12034 // (but don't consume) the next token to decide how to set `*propType`.
12035 //
12036 // `,` or `}` ==> PropertyType::Shorthand
12037 // `(` ==> PropertyType::Method
12038 // `=`, not in a class ==> PropertyType::CoverInitializedName
12039 // '=', in a class ==> PropertyType::Field
12040 // any token, in a class ==> PropertyType::Field (ASI)
12041 //
12042 // The caller must check `*propType` and throw if whatever we parsed isn't
12043 // allowed here (for example, a getter in a destructuring pattern).
12044 //
12045 // This method does *not* match `static` (allowed in classes) or `...`
12046 // (allowed in object literals and patterns). The caller must take care of
12047 // those before calling this method.
12048
12049 TokenKind ltok;
12050 if (!tokenStream.getToken(&ltok, TokenStream::SlashIsInvalid)) {
12051 return errorResult();
12052 }
12053
12054 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"
, 12055); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ltok != TokenKind::RightCurly"
") (" "caller should have handled TokenKind::RightCurly" ")"
); do { *((volatile int*)__null) = 12055; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
12055 "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"
, 12055); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ltok != TokenKind::RightCurly"
") (" "caller should have handled TokenKind::RightCurly" ")"
); do { *((volatile int*)__null) = 12055; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
12056
12057 // Accept `async` and/or `*`, indicating an async or generator method;
12058 // or `get` or `set` or `accessor`, indicating an accessor.
12059 bool isGenerator = false;
12060 bool isAsync = false;
12061 bool isGetter = false;
12062 bool isSetter = false;
12063#ifdef ENABLE_DECORATORS
12064 bool hasAccessor = false;
12065#endif
12066
12067 if (ltok == TokenKind::Async) {
12068 // `async` is also a PropertyName by itself (it's a conditional keyword),
12069 // so peek at the next token to see if we're really looking at a method.
12070 TokenKind tt = TokenKind::Eof;
12071 if (!tokenStream.peekTokenSameLine(&tt)) {
12072 return errorResult();
12073 }
12074 if (TokenKindCanStartPropertyName(tt) || tt == TokenKind::Mul) {
12075 isAsync = true;
12076 tokenStream.consumeKnownToken(tt);
12077 ltok = tt;
12078 }
12079 }
12080
12081 if (ltok == TokenKind::Mul) {
12082 isGenerator = true;
12083 if (!tokenStream.getToken(&ltok)) {
12084 return errorResult();
12085 }
12086 }
12087
12088 if (!isAsync && !isGenerator &&
12089 (ltok == TokenKind::Get || ltok == TokenKind::Set)) {
12090 // We have parsed |get| or |set|. Look for an accessor property
12091 // name next.
12092 TokenKind tt;
12093 if (!tokenStream.peekToken(&tt)) {
12094 return errorResult();
12095 }
12096 if (TokenKindCanStartPropertyName(tt)) {
12097 tokenStream.consumeKnownToken(tt);
12098 isGetter = (ltok == TokenKind::Get);
12099 isSetter = (ltok == TokenKind::Set);
12100 }
12101 }
12102
12103#ifdef ENABLE_DECORATORS
12104 if (!isGenerator && !isAsync && propertyNameContext == PropertyNameInClass &&
12105 ltok == TokenKind::Accessor) {
12106 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"
, 12106); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!isGetter && !isSetter"
")"); do { *((volatile int*)__null) = 12106; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12107 TokenKind tt;
12108 if (!tokenStream.peekTokenSameLine(&tt)) {
12109 return errorResult();
12110 }
12111
12112 // The target rule is `accessor [no LineTerminator here]
12113 // ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt`
12114 if (TokenKindCanStartPropertyName(tt)) {
12115 tokenStream.consumeKnownToken(tt);
12116 hasAccessor = true;
12117 }
12118 }
12119#endif
12120
12121 Node propName;
12122 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)
12123 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)
;
12124
12125 // Grab the next token following the property/method name.
12126 // (If this isn't a colon, we're going to either put it back or throw.)
12127 TokenKind tt;
12128 if (!tokenStream.getToken(&tt)) {
12129 return errorResult();
12130 }
12131
12132 if (tt == TokenKind::Colon) {
12133 if (isGenerator || isAsync || isGetter || isSetter
12134#ifdef ENABLE_DECORATORS
12135 || hasAccessor
12136#endif
12137 ) {
12138 error(JSMSG_BAD_PROP_ID);
12139 return errorResult();
12140 }
12141 *propType = PropertyType::Normal;
12142 return propName;
12143 }
12144
12145 if (propertyNameContext != PropertyNameInClass &&
12146 TokenKindIsPossibleIdentifierName(ltok) &&
12147 (tt == TokenKind::Comma || tt == TokenKind::RightCurly ||
12148 tt == TokenKind::Assign)) {
12149#ifdef ENABLE_DECORATORS
12150 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"
, 12150); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!hasAccessor"
")"); do { *((volatile int*)__null) = 12150; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12151#endif
12152 if (isGenerator || isAsync || isGetter || isSetter) {
12153 error(JSMSG_BAD_PROP_ID);
12154 return errorResult();
12155 }
12156
12157 anyChars.ungetToken();
12158 *propType = tt == TokenKind::Assign ? PropertyType::CoverInitializedName
12159 : PropertyType::Shorthand;
12160 return propName;
12161 }
12162
12163 if (tt == TokenKind::LeftParen) {
12164 anyChars.ungetToken();
12165
12166#ifdef ENABLE_RECORD_TUPLE
12167 if (propertyNameContext == PropertyNameInRecord) {
12168 // Record & Tuple proposal, section 7.1.1:
12169 // RecordPropertyDefinition doesn't cover methods
12170 error(JSMSG_BAD_PROP_ID);
12171 return errorResult();
12172 }
12173#endif
12174
12175#ifdef ENABLE_DECORATORS
12176 if (hasAccessor) {
12177 error(JSMSG_BAD_PROP_ID);
12178 return errorResult();
12179 }
12180#endif
12181
12182 if (isGenerator && isAsync) {
12183 *propType = PropertyType::AsyncGeneratorMethod;
12184 } else if (isGenerator) {
12185 *propType = PropertyType::GeneratorMethod;
12186 } else if (isAsync) {
12187 *propType = PropertyType::AsyncMethod;
12188 } else if (isGetter) {
12189 *propType = PropertyType::Getter;
12190 } else if (isSetter) {
12191 *propType = PropertyType::Setter;
12192 } else {
12193 *propType = PropertyType::Method;
12194 }
12195 return propName;
12196 }
12197
12198 if (propertyNameContext == PropertyNameInClass) {
12199 if (isGenerator || isAsync || isGetter || isSetter) {
12200 error(JSMSG_BAD_PROP_ID);
12201 return errorResult();
12202 }
12203 anyChars.ungetToken();
12204#ifdef ENABLE_DECORATORS
12205 if (!hasAccessor) {
12206 *propType = PropertyType::Field;
12207 } else {
12208 *propType = PropertyType::FieldWithAccessor;
12209 }
12210#else
12211 *propType = PropertyType::Field;
12212#endif
12213 return propName;
12214 }
12215
12216 error(JSMSG_COLON_AFTER_ID);
12217 return errorResult();
12218}
12219
12220template <class ParseHandler, typename Unit>
12221typename ParseHandler::UnaryNodeResult
12222GeneralParser<ParseHandler, Unit>::computedPropertyName(
12223 YieldHandling yieldHandling, const Maybe<DeclarationKind>& maybeDecl,
12224 PropertyNameContext propertyNameContext, ListNodeType literal) {
12225 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"
, 12225); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 12225; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12226
12227 uint32_t begin = pos().begin;
12228
12229 if (maybeDecl) {
12230 if (*maybeDecl == DeclarationKind::FormalParameter) {
12231 pc_->functionBox()->hasParameterExprs = true;
12232 }
12233 } else if (propertyNameContext ==
12234 PropertyNameContext::PropertyNameInLiteral) {
12235 handler_.setListHasNonConstInitializer(literal);
12236 }
12237
12238 Node assignNode;
12239 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)
12240 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)
;
12241
12242 if (!mustMatchToken(TokenKind::RightBracket, JSMSG_COMP_PROP_UNTERM_EXPR)) {
12243 return errorResult();
12244 }
12245 return handler_.newComputedName(assignNode, begin, pos().end);
12246}
12247
12248template <class ParseHandler, typename Unit>
12249typename ParseHandler::ListNodeResult
12250GeneralParser<ParseHandler, Unit>::objectLiteral(YieldHandling yieldHandling,
12251 PossibleError* possibleError) {
12252 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"
, 12252); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 12252; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12253
12254 uint32_t openedPos = pos().begin;
12255
12256 ListNodeType literal;
12257 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)
;
12258
12259 bool seenPrototypeMutation = false;
12260 bool seenCoverInitializedName = false;
12261 Maybe<DeclarationKind> declKind = Nothing();
12262 TaggedParserAtomIndex propAtom;
12263 for (;;) {
12264 TokenKind tt;
12265 if (!tokenStream.peekToken(&tt)) {
12266 return errorResult();
12267 }
12268 if (tt == TokenKind::RightCurly) {
12269 break;
12270 }
12271
12272 if (tt == TokenKind::TripleDot) {
12273 tokenStream.consumeKnownToken(TokenKind::TripleDot);
12274 uint32_t begin = pos().begin;
12275
12276 TokenPos innerPos;
12277 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12278 return errorResult();
12279 }
12280
12281 PossibleError possibleErrorInner(*this);
12282 Node inner;
12283 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)
12284 TripledotProhibited, &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
;
12285 if (!checkDestructuringAssignmentTarget(
12286 inner, innerPos, &possibleErrorInner, possibleError,
12287 TargetBehavior::ForbidAssignmentPattern)) {
12288 return errorResult();
12289 }
12290 if (!handler_.addSpreadProperty(literal, begin, inner)) {
12291 return errorResult();
12292 }
12293 } else {
12294 TokenPos namePos = anyChars.nextToken().pos;
12295
12296 PropertyType propType;
12297 Node propName;
12298 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)
12299 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)
12300 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)
;
12301
12302 if (propType == PropertyType::Normal) {
12303 TokenPos exprPos;
12304 if (!tokenStream.peekTokenPos(&exprPos, TokenStream::SlashIsRegExp)) {
12305 return errorResult();
12306 }
12307
12308 PossibleError possibleErrorInner(*this);
12309 Node propExpr;
12310 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)
12311 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)
12312 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
;
12313
12314 if (!checkDestructuringAssignmentElement(
12315 propExpr, exprPos, &possibleErrorInner, possibleError)) {
12316 return errorResult();
12317 }
12318
12319 if (propAtom == TaggedParserAtomIndex::WellKnown::proto_()) {
12320 if (seenPrototypeMutation) {
12321 // Directly report the error when we're definitely not
12322 // in a destructuring context.
12323 if (!possibleError) {
12324 errorAt(namePos.begin, JSMSG_DUPLICATE_PROTO_PROPERTY);
12325 return errorResult();
12326 }
12327
12328 // Otherwise delay error reporting until we've
12329 // determined whether or not we're destructuring.
12330 possibleError->setPendingExpressionErrorAt(
12331 namePos, JSMSG_DUPLICATE_PROTO_PROPERTY);
12332 }
12333 seenPrototypeMutation = true;
12334
12335 // This occurs *only* if we observe PropertyType::Normal!
12336 // Only |__proto__: v| mutates [[Prototype]]. Getters,
12337 // setters, method/generator definitions, computed
12338 // property name versions of all of these, and shorthands
12339 // do not.
12340 if (!handler_.addPrototypeMutation(literal, namePos.begin,
12341 propExpr)) {
12342 return errorResult();
12343 }
12344 } else {
12345 BinaryNodeType propDef;
12346 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)
12347 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)
;
12348
12349 handler_.addPropertyDefinition(literal, propDef);
12350 }
12351 } else if (propType == PropertyType::Shorthand) {
12352 /*
12353 * Support, e.g., |({x, y} = o)| as destructuring shorthand
12354 * for |({x: x, y: y} = o)|, and |var o = {x, y}| as
12355 * initializer shorthand for |var o = {x: x, y: y}|.
12356 */
12357 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12358 if (!name) {
12359 return errorResult();
12360 }
12361
12362 NameNodeType nameExpr;
12363 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)
;
12364
12365 if (possibleError) {
12366 checkDestructuringAssignmentName(nameExpr, namePos, possibleError);
12367 }
12368
12369 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
12370 nameExpr)) {
12371 return errorResult();
12372 }
12373 } else if (propType == PropertyType::CoverInitializedName) {
12374 /*
12375 * Support, e.g., |({x=1, y=2} = o)| as destructuring
12376 * shorthand with default values, as per ES6 12.14.5
12377 */
12378 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12379 if (!name) {
12380 return errorResult();
12381 }
12382
12383 Node lhs;
12384 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)
;
12385
12386 tokenStream.consumeKnownToken(TokenKind::Assign);
12387
12388 if (!seenCoverInitializedName) {
12389 // "shorthand default" or "CoverInitializedName" syntax is
12390 // only valid in the case of destructuring.
12391 seenCoverInitializedName = true;
12392
12393 if (!possibleError) {
12394 // Destructuring defaults are definitely not allowed
12395 // in this object literal, because of something the
12396 // caller knows about the preceding code. For example,
12397 // maybe the preceding token is an operator:
12398 // |x + {y=z}|.
12399 error(JSMSG_COLON_AFTER_ID);
12400 return errorResult();
12401 }
12402
12403 // Here we set a pending error so that later in the parse,
12404 // once we've determined whether or not we're
12405 // destructuring, the error can be reported or ignored
12406 // appropriately.
12407 possibleError->setPendingExpressionErrorAt(pos(),
12408 JSMSG_COLON_AFTER_ID);
12409 }
12410
12411 if (const char* chars = nameIsArgumentsOrEval(lhs)) {
12412 // |chars| is "arguments" or "eval" here.
12413 if (!strictModeErrorAt(namePos.begin, JSMSG_BAD_STRICT_ASSIGN,
12414 chars)) {
12415 return errorResult();
12416 }
12417 }
12418
12419 if (handler_.isArgumentsLength(lhs)) {
12420 pc_->sc()->setIneligibleForArgumentsLength();
12421 }
12422
12423 Node rhs;
12424 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)
12425 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)
;
12426
12427 BinaryNodeType propExpr;
12428 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)
12429 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)
;
12430
12431 if (!handler_.addPropertyDefinition(literal, propName, propExpr)) {
12432 return errorResult();
12433 }
12434 } else {
12435 TaggedParserAtomIndex funName;
12436 bool hasStaticName =
12437 !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom;
12438 if (hasStaticName) {
12439 funName = propAtom;
12440
12441 if (propType == PropertyType::Getter ||
12442 propType == PropertyType::Setter) {
12443 funName = prefixAccessorName(propType, propAtom);
12444 if (!funName) {
12445 return errorResult();
12446 }
12447 }
12448 }
12449
12450 FunctionNodeType funNode;
12451 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)
12452 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)
;
12453
12454 AccessorType atype = ToAccessorType(propType);
12455 if (!handler_.addObjectMethodDefinition(literal, propName, funNode,
12456 atype)) {
12457 return errorResult();
12458 }
12459
12460 if (possibleError) {
12461 possibleError->setPendingDestructuringErrorAt(
12462 namePos, JSMSG_BAD_DESTRUCT_TARGET);
12463 }
12464 }
12465 }
12466
12467 bool matched;
12468 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12469 TokenStream::SlashIsInvalid)) {
12470 return errorResult();
12471 }
12472 if (!matched) {
12473 break;
12474 }
12475 if (tt == TokenKind::TripleDot && possibleError) {
12476 possibleError->setPendingDestructuringErrorAt(pos(),
12477 JSMSG_REST_WITH_COMMA);
12478 }
12479 }
12480
12481 if (!mustMatchToken(
12482 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
12483 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
12484 JSMSG_CURLY_OPENED, openedPos);
12485 })) {
12486 return errorResult();
12487 }
12488
12489 handler_.setEndPosition(literal, pos().end);
12490 return literal;
12491}
12492
12493#ifdef ENABLE_RECORD_TUPLE
12494template <class ParseHandler, typename Unit>
12495typename ParseHandler::ListNodeResult
12496GeneralParser<ParseHandler, Unit>::recordLiteral(YieldHandling yieldHandling) {
12497 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"
, 12497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::HashCurly)"
")"); do { *((volatile int*)__null) = 12497; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12498
12499 uint32_t openedPos = pos().begin;
12500
12501 ListNodeType literal;
12502 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)
;
12503
12504 TaggedParserAtomIndex propAtom;
12505 for (;;) {
12506 TokenKind tt;
12507 if (!tokenStream.peekToken(&tt)) {
12508 return errorResult();
12509 }
12510 if (tt == TokenKind::RightCurly) {
12511 break;
12512 }
12513
12514 if (tt == TokenKind::TripleDot) {
12515 tokenStream.consumeKnownToken(TokenKind::TripleDot);
12516 uint32_t begin = pos().begin;
12517
12518 TokenPos innerPos;
12519 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12520 return errorResult();
12521 }
12522
12523 Node inner;
12524 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)
12525 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)
;
12526
12527 if (!handler_.addSpreadProperty(literal, begin, inner)) {
12528 return errorResult();
12529 }
12530 } else {
12531 TokenPos namePos = anyChars.nextToken().pos;
12532
12533 PropertyType propType;
12534 Node propName;
12535 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)
12536 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)
12537 /* 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)
12538 &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)
;
12539
12540 if (propType == PropertyType::Normal) {
12541 TokenPos exprPos;
12542 if (!tokenStream.peekTokenPos(&exprPos, TokenStream::SlashIsRegExp)) {
12543 return errorResult();
12544 }
12545
12546 Node propExpr;
12547 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)
12548 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)
;
12549
12550 if (propAtom == TaggedParserAtomIndex::WellKnown::proto_()) {
12551 errorAt(namePos.begin, JSMSG_RECORD_NO_PROTO);
12552 return errorResult();
12553 }
12554
12555 BinaryNodeType propDef;
12556 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)
12557 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)
;
12558
12559 handler_.addPropertyDefinition(literal, propDef);
12560 } else if (propType == PropertyType::Shorthand) {
12561 /*
12562 * Support |var o = #{x, y}| as initializer shorthand for
12563 * |var o = #{x: x, y: y}|.
12564 */
12565 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12566 if (!name) {
12567 return errorResult();
12568 }
12569
12570 NameNodeType nameExpr;
12571 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)
;
12572
12573 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
12574 nameExpr)) {
12575 return errorResult();
12576 }
12577 } else {
12578 error(JSMSG_BAD_PROP_ID);
12579 return errorResult();
12580 }
12581 }
12582
12583 bool matched;
12584 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12585 TokenStream::SlashIsInvalid)) {
12586 return errorResult();
12587 }
12588 if (!matched) {
12589 break;
12590 }
12591 }
12592
12593 if (!mustMatchToken(
12594 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
12595 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
12596 JSMSG_CURLY_OPENED, openedPos);
12597 })) {
12598 return errorResult();
12599 }
12600
12601 handler_.setEndPosition(literal, pos().end);
12602 return literal;
12603}
12604
12605template <class ParseHandler, typename Unit>
12606typename ParseHandler::ListNodeResult
12607GeneralParser<ParseHandler, Unit>::tupleLiteral(YieldHandling yieldHandling) {
12608 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"
, 12608); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::HashBracket)"
")"); do { *((volatile int*)__null) = 12608; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12609
12610 uint32_t begin = pos().begin;
12611 ListNodeType literal;
12612 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)
;
12613
12614 for (uint32_t index = 0;; index++) {
12615 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
12616 error(JSMSG_ARRAY_INIT_TOO_BIG);
12617 return errorResult();
12618 }
12619
12620 TokenKind tt;
12621 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
12622 return errorResult();
12623 }
12624 if (tt == TokenKind::RightBracket) {
12625 break;
12626 }
12627
12628 if (tt == TokenKind::TripleDot) {
12629 tokenStream.consumeKnownToken(TokenKind::TripleDot,
12630 TokenStream::SlashIsRegExp);
12631 uint32_t begin = pos().begin;
12632
12633 TokenPos innerPos;
12634 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12635 return errorResult();
12636 }
12637
12638 Node inner;
12639 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)
12640 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)
;
12641
12642 if (!handler_.addSpreadElement(literal, begin, inner)) {
12643 return errorResult();
12644 }
12645 } else {
12646 TokenPos elementPos;
12647 if (!tokenStream.peekTokenPos(&elementPos, TokenStream::SlashIsRegExp)) {
12648 return errorResult();
12649 }
12650
12651 Node element;
12652 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)
12653 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)
;
12654 handler_.addArrayElement(literal, element);
12655 }
12656
12657 bool matched;
12658 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12659 TokenStream::SlashIsRegExp)) {
12660 return errorResult();
12661 }
12662 if (!matched) {
12663 break;
12664 }
12665 }
12666
12667 if (!mustMatchToken(TokenKind::RightBracket, [this, begin](TokenKind actual) {
12668 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
12669 JSMSG_BRACKET_OPENED, begin);
12670 })) {
12671 return errorResult();
12672 }
12673
12674 handler_.setEndPosition(literal, pos().end);
12675 return literal;
12676}
12677#endif
12678
12679template <class ParseHandler, typename Unit>
12680typename ParseHandler::FunctionNodeResult
12681GeneralParser<ParseHandler, Unit>::methodDefinition(
12682 uint32_t toStringStart, PropertyType propType,
12683 TaggedParserAtomIndex funName) {
12684 FunctionSyntaxKind syntaxKind;
12685 switch (propType) {
12686 case PropertyType::Getter:
12687 syntaxKind = FunctionSyntaxKind::Getter;
12688 break;
12689
12690 case PropertyType::Setter:
12691 syntaxKind = FunctionSyntaxKind::Setter;
12692 break;
12693
12694 case PropertyType::Method:
12695 case PropertyType::GeneratorMethod:
12696 case PropertyType::AsyncMethod:
12697 case PropertyType::AsyncGeneratorMethod:
12698 syntaxKind = FunctionSyntaxKind::Method;
12699 break;
12700
12701 case PropertyType::Constructor:
12702 syntaxKind = FunctionSyntaxKind::ClassConstructor;
12703 break;
12704
12705 case PropertyType::DerivedConstructor:
12706 syntaxKind = FunctionSyntaxKind::DerivedClassConstructor;
12707 break;
12708
12709 default:
12710 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"
, 12710); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected property type"
")"); do { *((volatile int*)__null) = 12710; __attribute__((
nomerge)) ::abort(); } while (false); } while (false)
;
12711 }
12712
12713 GeneratorKind generatorKind = (propType == PropertyType::GeneratorMethod ||
12714 propType == PropertyType::AsyncGeneratorMethod)
12715 ? GeneratorKind::Generator
12716 : GeneratorKind::NotGenerator;
12717
12718 FunctionAsyncKind asyncKind = (propType == PropertyType::AsyncMethod ||
12719 propType == PropertyType::AsyncGeneratorMethod)
12720 ? FunctionAsyncKind::AsyncFunction
12721 : FunctionAsyncKind::SyncFunction;
12722
12723 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
12724
12725 FunctionNodeType funNode;
12726 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)
;
12727
12728 return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
12729 funName, syntaxKind, generatorKind, asyncKind);
12730}
12731
12732template <class ParseHandler, typename Unit>
12733bool GeneralParser<ParseHandler, Unit>::tryNewTarget(
12734 NewTargetNodeType* newTarget) {
12735 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"
, 12735); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::New)"
")"); do { *((volatile int*)__null) = 12735; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12736
12737 *newTarget = null();
12738
12739 NullaryNodeType newHolder;
12740 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)
;
12741
12742 uint32_t begin = pos().begin;
12743
12744 // |new| expects to look for an operand, so we will honor that.
12745 TokenKind next;
12746 if (!tokenStream.getToken(&next, TokenStream::SlashIsRegExp)) {
12747 return false;
12748 }
12749
12750 // Don't unget the token, since lookahead cannot handle someone calling
12751 // getToken() with a different modifier. Callers should inspect
12752 // currentToken().
12753 if (next != TokenKind::Dot) {
12754 return true;
12755 }
12756
12757 if (!tokenStream.getToken(&next)) {
12758 return false;
12759 }
12760 if (next != TokenKind::Target) {
12761 error(JSMSG_UNEXPECTED_TOKEN, "target", TokenKindToDesc(next));
12762 return false;
12763 }
12764
12765 if (!pc_->sc()->allowNewTarget()) {
12766 errorAt(begin, JSMSG_BAD_NEWTARGET);
12767 return false;
12768 }
12769
12770 NullaryNodeType targetHolder;
12771 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)
;
12772
12773 NameNodeType newTargetName;
12774 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)
;
12775
12776 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)
12777 *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)
12778 false)do { auto parserTryVarTempResult_ = (handler_.newNewTarget(newHolder
, targetHolder, newTargetName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*newTarget) = parserTryVarTempResult_
.unwrap(); } while (0)
;
12779
12780 return true;
12781}
12782
12783template <class ParseHandler, typename Unit>
12784typename ParseHandler::BinaryNodeResult
12785GeneralParser<ParseHandler, Unit>::importExpr(YieldHandling yieldHandling,
12786 bool allowCallSyntax) {
12787 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"
, 12787); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 12787; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12788
12789 NullaryNodeType importHolder;
12790 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)
;
12791
12792 TokenKind next;
12793 if (!tokenStream.getToken(&next)) {
12794 return errorResult();
12795 }
12796
12797 if (next == TokenKind::Dot) {
12798 if (!tokenStream.getToken(&next)) {
12799 return errorResult();
12800 }
12801 if (next != TokenKind::Meta) {
12802 error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
12803 return errorResult();
12804 }
12805
12806 if (parseGoal() != ParseGoal::Module) {
12807 errorAt(pos().begin, JSMSG_IMPORT_META_OUTSIDE_MODULE);
12808 return errorResult();
12809 }
12810
12811 NullaryNodeType metaHolder;
12812 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)
;
12813
12814 return handler_.newImportMeta(importHolder, metaHolder);
12815 }
12816
12817 if (next == TokenKind::LeftParen && allowCallSyntax) {
12818 Node arg;
12819 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)
;
12820
12821 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12822 return errorResult();
12823 }
12824
12825 Node optionalArg;
12826 if (options().importAttributes()) {
12827 if (next == TokenKind::Comma) {
12828 tokenStream.consumeKnownToken(TokenKind::Comma,
12829 TokenStream::SlashIsRegExp);
12830
12831 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12832 return errorResult();
12833 }
12834
12835 if (next != TokenKind::RightParen) {
12836 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)
12837 TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12838
12839 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12840 return errorResult();
12841 }
12842
12843 if (next == TokenKind::Comma) {
12844 tokenStream.consumeKnownToken(TokenKind::Comma,
12845 TokenStream::SlashIsRegExp);
12846 }
12847 } else {
12848 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)
12849 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)
;
12850 }
12851 } else {
12852 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)
12853 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)
;
12854 }
12855 } else {
12856 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)
12857 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)
;
12858 }
12859
12860 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_ARGS)) {
12861 return errorResult();
12862 }
12863
12864 Node spec;
12865 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)
;
12866
12867 return handler_.newCallImport(importHolder, spec);
12868 }
12869
12870 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
12871 return errorResult();
12872}
12873
12874template <class ParseHandler, typename Unit>
12875typename ParseHandler::NodeResult
12876GeneralParser<ParseHandler, Unit>::primaryExpr(
12877 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
12878 TokenKind tt, PossibleError* possibleError, InvokedPrediction invoked) {
12879 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"
, 12879); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 12879; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12880 AutoCheckRecursionLimit recursion(this->fc_);
12881 if (!recursion.check(this->fc_)) {
12882 return errorResult();
12883 }
12884
12885 switch (tt) {
12886 case TokenKind::Function:
12887 return functionExpr(pos().begin, invoked,
12888 FunctionAsyncKind::SyncFunction);
12889
12890 case TokenKind::Class:
12891 return classDefinition(yieldHandling, ClassExpression, NameRequired);
12892
12893 case TokenKind::LeftBracket:
12894 return arrayInitializer(yieldHandling, possibleError);
12895
12896 case TokenKind::LeftCurly:
12897 return objectLiteral(yieldHandling, possibleError);
12898
12899#ifdef ENABLE_RECORD_TUPLE
12900 case TokenKind::HashCurly:
12901 return recordLiteral(yieldHandling);
12902
12903 case TokenKind::HashBracket:
12904 return tupleLiteral(yieldHandling);
12905#endif
12906
12907#ifdef ENABLE_DECORATORS
12908 case TokenKind::At:
12909 return classDefinition(yieldHandling, ClassExpression, NameRequired);
12910#endif
12911
12912 case TokenKind::LeftParen: {
12913 TokenKind next;
12914 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12915 return errorResult();
12916 }
12917
12918 if (next == TokenKind::RightParen) {
12919 // Not valid expression syntax, but this is valid in an arrow function
12920 // with no params: `() => body`.
12921 tokenStream.consumeKnownToken(TokenKind::RightParen,
12922 TokenStream::SlashIsRegExp);
12923
12924 if (!tokenStream.peekToken(&next)) {
12925 return errorResult();
12926 }
12927 if (next != TokenKind::Arrow) {
12928 error(JSMSG_UNEXPECTED_TOKEN, "expression",
12929 TokenKindToDesc(TokenKind::RightParen));
12930 return errorResult();
12931 }
12932
12933 // Now just return something that will allow parsing to continue.
12934 // It doesn't matter what; when we reach the =>, we will rewind and
12935 // reparse the whole arrow function. See Parser::assignExpr.
12936 return handler_.newNullLiteral(pos());
12937 }
12938
12939 // Pass |possibleError| to support destructuring in arrow parameters.
12940 Node expr;
12941 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)
12942 possibleError))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, possibleError)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
12943 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_IN_PAREN)) {
12944 return errorResult();
12945 }
12946 return handler_.parenthesize(expr);
12947 }
12948
12949 case TokenKind::TemplateHead:
12950 return templateLiteral(yieldHandling);
12951
12952 case TokenKind::NoSubsTemplate:
12953 return noSubstitutionUntaggedTemplate();
12954
12955 case TokenKind::String:
12956 return stringLiteral();
12957
12958 default: {
12959 if (!TokenKindIsPossibleIdentifier(tt)) {
12960 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
12961 return errorResult();
12962 }
12963
12964 if (tt == TokenKind::Async) {
12965 TokenKind nextSameLine = TokenKind::Eof;
12966 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
12967 return errorResult();
12968 }
12969
12970 if (nextSameLine == TokenKind::Function) {
12971 uint32_t toStringStart = pos().begin;
12972 tokenStream.consumeKnownToken(TokenKind::Function);
12973 return functionExpr(toStringStart, PredictUninvoked,
12974 FunctionAsyncKind::AsyncFunction);
12975 }
12976 }
12977
12978 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12979 if (!name) {
12980 return errorResult();
12981 }
12982
12983 return identifierReference(name);
12984 }
12985
12986 case TokenKind::RegExp:
12987 return newRegExp();
12988
12989 case TokenKind::Number:
12990 return newNumber(anyChars.currentToken());
12991
12992 case TokenKind::BigInt:
12993 return newBigInt();
12994
12995 case TokenKind::True:
12996 return handler_.newBooleanLiteral(true, pos());
12997 case TokenKind::False:
12998 return handler_.newBooleanLiteral(false, pos());
12999 case TokenKind::This: {
13000 NameNodeType thisName = null();
13001 if (pc_->sc()->hasFunctionThisBinding()) {
13002 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
13003 }
13004 return handler_.newThisLiteral(pos(), thisName);
13005 }
13006 case TokenKind::Null:
13007 return handler_.newNullLiteral(pos());
13008
13009 case TokenKind::TripleDot: {
13010 // This isn't valid expression syntax, but it's valid in an arrow
13011 // function as a trailing rest param: `(a, b, ...rest) => body`. Check
13012 // if it's directly under
13013 // CoverParenthesizedExpressionAndArrowParameterList, and check for a
13014 // name, closing parenthesis, and arrow, and allow it only if all are
13015 // present.
13016 if (tripledotHandling != TripledotAllowed) {
13017 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
13018 return errorResult();
13019 }
13020
13021 TokenKind next;
13022 if (!tokenStream.getToken(&next)) {
13023 return errorResult();
13024 }
13025
13026 if (next == TokenKind::LeftBracket || next == TokenKind::LeftCurly) {
13027 // Validate, but don't store the pattern right now. The whole arrow
13028 // function is reparsed in functionFormalParametersAndBody().
13029 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)
13030 yieldHandling, next))do { auto mozTryTempResult_ = ::mozilla::ToResult(destructuringDeclaration
(DeclarationKind::CoverArrowParameter, yieldHandling, next));
if ((__builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return
mozTryTempResult_.propagateErr(); } } while (0)
;
13031 } else {
13032 // This doesn't check that the provided name is allowed, e.g. if
13033 // the enclosing code is strict mode code, any of "let", "yield",
13034 // or "arguments" should be prohibited. Argument-parsing code
13035 // handles that.
13036 if (!TokenKindIsPossibleIdentifier(next)) {
13037 error(JSMSG_UNEXPECTED_TOKEN, "rest argument name",
13038 TokenKindToDesc(next));
13039 return errorResult();
13040 }
13041 }
13042
13043 if (!tokenStream.getToken(&next)) {
13044 return errorResult();
13045 }
13046 if (next != TokenKind::RightParen) {
13047 error(JSMSG_UNEXPECTED_TOKEN, "closing parenthesis",
13048 TokenKindToDesc(next));
13049 return errorResult();
13050 }
13051
13052 if (!tokenStream.peekToken(&next)) {
13053 return errorResult();
13054 }
13055 if (next != TokenKind::Arrow) {
13056 // Advance the scanner for proper error location reporting.
13057 tokenStream.consumeKnownToken(next);
13058 error(JSMSG_UNEXPECTED_TOKEN, "'=>' after argument list",
13059 TokenKindToDesc(next));
13060 return errorResult();
13061 }
13062
13063 anyChars.ungetToken(); // put back right paren
13064
13065 // Return an arbitrary expression node. See case TokenKind::RightParen
13066 // above.
13067 return handler_.newNullLiteral(pos());
13068 }
13069 }
13070}
13071
13072template <class ParseHandler, typename Unit>
13073typename ParseHandler::NodeResult
13074GeneralParser<ParseHandler, Unit>::exprInParens(
13075 InHandling inHandling, YieldHandling yieldHandling,
13076 TripledotHandling tripledotHandling,
13077 PossibleError* possibleError /* = nullptr */) {
13078 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"
, 13078); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftParen)"
")"); do { *((volatile int*)__null) = 13078; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
13079 return expr(inHandling, yieldHandling, tripledotHandling, possibleError,
13080 PredictInvoked);
13081}
13082
13083template class PerHandlerParser<FullParseHandler>;
13084template class PerHandlerParser<SyntaxParseHandler>;
13085template class GeneralParser<FullParseHandler, Utf8Unit>;
13086template class GeneralParser<SyntaxParseHandler, Utf8Unit>;
13087template class GeneralParser<FullParseHandler, char16_t>;
13088template class GeneralParser<SyntaxParseHandler, char16_t>;
13089template class Parser<FullParseHandler, Utf8Unit>;
13090template class Parser<SyntaxParseHandler, Utf8Unit>;
13091template class Parser<FullParseHandler, char16_t>;
13092template class Parser<SyntaxParseHandler, char16_t>;
13093
13094} // namespace js::frontend

/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h

1/* -*- Mode: C++; tab-width: 2; 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/* A class for optional values and in-place lazy construction. */
8
9#ifndef mozilla_Maybe_h
10#define mozilla_Maybe_h
11
12#include <functional>
13#include <new> // for placement new
14#include <ostream>
15#include <type_traits>
16#include <utility>
17
18#include "mozilla/Alignment.h"
19#include "mozilla/Assertions.h"
20#include "mozilla/Attributes.h"
21#include "mozilla/MaybeStorageBase.h"
22#include "mozilla/MemoryChecking.h"
23#include "mozilla/OperatorNewExtensions.h"
24#include "mozilla/Poison.h"
25#include "mozilla/ThreadSafety.h"
26
27class nsCycleCollectionTraversalCallback;
28
29template <typename T>
30inline void CycleCollectionNoteChild(
31 nsCycleCollectionTraversalCallback& aCallback, T* aChild, const char* aName,
32 uint32_t aFlags);
33
34namespace mozilla {
35
36struct Nothing {};
37
38inline constexpr bool operator==(const Nothing&, const Nothing&) {
39 return true;
40}
41
42template <class T>
43class Maybe;
44
45namespace detail {
46
47// You would think that poisoning Maybe instances could just be a call
48// to mozWritePoison. Unfortunately, using a simple call to
49// mozWritePoison generates poor code on MSVC for small structures. The
50// generated code contains (always not-taken) branches and does a bunch
51// of setup for `rep stos{l,q}`, even though we know at compile time
52// exactly how many words we're poisoning. Instead, we're going to
53// force MSVC to generate the code we want via recursive templates.
54
55// Write the given poisonValue into p at offset*sizeof(uintptr_t).
56template <size_t offset>
57inline void WritePoisonAtOffset(void* p, const uintptr_t poisonValue) {
58 memcpy(static_cast<char*>(p) + offset * sizeof(poisonValue), &poisonValue,
59 sizeof(poisonValue));
60}
61
62template <size_t Offset, size_t NOffsets>
63struct InlinePoisoner {
64 static void poison(void* p, const uintptr_t poisonValue) {
65 WritePoisonAtOffset<Offset>(p, poisonValue);
66 InlinePoisoner<Offset + 1, NOffsets>::poison(p, poisonValue);
67 }
68};
69
70template <size_t N>
71struct InlinePoisoner<N, N> {
72 static void poison(void*, const uintptr_t) {
73 // All done!
74 }
75};
76
77// We can't generate inline code for large structures, though, because we'll
78// blow out recursive template instantiation limits, and the code would be
79// bloated to boot. So provide a fallback to the out-of-line poisoner.
80template <size_t ObjectSize>
81struct OutOfLinePoisoner {
82 static MOZ_NEVER_INLINE__attribute__((noinline)) void poison(void* p, const uintptr_t) {
83 mozWritePoison(p, ObjectSize);
84 }
85};
86
87template <typename T>
88inline void PoisonObject(T* p) {
89 const uintptr_t POISON = mozPoisonValue();
90 std::conditional_t<(sizeof(T) <= 8 * sizeof(POISON)),
91 InlinePoisoner<0, sizeof(T) / sizeof(POISON)>,
92 OutOfLinePoisoner<sizeof(T)>>::poison(p, POISON);
93}
94
95template <typename T>
96struct MaybePoisoner {
97 static const size_t N = sizeof(T);
98
99 static void poison(void* aPtr) {
100#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED1
101 if (N >= sizeof(uintptr_t)) {
102 PoisonObject(static_cast<std::remove_cv_t<T>*>(aPtr));
103 }
104#endif
105 MOZ_MAKE_MEM_UNDEFINED(aPtr, N)do { } while (0);
106 }
107};
108
109template <typename T,
110 bool TriviallyDestructibleAndCopyable =
111 IsTriviallyDestructibleAndCopyable<T>,
112 bool Copyable = std::is_copy_constructible_v<T>,
113 bool Movable = std::is_move_constructible_v<T>>
114class Maybe_CopyMove_Enabler;
115
116#define MOZ_MAYBE_COPY_OPS() \
117 Maybe_CopyMove_Enabler(const Maybe_CopyMove_Enabler& aOther) { \
118 if (downcast(aOther).isSome()) { \
119 downcast(*this).emplace(*downcast(aOther)); \
120 } \
121 } \
122 \
123 Maybe_CopyMove_Enabler& operator=(const Maybe_CopyMove_Enabler& aOther) { \
124 return downcast(*this).template operator= <T>(downcast(aOther)); \
125 }
126
127#define MOZ_MAYBE_MOVE_OPS() \
128 constexpr Maybe_CopyMove_Enabler(Maybe_CopyMove_Enabler&& aOther) { \
129 if (downcast(aOther).isSome()) { \
130 downcast(*this).emplace(std::move(*downcast(aOther))); \
131 downcast(aOther).reset(); \
132 } \
133 } \
134 \
135 constexpr Maybe_CopyMove_Enabler& operator=( \
136 Maybe_CopyMove_Enabler&& aOther) { \
137 downcast(*this).template operator= <T>(std::move(downcast(aOther))); \
138 \
139 return *this; \
140 }
141
142#define MOZ_MAYBE_DOWNCAST() \
143 static constexpr Maybe<T>& downcast(Maybe_CopyMove_Enabler& aObj) { \
144 return static_cast<Maybe<T>&>(aObj); \
145 } \
146 static constexpr const Maybe<T>& downcast( \
147 const Maybe_CopyMove_Enabler& aObj) { \
148 return static_cast<const Maybe<T>&>(aObj); \
149 }
150
151template <typename T>
152class Maybe_CopyMove_Enabler<T, true, true, true> {
153 public:
154 Maybe_CopyMove_Enabler() = default;
155
156 Maybe_CopyMove_Enabler(const Maybe_CopyMove_Enabler&) = default;
157 Maybe_CopyMove_Enabler& operator=(const Maybe_CopyMove_Enabler&) = default;
158 constexpr Maybe_CopyMove_Enabler(Maybe_CopyMove_Enabler&& aOther) {
159 downcast(aOther).reset();
160 }
161 constexpr Maybe_CopyMove_Enabler& operator=(Maybe_CopyMove_Enabler&& aOther) {
162 downcast(aOther).reset();
163 return *this;
164 }
165
166 private:
167 MOZ_MAYBE_DOWNCAST()
168};
169
170template <typename T>
171class Maybe_CopyMove_Enabler<T, true, false, true> {
172 public:
173 Maybe_CopyMove_Enabler() = default;
174
175 Maybe_CopyMove_Enabler(const Maybe_CopyMove_Enabler&) = delete;
176 Maybe_CopyMove_Enabler& operator=(const Maybe_CopyMove_Enabler&) = delete;
177 constexpr Maybe_CopyMove_Enabler(Maybe_CopyMove_Enabler&& aOther) {
178 downcast(aOther).reset();
179 }
180 constexpr Maybe_CopyMove_Enabler& operator=(Maybe_CopyMove_Enabler&& aOther) {
181 downcast(aOther).reset();
182 return *this;
183 }
184
185 private:
186 MOZ_MAYBE_DOWNCAST()
187};
188
189template <typename T>
190class Maybe_CopyMove_Enabler<T, false, true, true> {
191 public:
192 Maybe_CopyMove_Enabler() = default;
193
194 MOZ_MAYBE_COPY_OPS()
195 MOZ_MAYBE_MOVE_OPS()
196
197 private:
198 MOZ_MAYBE_DOWNCAST()
199};
200
201template <typename T>
202class Maybe_CopyMove_Enabler<T, false, false, true> {
203 public:
204 Maybe_CopyMove_Enabler() = default;
205
206 Maybe_CopyMove_Enabler(const Maybe_CopyMove_Enabler&) = delete;
207 Maybe_CopyMove_Enabler& operator=(const Maybe_CopyMove_Enabler&) = delete;
208 MOZ_MAYBE_MOVE_OPS()
209
210 private:
211 MOZ_MAYBE_DOWNCAST()
212};
213
214template <typename T>
215class Maybe_CopyMove_Enabler<T, false, true, false> {
216 public:
217 Maybe_CopyMove_Enabler() = default;
218
219 MOZ_MAYBE_COPY_OPS()
220 Maybe_CopyMove_Enabler(Maybe_CopyMove_Enabler&&) = delete;
221 Maybe_CopyMove_Enabler& operator=(Maybe_CopyMove_Enabler&&) = delete;
222
223 private:
224 MOZ_MAYBE_DOWNCAST()
225};
226
227template <typename T, bool TriviallyDestructibleAndCopyable>
228class Maybe_CopyMove_Enabler<T, TriviallyDestructibleAndCopyable, false,
229 false> {
230 public:
231 Maybe_CopyMove_Enabler() = default;
232
233 Maybe_CopyMove_Enabler(const Maybe_CopyMove_Enabler&) = delete;
234 Maybe_CopyMove_Enabler& operator=(const Maybe_CopyMove_Enabler&) = delete;
235 Maybe_CopyMove_Enabler(Maybe_CopyMove_Enabler&&) = delete;
236 Maybe_CopyMove_Enabler& operator=(Maybe_CopyMove_Enabler&&) = delete;
237};
238
239#undef MOZ_MAYBE_COPY_OPS
240#undef MOZ_MAYBE_MOVE_OPS
241#undef MOZ_MAYBE_DOWNCAST
242
243template <typename T, bool TriviallyDestructibleAndCopyable =
244 IsTriviallyDestructibleAndCopyable<T>>
245struct MaybeStorage;
246
247template <typename T>
248struct MaybeStorage<T, false> : MaybeStorageBase<T> {
249 protected:
250 char mIsSome = false; // not bool -- guarantees minimal space consumption
251
252 constexpr MaybeStorage() = default;
253 explicit MaybeStorage(const T& aVal)
254 : MaybeStorageBase<T>{aVal}, mIsSome{true} {}
255 explicit MaybeStorage(T&& aVal)
256 : MaybeStorageBase<T>{std::move(aVal)}, mIsSome{true} {}
257
258 template <typename... Args>
259 explicit MaybeStorage(std::in_place_t, Args&&... aArgs)
260 : MaybeStorageBase<T>{std::in_place, std::forward<Args>(aArgs)...},
261 mIsSome{true} {}
262
263 public:
264 // Copy and move operations are no-ops, since copying is moving is implemented
265 // by Maybe_CopyMove_Enabler.
266
267 MaybeStorage(const MaybeStorage&) : MaybeStorageBase<T>{} {}
268 MaybeStorage& operator=(const MaybeStorage&) { return *this; }
269 MaybeStorage(MaybeStorage&&) : MaybeStorageBase<T>{} {}
270 MaybeStorage& operator=(MaybeStorage&&) { return *this; }
271
272 ~MaybeStorage() {
273 if (mIsSome
17.1
Field 'mIsSome' is 0
17.1
Field 'mIsSome' is 0
17.1
Field 'mIsSome' is 0
17.1
Field 'mIsSome' is 0
17.1
Field 'mIsSome' is 0
) {
18
Taking false branch
274 this->addr()->T::~T();
275 }
276 }
19
Calling implicit destructor for 'MaybeStorageBase<js::frontend::ParseContext::Scope, false>'
20
Calling '~Union'
277};
278
279template <typename T>
280struct MaybeStorage<T, true> : MaybeStorageBase<T> {
281 protected:
282 char mIsSome = false; // not bool -- guarantees minimal space consumption
283
284 constexpr MaybeStorage() = default;
285 constexpr explicit MaybeStorage(const T& aVal)
286 : MaybeStorageBase<T>{aVal}, mIsSome{true} {}
287 constexpr explicit MaybeStorage(T&& aVal)
288 : MaybeStorageBase<T>{std::move(aVal)}, mIsSome{true} {}
289
290 template <typename... Args>
291 constexpr explicit MaybeStorage(std::in_place_t, Args&&... aArgs)
292 : MaybeStorageBase<T>{std::in_place, std::forward<Args>(aArgs)...},
293 mIsSome{true} {}
294};
295
296template <typename T>
297struct IsMaybeImpl : std::false_type {};
298
299template <typename T>
300struct IsMaybeImpl<Maybe<T>> : std::true_type {};
301
302template <typename T>
303using IsMaybe = IsMaybeImpl<std::decay_t<T>>;
304
305} // namespace detail
306
307template <typename T, typename U = typename std::remove_cv<
308 typename std::remove_reference<T>::type>::type>
309constexpr Maybe<U> Some(T&& aValue);
310
311/*
312 * Maybe is a container class which contains either zero or one elements. It
313 * serves two roles. It can represent values which are *semantically* optional,
314 * augmenting a type with an explicit 'Nothing' value. In this role, it provides
315 * methods that make it easy to work with values that may be missing, along with
316 * equality and comparison operators so that Maybe values can be stored in
317 * containers. Maybe values can be constructed conveniently in expressions using
318 * type inference, as follows:
319 *
320 * void doSomething(Maybe<Foo> aFoo) {
321 * if (aFoo) // Make sure that aFoo contains a value...
322 * aFoo->takeAction(); // and then use |aFoo->| to access it.
323 * } // |*aFoo| also works!
324 *
325 * doSomething(Nothing()); // Passes a Maybe<Foo> containing no value.
326 * doSomething(Some(Foo(100))); // Passes a Maybe<Foo> containing |Foo(100)|.
327 *
328 * You'll note that it's important to check whether a Maybe contains a value
329 * before using it, using conversion to bool, |isSome()|, or |isNothing()|. You
330 * can avoid these checks, and sometimes write more readable code, using
331 * |valueOr()|, |ptrOr()|, and |refOr()|, which allow you to retrieve the value
332 * in the Maybe and provide a default for the 'Nothing' case. You can also use
333 * |apply()| to call a function only if the Maybe holds a value, and |map()| to
334 * transform the value in the Maybe, returning another Maybe with a possibly
335 * different type.
336 *
337 * Maybe's other role is to support lazily constructing objects without using
338 * dynamic storage. A Maybe directly contains storage for a value, but it's
339 * empty by default. |emplace()|, as mentioned above, can be used to construct a
340 * value in Maybe's storage. The value a Maybe contains can be destroyed by
341 * calling |reset()|; this will happen automatically if a Maybe is destroyed
342 * while holding a value.
343 *
344 * It's a common idiom in C++ to use a pointer as a 'Maybe' type, with a null
345 * value meaning 'Nothing' and any other value meaning 'Some'. You can convert
346 * from such a pointer to a Maybe value using 'ToMaybe()'.
347 *
348 * Maybe is inspired by similar types in the standard library of many other
349 * languages (e.g. Haskell's Maybe and Rust's Option). In the C++ world it's
350 * very similar to std::optional, which was proposed for C++14 and originated in
351 * Boost. The most important differences between Maybe and std::optional are:
352 *
353 * - std::optional<T> may be compared with T. We deliberately forbid that.
354 * - std::optional has |valueOr()|, equivalent to Maybe's |valueOr()|, but
355 * lacks corresponding methods for |refOr()| and |ptrOr()|.
356 * - std::optional lacks |map()| and |apply()|, making it less suitable for
357 * functional-style code.
358 * - std::optional lacks many convenience functions that Maybe has. Most
359 * unfortunately, it lacks equivalents of the type-inferred constructor
360 * functions |Some()| and |Nothing()|.
361 */
362template <class T>
363class MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS Maybe
364 : private detail::MaybeStorage<T>,
365 public detail::Maybe_CopyMove_Enabler<T> {
366 template <typename, bool, bool, bool>
367 friend class detail::Maybe_CopyMove_Enabler;
368
369 template <typename U, typename V>
370 friend constexpr Maybe<V> Some(U&& aValue);
371
372 struct SomeGuard {};
373
374 template <typename U>
375 constexpr Maybe(U&& aValue, SomeGuard)
376 : detail::MaybeStorage<T>{std::forward<U>(aValue)} {}
377
378 using detail::MaybeStorage<T>::mIsSome;
379 using detail::MaybeStorage<T>::mStorage;
380
381 void poisonData() { detail::MaybePoisoner<T>::poison(&mStorage.val); }
382
383 public:
384 using ValueType = T;
385
386 MOZ_ALLOW_TEMPORARY constexpr Maybe() = default;
387
388 MOZ_ALLOW_TEMPORARY MOZ_IMPLICIT constexpr Maybe(Nothing) : Maybe{} {}
389
390 template <typename... Args>
391 constexpr explicit Maybe(std::in_place_t, Args&&... aArgs)
392 : detail::MaybeStorage<T>{std::in_place, std::forward<Args>(aArgs)...} {}
393
394 /**
395 * Maybe<T> can be copy-constructed from a Maybe<U> if T is constructible from
396 * a const U&.
397 */
398 template <typename U,
399 std::enable_if_t<std::is_constructible_v<T, const U&>, bool> = true>
400 MOZ_IMPLICIT Maybe(const Maybe<U>& aOther) {
401 if (aOther.isSome()) {
402 emplace(*aOther);
403 }
404 }
405
406 template <typename U, std::enable_if_t<!std::is_constructible_v<T, const U&>,
407 bool> = true>
408 explicit Maybe(const Maybe<U>& aOther) = delete;
409
410 /**
411 * Maybe<T> can be move-constructed from a Maybe<U> if T is constructible from
412 * a U&&.
413 */
414 template <typename U,
415 std::enable_if_t<std::is_constructible_v<T, U&&>, bool> = true>
416 MOZ_IMPLICIT Maybe(Maybe<U>&& aOther) {
417 if (aOther.isSome()) {
418 emplace(std::move(*aOther));
419 aOther.reset();
420 }
421 }
422 template <typename U,
423 std::enable_if_t<!std::is_constructible_v<T, U&&>, bool> = true>
424 explicit Maybe(Maybe<U>&& aOther) = delete;
425
426 template <typename U,
427 std::enable_if_t<std::is_constructible_v<T, const U&>, bool> = true>
428 Maybe& operator=(const Maybe<U>& aOther) {
429 if (aOther.isSome()) {
430 if (mIsSome) {
431 ref() = aOther.ref();
432 } else {
433 emplace(*aOther);
434 }
435 } else {
436 reset();
437 }
438 return *this;
439 }
440
441 template <typename U, std::enable_if_t<!std::is_constructible_v<T, const U&>,
442 bool> = true>
443 Maybe& operator=(const Maybe<U>& aOther) = delete;
444
445 template <typename U,
446 std::enable_if_t<std::is_constructible_v<T, U&&>, bool> = true>
447 Maybe& operator=(Maybe<U>&& aOther) {
448 if (aOther.isSome()) {
449 if (mIsSome) {
450 ref() = std::move(aOther.ref());
451 } else {
452 emplace(std::move(*aOther));
453 }
454 aOther.reset();
455 } else {
456 reset();
457 }
458
459 return *this;
460 }
461
462 template <typename U,
463 std::enable_if_t<!std::is_constructible_v<T, U&&>, bool> = true>
464 Maybe& operator=(Maybe<U>&& aOther) = delete;
465
466 constexpr Maybe& operator=(Nothing) {
467 reset();
468 return *this;
469 }
470
471 /* Methods that check whether this Maybe contains a value */
472 constexpr explicit operator bool() const { return isSome(); }
473 constexpr bool isSome() const { return mIsSome; }
474 constexpr bool isNothing() const { return !mIsSome; }
475
476 /* Returns the contents of this Maybe<T> by value. Unsafe unless |isSome()|.
477 */
478 constexpr T value() const&;
479 constexpr T value() &&;
480 constexpr T value() const&&;
481
482 /**
483 * Move the contents of this Maybe<T> out of internal storage and return it
484 * without calling the destructor. The internal storage is also reset to
485 * avoid multiple calls. Unsafe unless |isSome()|.
486 */
487 constexpr T extract() {
488 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 488); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 488; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
489 T v = std::move(mStorage.val);
490 reset();
491 return v;
492 }
493
494 /**
495 * Returns the value (possibly |Nothing()|) by moving it out of this Maybe<T>
496 * and leaving |Nothing()| in its place.
497 */
498 Maybe<T> take() { return std::exchange(*this, Nothing()); }
499
500 /*
501 * Returns the contents of this Maybe<T> by value. If |isNothing()|, returns
502 * the default value provided.
503 *
504 * Note: If the value passed to aDefault is not the result of a trivial
505 * expression, but expensive to evaluate, e.g. |valueOr(ExpensiveFunction())|,
506 * use |valueOrFrom| instead, e.g.
507 * |valueOrFrom([arg] { return ExpensiveFunction(arg); })|. This ensures
508 * that the expensive expression is only evaluated when its result will
509 * actually be used.
510 */
511 template <typename V>
512 constexpr T valueOr(V&& aDefault) const {
513 if (isSome()) {
514 return ref();
515 }
516 return std::forward<V>(aDefault);
517 }
518
519 /*
520 * Returns the contents of this Maybe<T> by value. If |isNothing()|, returns
521 * the value returned from the function or functor provided.
522 */
523 template <typename F>
524 constexpr T valueOrFrom(F&& aFunc) const {
525 if (isSome()) {
526 return ref();
527 }
528 return aFunc();
529 }
530
531 /* Returns the contents of this Maybe<T> by pointer. Unsafe unless |isSome()|.
532 */
533 T* ptr();
534 constexpr const T* ptr() const;
535
536 /*
537 * Returns the contents of this Maybe<T> by pointer. If |isNothing()|,
538 * returns the default value provided.
539 */
540 T* ptrOr(T* aDefault) {
541 if (isSome()) {
542 return ptr();
543 }
544 return aDefault;
545 }
546
547 constexpr const T* ptrOr(const T* aDefault) const {
548 if (isSome()) {
549 return ptr();
550 }
551 return aDefault;
552 }
553
554 /*
555 * Returns the contents of this Maybe<T> by pointer. If |isNothing()|,
556 * returns the value returned from the function or functor provided.
557 */
558 template <typename F>
559 T* ptrOrFrom(F&& aFunc) {
560 if (isSome()) {
561 return ptr();
562 }
563 return aFunc();
564 }
565
566 template <typename F>
567 const T* ptrOrFrom(F&& aFunc) const {
568 if (isSome()) {
569 return ptr();
570 }
571 return aFunc();
572 }
573
574 constexpr T* operator->();
575 constexpr const T* operator->() const;
576
577 /* Returns the contents of this Maybe<T> by ref. Unsafe unless |isSome()|. */
578 constexpr T& ref() &;
579 constexpr const T& ref() const&;
580 constexpr T&& ref() &&;
581 constexpr const T&& ref() const&&;
582
583 /*
584 * Returns the contents of this Maybe<T> by ref. If |isNothing()|, returns
585 * the default value provided.
586 */
587 constexpr T& refOr(T& aDefault) {
588 if (isSome()) {
589 return ref();
590 }
591 return aDefault;
592 }
593
594 constexpr const T& refOr(const T& aDefault) const {
595 if (isSome()) {
596 return ref();
597 }
598 return aDefault;
599 }
600
601 /*
602 * Returns the contents of this Maybe<T> by ref. If |isNothing()|, returns the
603 * value returned from the function or functor provided.
604 */
605 template <typename F>
606 constexpr T& refOrFrom(F&& aFunc) {
607 if (isSome()) {
608 return ref();
609 }
610 return aFunc();
611 }
612
613 template <typename F>
614 constexpr const T& refOrFrom(F&& aFunc) const {
615 if (isSome()) {
616 return ref();
617 }
618 return aFunc();
619 }
620
621 constexpr T& operator*() &;
622 constexpr const T& operator*() const&;
623 constexpr T&& operator*() &&;
624 constexpr const T&& operator*() const&&;
625
626 /* If |isSome()|, runs the provided function or functor on the contents of
627 * this Maybe. */
628 template <typename Func>
629 constexpr Maybe& apply(Func&& aFunc) & {
630 if (isSome()) {
631 std::forward<Func>(aFunc)(ref());
632 }
633 return *this;
634 }
635
636 template <typename Func>
637 constexpr const Maybe& apply(Func&& aFunc) const& {
638 if (isSome()) {
639 std::forward<Func>(aFunc)(ref());
640 }
641 return *this;
642 }
643
644 template <typename Func>
645 constexpr Maybe& apply(Func&& aFunc) && {
646 if (isSome()) {
647 std::forward<Func>(aFunc)(extract());
648 }
649 return *this;
650 }
651
652 template <typename Func>
653 constexpr Maybe& apply(Func&& aFunc) const&& {
654 if (isSome()) {
655 std::forward<Func>(aFunc)(extract());
656 }
657 return *this;
658 }
659
660 /*
661 * If |isSome()|, runs the provided function and returns the result wrapped
662 * in a Maybe. If |isNothing()|, returns an empty Maybe value with the same
663 * value type as what the provided function would have returned.
664 */
665 template <typename Func>
666 constexpr auto map(Func&& aFunc) & {
667 if (isSome()) {
668 return Some(std::forward<Func>(aFunc)(ref()));
669 }
670 return Maybe<decltype(std::forward<Func>(aFunc)(ref()))>{};
671 }
672
673 template <typename Func>
674 constexpr auto map(Func&& aFunc) const& {
675 if (isSome()) {
676 return Some(std::forward<Func>(aFunc)(ref()));
677 }
678 return Maybe<decltype(std::forward<Func>(aFunc)(ref()))>{};
679 }
680
681 template <typename Func>
682 constexpr auto map(Func&& aFunc) && {
683 if (isSome()) {
684 return Some(std::forward<Func>(aFunc)(extract()));
685 }
686 return Maybe<decltype(std::forward<Func>(aFunc)(extract()))>{};
687 }
688
689 template <typename Func>
690 constexpr auto map(Func&& aFunc) const&& {
691 if (isSome()) {
692 return Some(std::forward<Func>(aFunc)(extract()));
693 }
694 return Maybe<decltype(std::forward<Func>(aFunc)(extract()))>{};
695 }
696
697 /*
698 * If |isSome()|, runs the provided function or functor on the contents of
699 * this Maybe and returns the result. Note that the provided function or
700 * functor must return a Maybe<U> of any type U.
701 * If |isNothing()|, returns an empty Maybe value with the same type as what
702 * the provided function would have returned.
703 */
704 template <typename Func>
705 constexpr auto andThen(Func&& aFunc) & {
706 static_assert(std::is_invocable_v<Func, T&>);
707 using U = std::invoke_result_t<Func, T&>;
708 static_assert(detail::IsMaybe<U>::value);
709 if (isSome()) {
710 return std::invoke(std::forward<Func>(aFunc), ref());
711 }
712 return std::remove_cv_t<std::remove_reference_t<U>>{};
713 }
714
715 template <typename Func>
716 constexpr auto andThen(Func&& aFunc) const& {
717 static_assert(std::is_invocable_v<Func, const T&>);
718 using U = std::invoke_result_t<Func, const T&>;
719 static_assert(detail::IsMaybe<U>::value);
720 if (isSome()) {
721 return std::invoke(std::forward<Func>(aFunc), ref());
722 }
723 return std::remove_cv_t<std::remove_reference_t<U>>{};
724 }
725
726 template <typename Func>
727 constexpr auto andThen(Func&& aFunc) && {
728 static_assert(std::is_invocable_v<Func, T&&>);
729 using U = std::invoke_result_t<Func, T&&>;
730 static_assert(detail::IsMaybe<U>::value);
731 if (isSome()) {
732 return std::invoke(std::forward<Func>(aFunc), extract());
733 }
734 return std::remove_cv_t<std::remove_reference_t<U>>{};
735 }
736
737 template <typename Func>
738 constexpr auto andThen(Func&& aFunc) const&& {
739 static_assert(std::is_invocable_v<Func, const T&&>);
740 using U = std::invoke_result_t<Func, const T&&>;
741 static_assert(detail::IsMaybe<U>::value);
742 if (isSome()) {
743 return std::invoke(std::forward<Func>(aFunc), extract());
744 }
745 return std::remove_cv_t<std::remove_reference_t<U>>{};
746 }
747
748 /*
749 * If |isNothing()|, runs the provided function or functor and returns its
750 * result. If |isSome()|, returns the contained value wrapped in a Maybe.
751 */
752 template <typename Func>
753 constexpr Maybe orElse(Func&& aFunc) & {
754 static_assert(std::is_invocable_v<Func>);
755 using U = std::invoke_result_t<Func>;
756 static_assert(
757 std::is_same_v<Maybe, std::remove_cv_t<std::remove_reference_t<U>>>);
758 if (isSome()) {
759 return *this;
760 }
761 return std::invoke(std::forward<Func>(aFunc));
762 }
763
764 template <typename Func>
765 constexpr Maybe orElse(Func&& aFunc) const& {
766 static_assert(std::is_invocable_v<Func>);
767 using U = std::invoke_result_t<Func>;
768 static_assert(
769 std::is_same_v<Maybe, std::remove_cv_t<std::remove_reference_t<U>>>);
770 if (isSome()) {
771 return *this;
772 }
773 return std::invoke(std::forward<Func>(aFunc));
774 }
775
776 template <typename Func>
777 constexpr Maybe orElse(Func&& aFunc) && {
778 static_assert(std::is_invocable_v<Func>);
779 using U = std::invoke_result_t<Func>;
780 static_assert(
781 std::is_same_v<Maybe, std::remove_cv_t<std::remove_reference_t<U>>>);
782 if (isSome()) {
783 return std::move(*this);
784 }
785 return std::invoke(std::forward<Func>(aFunc));
786 }
787
788 template <typename Func>
789 constexpr Maybe orElse(Func&& aFunc) const&& {
790 static_assert(std::is_invocable_v<Func>);
791 using U = std::invoke_result_t<Func>;
792 static_assert(
793 std::is_same_v<Maybe, std::remove_cv_t<std::remove_reference_t<U>>>);
794 if (isSome()) {
795 return std::move(*this);
796 }
797 return std::invoke(std::forward<Func>(aFunc));
798 }
799
800 /* If |isSome()|, empties this Maybe and destroys its contents. */
801 constexpr void reset() {
802 if (isSome()) {
803 if constexpr (!std::is_trivially_destructible_v<T>) {
804 /*
805 * Static analyzer gets confused if we have Maybe<MutexAutoLock>,
806 * so we suppress thread-safety warnings here
807 */
808 MOZ_PUSH_IGNORE_THREAD_SAFETYGCC diagnostic push GCC diagnostic ignored "-Wthread-safety"
809 ref().T::~T();
810 MOZ_POP_THREAD_SAFETYGCC diagnostic pop
811 poisonData();
812 }
813 mIsSome = false;
814 }
815 }
816
817 /*
818 * Constructs a T value in-place in this empty Maybe<T>'s storage. The
819 * arguments to |emplace()| are the parameters to T's constructor.
820 */
821 template <typename... Args>
822 constexpr void emplace(Args&&... aArgs);
823
824 template <typename U>
825 constexpr std::enable_if_t<std::is_same_v<T, U> &&
826 std::is_copy_constructible_v<U> &&
827 !std::is_move_constructible_v<U>>
828 emplace(U&& aArgs) {
829 emplace(aArgs);
830 }
831
832 friend std::ostream& operator<<(std::ostream& aStream,
833 const Maybe<T>& aMaybe) {
834 if (aMaybe) {
835 aStream << aMaybe.ref();
836 } else {
837 aStream << "<Nothing>";
838 }
839 return aStream;
840 }
841};
842
843template <typename T>
844class Maybe<T&> {
845 public:
846 constexpr Maybe() = default;
847 constexpr MOZ_IMPLICIT Maybe(Nothing) {}
848
849 void emplace(T& aRef) { mValue = &aRef; }
850
851 /* Methods that check whether this Maybe contains a value */
852 constexpr explicit operator bool() const { return isSome(); }
853 constexpr bool isSome() const { return mValue; }
854 constexpr bool isNothing() const { return !mValue; }
855
856 T& ref() const {
857 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 857); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 857; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
858 return *mValue;
859 }
860
861 T* operator->() const { return &ref(); }
862 T& operator*() const { return ref(); }
863
864 // Deliberately not defining value and ptr accessors, as these may be
865 // confusing on a reference-typed Maybe.
866
867 // XXX Should we define refOr?
868
869 void reset() { mValue = nullptr; }
870
871 template <typename Func>
872 const Maybe& apply(Func&& aFunc) const {
873 if (isSome()) {
874 std::forward<Func>(aFunc)(ref());
875 }
876 return *this;
877 }
878
879 template <typename Func>
880 auto map(Func&& aFunc) const {
881 Maybe<decltype(std::forward<Func>(aFunc)(ref()))> val;
882 if (isSome()) {
883 val.emplace(std::forward<Func>(aFunc)(ref()));
884 }
885 return val;
886 }
887
888 template <typename Func>
889 constexpr auto andThen(Func&& aFunc) const {
890 static_assert(std::is_invocable_v<Func, T&>);
891 using U = std::invoke_result_t<Func, T&>;
892 static_assert(detail::IsMaybe<U>::value);
893 if (isSome()) {
894 return std::invoke(std::forward<Func>(aFunc), ref());
895 }
896 return std::remove_cv_t<std::remove_reference_t<U>>{};
897 }
898
899 template <typename Func>
900 constexpr Maybe orElse(Func&& aFunc) const {
901 static_assert(std::is_invocable_v<Func>);
902 using U = std::invoke_result_t<Func>;
903 static_assert(
904 std::is_same_v<Maybe, std::remove_cv_t<std::remove_reference_t<U>>>);
905 if (isSome()) {
906 return *this;
907 }
908 return std::invoke(std::forward<Func>(aFunc));
909 }
910
911 bool refEquals(const Maybe<T&>& aOther) const {
912 return mValue == aOther.mValue;
913 }
914
915 bool refEquals(const T& aOther) const { return mValue == &aOther; }
916
917 private:
918 T* mValue = nullptr;
919};
920
921template <typename T>
922constexpr T Maybe<T>::value() const& {
923 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 923); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 923; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
924 return ref();
925}
926
927template <typename T>
928constexpr T Maybe<T>::value() && {
929 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 929); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 929; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
930 return std::move(ref());
931}
932
933template <typename T>
934constexpr T Maybe<T>::value() const&& {
935 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 935); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 935; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
936 return std::move(ref());
937}
938
939template <typename T>
940T* Maybe<T>::ptr() {
941 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 941); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 941; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
942 return &ref();
943}
944
945template <typename T>
946constexpr const T* Maybe<T>::ptr() const {
947 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 947); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 947; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
948 return &ref();
949}
950
951template <typename T>
952constexpr T* Maybe<T>::operator->() {
953 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 953); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 953; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
954 return ptr();
955}
956
957template <typename T>
958constexpr const T* Maybe<T>::operator->() const {
959 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 959); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 959; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
960 return ptr();
961}
962
963template <typename T>
964constexpr T& Maybe<T>::ref() & {
965 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 965); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 965; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
966 return mStorage.val;
967}
968
969template <typename T>
970constexpr const T& Maybe<T>::ref() const& {
971 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 971); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 971; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
972 return mStorage.val;
973}
974
975template <typename T>
976constexpr T&& Maybe<T>::ref() && {
977 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 977); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 977; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
978 return std::move(mStorage.val);
979}
980
981template <typename T>
982constexpr const T&& Maybe<T>::ref() const&& {
983 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 983); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 983; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
984 return std::move(mStorage.val);
985}
986
987template <typename T>
988constexpr T& Maybe<T>::operator*() & {
989 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 989); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 989; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
990 return ref();
991}
992
993template <typename T>
994constexpr const T& Maybe<T>::operator*() const& {
995 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 995); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 995; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
996 return ref();
997}
998
999template <typename T>
1000constexpr T&& Maybe<T>::operator*() && {
1001 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 1001); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 1001; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1002 return std::move(ref());
1003}
1004
1005template <typename T>
1006constexpr const T&& Maybe<T>::operator*() const&& {
1007 MOZ_RELEASE_ASSERT(isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 1007); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "isSome()"
")"); do { *((volatile int*)__null) = 1007; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1008 return std::move(ref());
1009}
1010
1011template <typename T>
1012template <typename... Args>
1013constexpr void Maybe<T>::emplace(Args&&... aArgs) {
1014 MOZ_RELEASE_ASSERT(!isSome())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!isSome())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!isSome()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("!isSome()", "/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/Maybe.h"
, 1014); AnnotateMozCrashReason("MOZ_RELEASE_ASSERT" "(" "!isSome()"
")"); do { *((volatile int*)__null) = 1014; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1015 ::new (KnownNotNull, &mStorage.val) T(std::forward<Args>(aArgs)...);
1016 mIsSome = true;
1017}
1018
1019/*
1020 * Some() creates a Maybe<T> value containing the provided T value. If T has a
1021 * move constructor, it's used to make this as efficient as possible.
1022 *
1023 * Some() selects the type of Maybe it returns by removing any const, volatile,
1024 * or reference qualifiers from the type of the value you pass to it. This gives
1025 * it more intuitive behavior when used in expressions, but it also means that
1026 * if you need to construct a Maybe value that holds a const, volatile, or
1027 * reference value, you need to use emplace() instead.
1028 */
1029template <typename T, typename U>
1030constexpr Maybe<U> Some(T&& aValue) {
1031 return {std::forward<T>(aValue), typename Maybe<U>::SomeGuard{}};
1032}
1033
1034template <typename T>
1035constexpr Maybe<T&> SomeRef(T& aValue) {
1036 Maybe<T&> value;
1037 value.emplace(aValue);
1038 return value;
1039}
1040
1041template <typename T>
1042constexpr Maybe<T&> ToMaybeRef(T* const aPtr) {
1043 return aPtr ? SomeRef(*aPtr) : Nothing{};
1044}
1045
1046template <typename T>
1047Maybe<std::remove_cv_t<std::remove_reference_t<T>>> ToMaybe(T* aPtr) {
1048 if (aPtr) {
1049 return Some(*aPtr);
1050 }
1051 return Nothing();
1052}
1053
1054/*
1055 * Two Maybe<T> values are equal if
1056 * - both are Nothing, or
1057 * - both are Some, and the values they contain are equal.
1058 */
1059template <typename T>
1060constexpr bool operator==(const Maybe<T>& aLHS, const Maybe<T>& aRHS) {
1061 static_assert(!std::is_reference_v<T>,
1062 "operator== is not defined for Maybe<T&>, compare values or "
1063 "addresses explicitly instead");
1064 if (aLHS.isNothing() != aRHS.isNothing()) {
1065 return false;
1066 }
1067 return aLHS.isNothing() || *aLHS == *aRHS;
1068}
1069
1070template <typename T>
1071constexpr bool operator!=(const Maybe<T>& aLHS, const Maybe<T>& aRHS) {
1072 return !(aLHS == aRHS);
1073}
1074
1075/*
1076 * We support comparison to Nothing to allow reasonable expressions like:
1077 * if (maybeValue == Nothing()) { ... }
1078 */
1079template <typename T>
1080constexpr bool operator==(const Maybe<T>& aLHS, const Nothing& aRHS) {
1081 return aLHS.isNothing();
1082}
1083
1084template <typename T>
1085constexpr bool operator!=(const Maybe<T>& aLHS, const Nothing& aRHS) {
1086 return !(aLHS == aRHS);
1087}
1088
1089template <typename T>
1090constexpr bool operator==(const Nothing& aLHS, const Maybe<T>& aRHS) {
1091 return aRHS.isNothing();
1092}
1093
1094template <typename T>
1095constexpr bool operator!=(const Nothing& aLHS, const Maybe<T>& aRHS) {
1096 return !(aLHS == aRHS);
1097}
1098
1099/*
1100 * Maybe<T> values are ordered in the same way T values are ordered, except that
1101 * Nothing comes before anything else.
1102 */
1103template <typename T>
1104constexpr bool operator<(const Maybe<T>& aLHS, const Maybe<T>& aRHS) {
1105 if (aLHS.isNothing()) {
1106 return aRHS.isSome();
1107 }
1108 if (aRHS.isNothing()) {
1109 return false;
1110 }
1111 return *aLHS < *aRHS;
1112}
1113
1114template <typename T>
1115constexpr bool operator>(const Maybe<T>& aLHS, const Maybe<T>& aRHS) {
1116 return !(aLHS < aRHS || aLHS == aRHS);
1117}
1118
1119template <typename T>
1120constexpr bool operator<=(const Maybe<T>& aLHS, const Maybe<T>& aRHS) {
1121 return aLHS < aRHS || aLHS == aRHS;
1122}
1123
1124template <typename T>
1125constexpr bool operator>=(const Maybe<T>& aLHS, const Maybe<T>& aRHS) {
1126 return !(aLHS < aRHS);
1127}
1128
1129template <typename T>
1130inline void ImplCycleCollectionTraverse(
1131 nsCycleCollectionTraversalCallback& aCallback, mozilla::Maybe<T>& aField,
1132 const char* aName, uint32_t aFlags = 0) {
1133 if (aField) {
1134 ImplCycleCollectionTraverse(aCallback, aField.ref(), aName, aFlags);
1135 }
1136}
1137
1138template <typename T>
1139inline void ImplCycleCollectionUnlink(mozilla::Maybe<T>& aField) {
1140 if (aField) {
1141 ImplCycleCollectionUnlink(aField.ref());
1142 }
1143}
1144
1145} // namespace mozilla
1146
1147#endif /* mozilla_Maybe_h */

/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/mozilla/MaybeStorageBase.h

1/* -*- Mode: C++; tab-width: 2; 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/* Internal storage class used e.g. by Maybe and Result. This file doesn't
8 * contain any public declarations. */
9
10#ifndef mfbt_MaybeStorageBase_h
11#define mfbt_MaybeStorageBase_h
12
13#include <type_traits>
14#include <utility>
15
16namespace mozilla::detail {
17
18template <typename T>
19constexpr bool IsTriviallyDestructibleAndCopyable =
20 std::is_trivially_destructible_v<T> &&
21 (std::is_trivially_copy_constructible_v<T> ||
22 !std::is_copy_constructible_v<T>);
23
24template <typename T, bool TriviallyDestructibleAndCopyable =
25 IsTriviallyDestructibleAndCopyable<T>>
26struct MaybeStorageBase;
27
28template <typename T>
29struct MaybeStorageBase<T, false> {
30 protected:
31 using NonConstT = std::remove_const_t<T>;
32
33 union Union {
34 Union() {}
35 explicit Union(const T& aVal) : val{aVal} {}
36 template <typename U,
37 typename = std::enable_if_t<std::is_move_constructible_v<U>>>
38 explicit Union(U&& aVal) : val{std::forward<U>(aVal)} {}
39 template <typename... Args>
40 explicit Union(std::in_place_t, Args&&... aArgs)
41 : val{std::forward<Args>(aArgs)...} {}
42
43 ~Union() {}
21
Calling implicit destructor for 'Scope'
22
Calling defaulted destructor for 'PooledVectorPtr<mozilla::Vector<js::frontend::FunctionBox *, 24, js::SystemAllocPolicy>>'
44
45 NonConstT val;
46 } mStorage;
47
48 public:
49 constexpr MaybeStorageBase() = default;
50 explicit MaybeStorageBase(const T& aVal) : mStorage{aVal} {}
51 explicit MaybeStorageBase(T&& aVal) : mStorage{std::move(aVal)} {}
52 template <typename... Args>
53 explicit MaybeStorageBase(std::in_place_t, Args&&... aArgs)
54 : mStorage{std::in_place, std::forward<Args>(aArgs)...} {}
55
56 const T* addr() const { return &mStorage.val; }
57 T* addr() { return &mStorage.val; }
58};
59
60template <typename T>
61struct MaybeStorageBase<T, true> {
62 protected:
63 using NonConstT = std::remove_const_t<T>;
64
65 union Union {
66 constexpr Union() : empty() {}
67 constexpr explicit Union(const T& aVal) : val{aVal} {}
68 constexpr explicit Union(T&& aVal) : val{std::move(aVal)} {}
69 template <typename... Args>
70 constexpr explicit Union(std::in_place_t, Args&&... aArgs)
71 : val{std::forward<Args>(aArgs)...} {}
72
73 NonConstT val;
74 char empty;
75 } mStorage;
76
77 public:
78 constexpr MaybeStorageBase() = default;
79 constexpr explicit MaybeStorageBase(const T& aVal) : mStorage{aVal} {}
80 constexpr explicit MaybeStorageBase(T&& aVal) : mStorage{std::move(aVal)} {}
81
82 template <typename... Args>
83 constexpr explicit MaybeStorageBase(std::in_place_t, Args&&... aArgs)
84 : mStorage{std::in_place, std::forward<Args>(aArgs)...} {}
85
86 constexpr const T* addr() const { return &mStorage.val; }
87 constexpr T* addr() { return &mStorage.val; }
88};
89
90} // namespace mozilla::detail
91
92#endif

/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.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 frontend_ParseContext_h
8#define frontend_ParseContext_h
9
10#include "ds/Nestable.h"
11#include "frontend/ErrorReporter.h"
12#include "frontend/NameAnalysisTypes.h" // DeclaredNameInfo, FunctionBoxVector
13#include "frontend/NameCollections.h"
14#include "frontend/ParserAtom.h" // TaggedParserAtomIndex
15#include "frontend/ScriptIndex.h" // ScriptIndex
16#include "frontend/SharedContext.h"
17#include "js/friend/ErrorMessages.h" // JSMSG_*
18#include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind
19
20namespace js {
21
22namespace frontend {
23
24class ParserBase;
25class UsedNameTracker;
26
27struct CompilationState;
28
29const char* DeclarationKindString(DeclarationKind kind);
30
31// Returns true if the declaration is `var` or equivalent.
32bool DeclarationKindIsVar(DeclarationKind kind);
33
34bool DeclarationKindIsParameter(DeclarationKind kind);
35
36/*
37 * The struct ParseContext stores information about the current parsing context,
38 * which is part of the parser state (see the field Parser::pc). The current
39 * parsing context is either the global context, or the function currently being
40 * parsed. When the parser encounters a function definition, it creates a new
41 * ParseContext, makes it the new current context.
42 */
43class ParseContext : public Nestable<ParseContext> {
44 public:
45 // The intra-function statement stack.
46 //
47 // Used for early error checking that depend on the nesting structure of
48 // statements, such as continue/break targets, labels, and unbraced
49 // lexical declarations.
50 class Statement : public Nestable<Statement> {
51 StatementKind kind_;
52
53 public:
54 using Nestable<Statement>::enclosing;
55 using Nestable<Statement>::findNearest;
56
57 Statement(ParseContext* pc, StatementKind kind)
58 : Nestable<Statement>(&pc->innermostStatement_), kind_(kind) {}
59
60 template <typename T>
61 inline bool is() const;
62 template <typename T>
63 inline T& as();
64
65 StatementKind kind() const { return kind_; }
66
67 void refineForKind(StatementKind newForKind) {
68 MOZ_ASSERT(kind_ == StatementKind::ForLoop)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind_ == StatementKind::ForLoop)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind_ == StatementKind::ForLoop
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"kind_ == StatementKind::ForLoop", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 68); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind_ == StatementKind::ForLoop"
")"); do { *((volatile int*)__null) = 68; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
69 MOZ_ASSERT(newForKind == StatementKind::ForInLoop ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(newForKind == StatementKind::ForInLoop || newForKind
== StatementKind::ForOfLoop)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(newForKind == StatementKind::
ForInLoop || newForKind == StatementKind::ForOfLoop))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("newForKind == StatementKind::ForInLoop || newForKind == StatementKind::ForOfLoop"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 70); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newForKind == StatementKind::ForInLoop || newForKind == StatementKind::ForOfLoop"
")"); do { *((volatile int*)__null) = 70; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
70 newForKind == StatementKind::ForOfLoop)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(newForKind == StatementKind::ForInLoop || newForKind
== StatementKind::ForOfLoop)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(newForKind == StatementKind::
ForInLoop || newForKind == StatementKind::ForOfLoop))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("newForKind == StatementKind::ForInLoop || newForKind == StatementKind::ForOfLoop"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 70); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newForKind == StatementKind::ForInLoop || newForKind == StatementKind::ForOfLoop"
")"); do { *((volatile int*)__null) = 70; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
71 kind_ = newForKind;
72 }
73 };
74
75 class LabelStatement : public Statement {
76 TaggedParserAtomIndex label_;
77
78 public:
79 LabelStatement(ParseContext* pc, TaggedParserAtomIndex label)
80 : Statement(pc, StatementKind::Label), label_(label) {}
81
82 TaggedParserAtomIndex label() const { return label_; }
83 };
84
85 struct ClassStatement : public Statement {
86 FunctionBox* constructorBox;
87
88 explicit ClassStatement(ParseContext* pc)
89 : Statement(pc, StatementKind::Class), constructorBox(nullptr) {}
90 };
91
92 // The intra-function scope stack.
93 //
94 // Tracks declared and used names within a scope.
95 class Scope : public Nestable<Scope> {
96 // Names declared in this scope. Corresponds to the union of
97 // VarDeclaredNames and LexicallyDeclaredNames in the ES spec.
98 //
99 // A 'var' declared name is a member of the declared name set of every
100 // scope in its scope contour.
101 //
102 // A lexically declared name is a member only of the declared name set of
103 // the scope in which it is declared.
104 PooledMapPtr<DeclaredNameMap> declared_;
105
106 // FunctionBoxes in this scope that need to be considered for Annex
107 // B.3.3 semantics. This is checked on Scope exit, as by then we have
108 // all the declared names and would know if Annex B.3.3 is applicable.
109 PooledVectorPtr<FunctionBoxVector> possibleAnnexBFunctionBoxes_;
110
111 // Monotonically increasing id.
112 uint32_t id_;
113
114 // Flag for determining if we can apply an optimization to store bindings in
115 // stack slots, which is applied in generator or async functions, or in
116 // async modules.
117 //
118 // This limit is a performance heuristic. Stack slots reduce allocations,
119 // and `Local` opcodes are a bit faster than `AliasedVar` ones; but at each
120 // `yield` or `await` the stack slots must be memcpy'd into a
121 // GeneratorObject. At some point the memcpy is too much. The limit is
122 // plenty for typical human-authored code.
123 enum class GeneratorOrAsyncScopeFlag : uint32_t {
124 // Scope is small enough that bindings can be stored in stack slots.
125 Optimizable = 0,
126
127 // Scope is too big and all bindings should be closed over.
128 TooManyBindings = UINT32_MAX(4294967295U),
129 };
130
131 // Scope size info, relevant for scopes in generators, async functions, and
132 // async modules only.
133 static constexpr uint32_t InnerScopeSlotCountInitialValue = 0;
134 union {
135 // The estimated number of slots needed for nested scopes inside this one.
136 // Calculated while parsing the scope and inner scopes.
137 // Valid only if isOptimizableFlagCalculated_ is false.
138 uint32_t innerScopeSlotCount_ = InnerScopeSlotCountInitialValue;
139
140 // Set when leaving the scope.
141 // Valid only if isOptimizableFlagCalculated_ is true.
142 GeneratorOrAsyncScopeFlag optimizableFlag_;
143 } generatorOrAsyncScopeInfo_;
144
145#ifdef DEBUG1
146 bool isGeneratorOrAsyncScopeInfoUsed_ = false;
147 bool isOptimizableFlagCalculated_ = false;
148#endif
149
150 uint32_t innerScopeSlotCount() {
151 MOZ_ASSERT(!isOptimizableFlagCalculated_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!isOptimizableFlagCalculated_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!isOptimizableFlagCalculated_
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!isOptimizableFlagCalculated_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 151); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!isOptimizableFlagCalculated_"
")"); do { *((volatile int*)__null) = 151; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
152#ifdef DEBUG1
153 isGeneratorOrAsyncScopeInfoUsed_ = true;
154#endif
155 return generatorOrAsyncScopeInfo_.innerScopeSlotCount_;
156 }
157 void setInnerScopeSlotCount(uint32_t slotCount) {
158 MOZ_ASSERT(!isOptimizableFlagCalculated_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!isOptimizableFlagCalculated_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!isOptimizableFlagCalculated_
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!isOptimizableFlagCalculated_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 158); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!isOptimizableFlagCalculated_"
")"); do { *((volatile int*)__null) = 158; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
159 generatorOrAsyncScopeInfo_.innerScopeSlotCount_ = slotCount;
160#ifdef DEBUG1
161 isGeneratorOrAsyncScopeInfoUsed_ = true;
162#endif
163 }
164 void propagateInnerScopeSlotCount(uint32_t slotCount) {
165 if (slotCount > innerScopeSlotCount()) {
166 setInnerScopeSlotCount(slotCount);
167 }
168 }
169
170 void setGeneratorOrAsyncScopeIsOptimizable() {
171 MOZ_ASSERT(!isOptimizableFlagCalculated_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!isOptimizableFlagCalculated_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!isOptimizableFlagCalculated_
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!isOptimizableFlagCalculated_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 171); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!isOptimizableFlagCalculated_"
")"); do { *((volatile int*)__null) = 171; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
172#ifdef DEBUG1
173 isGeneratorOrAsyncScopeInfoUsed_ = true;
174 isOptimizableFlagCalculated_ = true;
175#endif
176 generatorOrAsyncScopeInfo_.optimizableFlag_ =
177 GeneratorOrAsyncScopeFlag::Optimizable;
178 }
179
180 void setGeneratorOrAsyncScopeHasTooManyBindings() {
181 MOZ_ASSERT(!isOptimizableFlagCalculated_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!isOptimizableFlagCalculated_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!isOptimizableFlagCalculated_
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!isOptimizableFlagCalculated_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 181); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!isOptimizableFlagCalculated_"
")"); do { *((volatile int*)__null) = 181; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
182#ifdef DEBUG1
183 isGeneratorOrAsyncScopeInfoUsed_ = true;
184 isOptimizableFlagCalculated_ = true;
185#endif
186 generatorOrAsyncScopeInfo_.optimizableFlag_ =
187 GeneratorOrAsyncScopeFlag::TooManyBindings;
188 }
189
190 bool maybeReportOOM(ParseContext* pc, bool result) {
191 if (!result) {
192 ReportOutOfMemory(pc->sc()->fc_);
193 }
194 return result;
195 }
196
197 public:
198 using DeclaredNamePtr = DeclaredNameMap::Ptr;
199 using AddDeclaredNamePtr = DeclaredNameMap::AddPtr;
200
201 using Nestable<Scope>::enclosing;
202
203 explicit inline Scope(ParserBase* parser);
204 explicit inline Scope(FrontendContext* fc, ParseContext* pc,
205 UsedNameTracker& usedNames);
206
207 void dump(ParseContext* pc, ParserBase* parser);
208
209 uint32_t id() const { return id_; }
210
211 [[nodiscard]] bool init(ParseContext* pc) {
212 if (id_ == UINT32_MAX(4294967295U)) {
213 pc->errorReporter_.errorNoOffset(JSMSG_NEED_DIET, "script");
214 return false;
215 }
216
217 return declared_.acquire(pc->sc()->fc_);
218 }
219
220 bool isEmpty() const { return declared_->all().empty(); }
221
222 uint32_t declaredCount() const {
223 size_t count = declared_->count();
224 MOZ_ASSERT(count <= UINT32_MAX)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(count <= (4294967295U))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(count <= (4294967295U))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("count <= (4294967295U)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 224); AnnotateMozCrashReason("MOZ_ASSERT" "(" "count <= (4294967295U)"
")"); do { *((volatile int*)__null) = 224; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
225 return uint32_t(count);
226 }
227
228 DeclaredNamePtr lookupDeclaredName(TaggedParserAtomIndex name) {
229 return declared_->lookup(name);
230 }
231
232 AddDeclaredNamePtr lookupDeclaredNameForAdd(TaggedParserAtomIndex name) {
233 return declared_->lookupForAdd(name);
234 }
235
236 [[nodiscard]] bool addDeclaredName(ParseContext* pc, AddDeclaredNamePtr& p,
237 TaggedParserAtomIndex name,
238 DeclarationKind kind, uint32_t pos,
239 ClosedOver closedOver = ClosedOver::No) {
240 return maybeReportOOM(
241 pc, declared_->add(p, name, DeclaredNameInfo(kind, pos, closedOver)));
242 }
243
244 // Add a FunctionBox as a possible candidate for Annex B.3.3 semantics.
245 [[nodiscard]] bool addPossibleAnnexBFunctionBox(ParseContext* pc,
246 FunctionBox* funbox);
247
248 // Check if the candidate function boxes for Annex B.3.3 should in
249 // fact get Annex B semantics. Checked on Scope exit.
250 [[nodiscard]] bool propagateAndMarkAnnexBFunctionBoxes(ParseContext* pc,
251 ParserBase* parser);
252
253 // Add and remove catch parameter names. Used to implement the odd
254 // semantics of catch bodies.
255 bool addCatchParameters(ParseContext* pc, Scope& catchParamScope);
256 void removeCatchParameters(ParseContext* pc, Scope& catchParamScope);
257
258 void useAsVarScope(ParseContext* pc) {
259 MOZ_ASSERT(!pc->varScope_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!pc->varScope_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!pc->varScope_))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("!pc->varScope_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 259); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc->varScope_"
")"); do { *((volatile int*)__null) = 259; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
260 pc->varScope_ = this;
261 }
262
263 // Maximum number of fixed stack slots in a generator or async function
264 // script. If a script would have more, we instead store some variables in
265 // heap EnvironmentObjects.
266 //
267 // This limit is a performance heuristic. Stack slots reduce allocations,
268 // and `Local` opcodes are a bit faster than `AliasedVar` ones; but at each
269 // `yield` or `await` the stack slots must be memcpy'd into a
270 // GeneratorObject. At some point the memcpy is too much. The limit is
271 // plenty for typical human-authored code.
272 //
273 // NOTE: This just limits the number of fixed slots, not the entire stack
274 // slots. `yield` and `await` can happen with more slots if there
275 // are many stack values, and the number of values copied to the
276 // generator's stack storage array can be more than the limit.
277 static constexpr uint32_t FixedSlotLimit = 256;
278
279 // This is called as we leave a function, var, or lexical scope in a
280 // generator or async function. `ownSlotCount` is the number of `bindings_`
281 // that are not closed over.
282 void setOwnStackSlotCount(uint32_t ownSlotCount) {
283 uint32_t slotCount = ownSlotCount + innerScopeSlotCount();
284 if (slotCount > FixedSlotLimit) {
285 slotCount = innerScopeSlotCount();
286 setGeneratorOrAsyncScopeHasTooManyBindings();
287 } else {
288 setGeneratorOrAsyncScopeIsOptimizable();
289 }
290
291 // Propagate total size to enclosing scope.
292 if (Scope* parent = enclosing()) {
293 parent->propagateInnerScopeSlotCount(slotCount);
294 }
295 }
296
297 bool tooBigToOptimize() const {
298 // NOTE: This is called also for scopes in non-generator/non-async.
299 // generatorOrAsyncScopeInfo_ is used only from generator or async,
300 // and if it's not used, it holds the initial value, which is the
301 // same value as GeneratorOrAsyncScopeFlag::Optimizable.
302 static_assert(InnerScopeSlotCountInitialValue ==
303 uint32_t(GeneratorOrAsyncScopeFlag::Optimizable));
304 MOZ_ASSERT(!isGeneratorOrAsyncScopeInfoUsed_ ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!isGeneratorOrAsyncScopeInfoUsed_ || isOptimizableFlagCalculated_
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!isGeneratorOrAsyncScopeInfoUsed_ || isOptimizableFlagCalculated_
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!isGeneratorOrAsyncScopeInfoUsed_ || isOptimizableFlagCalculated_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 305); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!isGeneratorOrAsyncScopeInfoUsed_ || isOptimizableFlagCalculated_"
")"); do { *((volatile int*)__null) = 305; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
305 isOptimizableFlagCalculated_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!isGeneratorOrAsyncScopeInfoUsed_ || isOptimizableFlagCalculated_
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(!isGeneratorOrAsyncScopeInfoUsed_ || isOptimizableFlagCalculated_
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!isGeneratorOrAsyncScopeInfoUsed_ || isOptimizableFlagCalculated_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 305); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!isGeneratorOrAsyncScopeInfoUsed_ || isOptimizableFlagCalculated_"
")"); do { *((volatile int*)__null) = 305; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
306 return generatorOrAsyncScopeInfo_.optimizableFlag_ !=
307 GeneratorOrAsyncScopeFlag::Optimizable;
308 }
309
310 // An iterator for the set of names a scope binds: the set of all
311 // declared names for 'var' scopes, and the set of lexically declared
312 // names, plus synthetic names, for non-'var' scopes.
313 class BindingIter {
314 friend class Scope;
315
316 DeclaredNameMap::Range declaredRange_;
317 mozilla::DebugOnly<uint32_t> count_;
318 bool isVarScope_;
319
320 BindingIter(Scope& scope, bool isVarScope)
321 : declaredRange_(scope.declared_->all()),
322 count_(0),
323 isVarScope_(isVarScope) {
324 settle();
325 }
326
327 bool isLexicallyDeclared() {
328 return BindingKindIsLexical(kind()) ||
329 kind() == BindingKind::Synthetic ||
330 kind() == BindingKind::PrivateMethod;
331 }
332
333 void settle() {
334 // Both var and lexically declared names are binding in a var
335 // scope.
336 if (isVarScope_) {
337 return;
338 }
339
340 // Otherwise, only lexically declared names are binding. Pop the range
341 // until we find such a name.
342 while (!declaredRange_.empty()) {
343 if (isLexicallyDeclared()) {
344 break;
345 }
346 declaredRange_.popFront();
347 }
348 }
349
350 public:
351 bool done() const { return declaredRange_.empty(); }
352
353 explicit operator bool() const { return !done(); }
354
355 TaggedParserAtomIndex name() {
356 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/frontend/ParseContext.h"
, 356); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 356; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
357 return declaredRange_.front().key();
358 }
359
360 DeclarationKind declarationKind() {
361 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/frontend/ParseContext.h"
, 361); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 361; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
362 return declaredRange_.front().value()->kind();
363 }
364
365 BindingKind kind() {
366 return DeclarationKindToBindingKind(declarationKind());
367 }
368
369 bool closedOver() {
370 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/frontend/ParseContext.h"
, 370); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 370; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
371 return declaredRange_.front().value()->closedOver();
372 }
373
374 void setClosedOver() {
375 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/frontend/ParseContext.h"
, 375); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 375; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
376 return declaredRange_.front().value()->setClosedOver();
377 }
378
379 void operator++(int) {
380 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/frontend/ParseContext.h"
, 380); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!done()" ")"
); do { *((volatile int*)__null) = 380; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
381 MOZ_ASSERT(count_ != UINT32_MAX)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(count_ != (4294967295U))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(count_ != (4294967295U)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("count_ != (4294967295U)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "count_ != (4294967295U)"
")"); do { *((volatile int*)__null) = 381; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
382 declaredRange_.popFront();
383 settle();
384 }
385 };
386
387 inline BindingIter bindings(ParseContext* pc);
388 };
389
390 class VarScope : public Scope {
391 public:
392 explicit inline VarScope(ParserBase* parser);
393 explicit inline VarScope(FrontendContext* fc, ParseContext* pc,
394 UsedNameTracker& usedNames);
395 };
396
397 private:
398 // Context shared between parsing and bytecode generation.
399 SharedContext* sc_;
400
401 // A mechanism used for error reporting.
402 ErrorReporter& errorReporter_;
403
404 // The innermost statement, i.e., top of the statement stack.
405 Statement* innermostStatement_;
406
407 // The innermost scope, i.e., top of the scope stack.
408 //
409 // The outermost scope in the stack is usually varScope_. In the case of
410 // functions, the outermost scope is functionScope_, which may be
411 // varScope_. See comment above functionScope_.
412 Scope* innermostScope_;
413
414 // If isFunctionBox() and the function is a named lambda, the DeclEnv
415 // scope for named lambdas.
416 mozilla::Maybe<Scope> namedLambdaScope_;
417
418 // If isFunctionBox(), the scope for the function. If there are no
419 // parameter expressions, this is scope for the entire function. If there
420 // are parameter expressions, this holds the special function names
421 // ('.this', 'arguments') and the formal parameters.
422 mozilla::Maybe<Scope> functionScope_;
423
424 // The body-level scope. This always exists, but not necessarily at the
425 // beginning of parsing the script in the case of functions with parameter
426 // expressions.
427 Scope* varScope_;
428
429 // Simple formal parameter names, in order of appearance. Only used when
430 // isFunctionBox().
431 PooledVectorPtr<AtomVector> positionalFormalParameterNames_;
432
433 // Closed over binding names, in order of appearance. Null-delimited
434 // between scopes. Only used when syntax parsing.
435 PooledVectorPtr<AtomVector> closedOverBindingsForLazy_;
436
437 public:
438 // All inner functions in this context. Only used when syntax parsing.
439 // The Functions (or FunctionCreateionDatas) are traced as part of the
440 // CompilationStencil function vector.
441 Vector<ScriptIndex, 4> innerFunctionIndexesForLazy;
442
443 // In a function context, points to a Directive struct that can be updated
444 // to reflect new directives encountered in the Directive Prologue that
445 // require reparsing the function. In global/module/generator-tail contexts,
446 // we don't need to reparse when encountering a DirectivePrologue so this
447 // pointer may be nullptr.
448 Directives* newDirectives;
449
450 // lastYieldOffset stores the offset of the last yield that was parsed.
451 // NoYieldOffset is its initial value.
452 static const uint32_t NoYieldOffset = UINT32_MAX(4294967295U);
453 uint32_t lastYieldOffset;
454
455 // lastAwaitOffset stores the offset of the last await that was parsed.
456 // NoAwaitOffset is its initial value.
457 static const uint32_t NoAwaitOffset = UINT32_MAX(4294967295U);
458 uint32_t lastAwaitOffset;
459
460 private:
461 // Monotonically increasing id.
462 uint32_t scriptId_;
463
464 // Set when encountering a super.property inside a method. We need to mark
465 // the nearest super scope as needing a home object.
466 bool superScopeNeedsHomeObject_;
467
468 public:
469 ParseContext(FrontendContext* fc, ParseContext*& parent, SharedContext* sc,
470 ErrorReporter& errorReporter, CompilationState& compilationState,
471 Directives* newDirectives, bool isFull);
472
473 [[nodiscard]] bool init();
474
475 SharedContext* sc() { return sc_; }
476
477 // `true` if we are in the body of a function definition.
478 bool isFunctionBox() const { return sc_->isFunctionBox(); }
479
480 FunctionBox* functionBox() { return sc_->asFunctionBox(); }
481
482 Statement* innermostStatement() { return innermostStatement_; }
483
484 Scope* innermostScope() {
485 // There is always at least one scope: the 'var' scope.
486 MOZ_ASSERT(innermostScope_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(innermostScope_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(innermostScope_))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("innermostScope_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 486); AnnotateMozCrashReason("MOZ_ASSERT" "(" "innermostScope_"
")"); do { *((volatile int*)__null) = 486; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
487 return innermostScope_;
488 }
489
490 Scope& namedLambdaScope() {
491 MOZ_ASSERT(functionBox()->isNamedLambda())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(functionBox()->isNamedLambda())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(functionBox()->isNamedLambda
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("functionBox()->isNamedLambda()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "functionBox()->isNamedLambda()"
")"); do { *((volatile int*)__null) = 491; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
492 return *namedLambdaScope_;
493 }
494
495 Scope& functionScope() {
496 MOZ_ASSERT(isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isFunctionBox()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isFunctionBox()"
")"); do { *((volatile int*)__null) = 496; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
497 return *functionScope_;
498 }
499
500 Scope& varScope() {
501 MOZ_ASSERT(varScope_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(varScope_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(varScope_))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("varScope_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 501); AnnotateMozCrashReason("MOZ_ASSERT" "(" "varScope_" ")"
); do { *((volatile int*)__null) = 501; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
502 return *varScope_;
503 }
504
505 bool isFunctionExtraBodyVarScopeInnermost() {
506 return isFunctionBox() && functionBox()->hasParameterExprs &&
507 innermostScope() == varScope_;
508 }
509
510 template <typename Predicate /* (Statement*) -> bool */>
511 Statement* findInnermostStatement(Predicate predicate) {
512 return Statement::findNearest(innermostStatement_, predicate);
513 }
514
515 template <typename T, typename Predicate /* (Statement*) -> bool */>
516 T* findInnermostStatement(Predicate predicate) {
517 return Statement::findNearest<T>(innermostStatement_, predicate);
518 }
519
520 template <typename T>
521 T* findInnermostStatement() {
522 return Statement::findNearest<T>(innermostStatement_);
523 }
524
525 AtomVector& positionalFormalParameterNames() {
526 return *positionalFormalParameterNames_;
527 }
528
529 AtomVector& closedOverBindingsForLazy() {
530 return *closedOverBindingsForLazy_;
531 }
532
533 enum class BreakStatementError : uint8_t {
534 // Unlabeled break must be inside loop or switch.
535 ToughBreak,
536 LabelNotFound,
537 };
538
539 // Return Err(true) if we have encountered at least one loop,
540 // Err(false) otherwise.
541 [[nodiscard]] inline JS::Result<Ok, BreakStatementError> checkBreakStatement(
542 TaggedParserAtomIndex label);
543
544 enum class ContinueStatementError : uint8_t {
545 NotInALoop,
546 LabelNotFound,
547 };
548 [[nodiscard]] inline JS::Result<Ok, ContinueStatementError>
549 checkContinueStatement(TaggedParserAtomIndex label);
550
551 // True if we are at the topmost level of a entire script or function body.
552 // For example, while parsing this code we would encounter f1 and f2 at
553 // body level, but we would not encounter f3 or f4 at body level:
554 //
555 // function f1() { function f2() { } }
556 // if (cond) { function f3() { if (cond) { function f4() { } } } }
557 //
558 bool atBodyLevel() { return !innermostStatement_; }
559
560 bool atGlobalLevel() { return atBodyLevel() && sc_->isGlobalContext(); }
561
562 // True if we are at the topmost level of a module only.
563 bool atModuleLevel() { return atBodyLevel() && sc_->isModuleContext(); }
564
565 // True if we are at the topmost level of an entire script or module. For
566 // example, in the comment on |atBodyLevel()| above, we would encounter |f1|
567 // and the outermost |if (cond)| at top level, and everything else would not
568 // be at top level.
569 bool atTopLevel() { return atBodyLevel() && sc_->isTopLevelContext(); }
570
571 bool atModuleTopLevel() {
572 // True if we are at the topmost level of an entire module.
573 //
574 // For example, this is used to determine if an await statement should
575 // mark a module as an async module during parsing.
576 //
577 // Example module:
578 // import x from "y";
579 //
580 // await x.foo(); // mark as Top level await.
581 //
582 // if (cond) {
583 // await x.bar(); // mark as Top level await.
584 // }
585 //
586 // async function z() {
587 // await x.baz(); // do not mark as Top level await.
588 // }
589 return sc_->isModuleContext() && sc_->isTopLevelContext();
590 }
591
592 // True if this is the outermost ParserContext for current compile. For
593 // delazification, this lets us identify if the lazy PrivateScriptData is for
594 // current parser context.
595 bool isOutermostOfCurrentCompile() const {
596 MOZ_ASSERT(!!enclosing() == !!scriptId())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!!enclosing() == !!scriptId())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!!enclosing() == !!scriptId(
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!!enclosing() == !!scriptId()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!!enclosing() == !!scriptId()"
")"); do { *((volatile int*)__null) = 596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
597 return (scriptId() == 0);
598 }
599
600#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
601 bool isUsingSyntaxAllowed() { return !atGlobalLevel() || atModuleTopLevel(); }
602#endif
603
604 void setSuperScopeNeedsHomeObject() {
605 MOZ_ASSERT(sc_->allowSuperProperty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(sc_->allowSuperProperty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(sc_->allowSuperProperty()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"sc_->allowSuperProperty()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/ParseContext.h"
, 605); AnnotateMozCrashReason("MOZ_ASSERT" "(" "sc_->allowSuperProperty()"
")"); do { *((volatile int*)__null) = 605; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
606 superScopeNeedsHomeObject_ = true;
607 }
608
609 bool superScopeNeedsHomeObject() const { return superScopeNeedsHomeObject_; }
610
611 bool useAsmOrInsideUseAsm() const {
612 return sc_->isFunctionBox() && sc_->asFunctionBox()->useAsmOrInsideUseAsm();
613 }
614
615 // A generator is marked as a generator before its body is parsed.
616 GeneratorKind generatorKind() const {
617 return sc_->isFunctionBox() ? sc_->asFunctionBox()->generatorKind()
618 : GeneratorKind::NotGenerator;
619 }
620
621 bool isGenerator() const {
622 return generatorKind() == GeneratorKind::Generator;
623 }
624
625 bool isAsync() const {
626 return sc_->isSuspendableContext() &&
627 sc_->asSuspendableContext()->isAsync();
628 }
629
630 bool isGeneratorOrAsync() const { return isGenerator() || isAsync(); }
631
632 bool needsDotGeneratorName() const { return isGeneratorOrAsync(); }
633
634 FunctionAsyncKind asyncKind() const {
635 return isAsync() ? FunctionAsyncKind::AsyncFunction
636 : FunctionAsyncKind::SyncFunction;
637 }
638
639 bool isArrowFunction() const {
640 return sc_->isFunctionBox() && sc_->asFunctionBox()->isArrow();
641 }
642
643 bool isMethod() const {
644 return sc_->isFunctionBox() && sc_->asFunctionBox()->isMethod();
645 }
646
647 bool isGetterOrSetter() const {
648 return sc_->isFunctionBox() && (sc_->asFunctionBox()->isGetter() ||
649 sc_->asFunctionBox()->isSetter());
650 }
651
652 bool allowReturn() const {
653 return sc_->isFunctionBox() && sc_->asFunctionBox()->allowReturn();
654 }
655
656 uint32_t scriptId() const { return scriptId_; }
657
658 bool computeAnnexBAppliesToLexicalFunctionInInnermostScope(
659 FunctionBox* funbox, ParserBase* parser, bool* annexBApplies);
660
661 bool tryDeclareVar(TaggedParserAtomIndex name, ParserBase* parser,
662 DeclarationKind kind, uint32_t beginPos,
663 mozilla::Maybe<DeclarationKind>* redeclaredKind,
664 uint32_t* prevPos);
665
666 bool hasUsedName(const UsedNameTracker& usedNames,
667 TaggedParserAtomIndex name);
668 bool hasClosedOverName(const UsedNameTracker& usedNames,
669 TaggedParserAtomIndex name);
670 bool hasUsedFunctionSpecialName(const UsedNameTracker& usedNames,
671 TaggedParserAtomIndex name);
672 bool hasClosedOverFunctionSpecialName(const UsedNameTracker& usedNames,
673 TaggedParserAtomIndex name);
674
675 bool declareFunctionThis(const UsedNameTracker& usedNames,
676 bool canSkipLazyClosedOverBindings);
677 bool declareFunctionArgumentsObject(const UsedNameTracker& usedNames,
678 bool canSkipLazyClosedOverBindings);
679 bool declareNewTarget(const UsedNameTracker& usedNames,
680 bool canSkipLazyClosedOverBindings);
681 bool declareDotGeneratorName();
682 bool declareTopLevelDotGeneratorName();
683
684 // Used to determine if we have non-length uses of the arguments binding.
685 // This works by incrementing this counter each time we encounter the
686 // arguments name, and decrementing each time it is combined into
687 // arguments.length; as a result, if this is non-zero at the end of parsing,
688 // we have identified a non-length use of the arguments binding.
689 size_t numberOfArgumentsNames = 0;
690
691 private:
692 [[nodiscard]] bool isVarRedeclaredInInnermostScope(
693 TaggedParserAtomIndex name, ParserBase* parser, DeclarationKind kind,
694 mozilla::Maybe<DeclarationKind>* out);
695
696 [[nodiscard]] bool isVarRedeclaredInEval(
697 TaggedParserAtomIndex name, ParserBase* parser, DeclarationKind kind,
698 mozilla::Maybe<DeclarationKind>* out);
699
700 enum DryRunOption { NotDryRun, DryRunInnermostScopeOnly };
701 template <DryRunOption dryRunOption>
702 bool tryDeclareVarHelper(TaggedParserAtomIndex name, ParserBase* parser,
703 DeclarationKind kind, uint32_t beginPos,
704 mozilla::Maybe<DeclarationKind>* redeclaredKind,
705 uint32_t* prevPos);
706};
707
708} // namespace frontend
709
710} // namespace js
711
712#endif // frontend_ParseContext_h

/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.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 frontend_NameCollections_h
8#define frontend_NameCollections_h
9
10#include "mozilla/Assertions.h" // MOZ_ASSERT
11#include "mozilla/Attributes.h" // MOZ_IMPLICIT
12
13#include <stddef.h> // size_t
14#include <stdint.h> // uint32_t, uint64_t
15#include <type_traits> // std::{true_type, false_type, is_trivial_v, is_trivially_copyable_v, is_trivially_destructible_v}
16#include <utility> // std::forward
17
18#include "ds/InlineTable.h" // InlineMap, DefaultKeyPolicy
19#include "frontend/NameAnalysisTypes.h" // AtomVector, FunctionBoxVector
20#include "frontend/ParserAtom.h" // TaggedParserAtomIndex, TrivialTaggedParserAtomIndex
21#include "frontend/TaggedParserAtomIndexHasher.h" // TrivialTaggedParserAtomIndexHasher
22#include "js/AllocPolicy.h" // SystemAllocPolicy, ReportOutOfMemory
23#include "js/Utility.h" // js_new, js_delete
24#include "js/Vector.h" // Vector
25
26namespace js::frontend {
27
28class FunctionBox;
29
30// A pool of recyclable containers for use in the frontend. The Parser and
31// BytecodeEmitter create many maps for name analysis that are short-lived
32// (i.e., for the duration of parsing or emitting a lexical scope). Making
33// them recyclable cuts down significantly on allocator churn.
34template <typename RepresentativeCollection, typename ConcreteCollectionPool>
35class CollectionPool {
36 using RecyclableCollections = Vector<void*, 32, SystemAllocPolicy>;
37
38 RecyclableCollections all_;
39 RecyclableCollections recyclable_;
40
41 static RepresentativeCollection* asRepresentative(void* p) {
42 return reinterpret_cast<RepresentativeCollection*>(p);
43 }
44
45 RepresentativeCollection* allocate() {
46 size_t newAllLength = all_.length() + 1;
47 if (!all_.reserve(newAllLength) || !recyclable_.reserve(newAllLength)) {
48 return nullptr;
49 }
50
51 RepresentativeCollection* collection = js_new<RepresentativeCollection>();
52 if (collection) {
53 all_.infallibleAppend(collection);
54 }
55 return collection;
56 }
57
58 public:
59 ~CollectionPool() { purgeAll(); }
60
61 void purgeAll() {
62 void** end = all_.end();
63 for (void** it = all_.begin(); it != end; ++it) {
64 js_delete(asRepresentative(*it));
65 }
66
67 all_.clearAndFree();
68 recyclable_.clearAndFree();
69 }
70
71 // Fallibly aquire one of the supported collection types from the pool.
72 template <typename Collection>
73 Collection* acquire(FrontendContext* fc) {
74 ConcreteCollectionPool::template assertInvariants<Collection>();
75
76 RepresentativeCollection* collection;
77 if (recyclable_.empty()) {
78 collection = allocate();
79 if (!collection) {
80 ReportOutOfMemory(fc);
81 }
82 } else {
83 collection = asRepresentative(recyclable_.popCopy());
84 collection->clear();
85 }
86 return reinterpret_cast<Collection*>(collection);
87 }
88
89 // Release a collection back to the pool.
90 template <typename Collection>
91 void release(Collection** collection) {
92 ConcreteCollectionPool::template assertInvariants<Collection>();
93 MOZ_ASSERT(*collection)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(*collection)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*collection))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("*collection", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 93); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*collection" ")"
); do { *((volatile int*)__null) = 93; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
94
95#ifdef DEBUG1
96 bool ok = false;
97 // Make sure the collection is in |all_| but not already in |recyclable_|.
98 for (void** it = all_.begin(); it != all_.end(); ++it) {
99 if (*it == *collection) {
100 ok = true;
101 break;
102 }
103 }
104 MOZ_ASSERT(ok)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ok)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(ok))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("ok", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 104); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ok" ")"); do
{ *((volatile int*)__null) = 104; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
105 for (void** it = recyclable_.begin(); it != recyclable_.end(); ++it) {
106 MOZ_ASSERT(*it != *collection)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(*it != *collection)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*it != *collection))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("*it != *collection"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 106); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*it != *collection"
")"); do { *((volatile int*)__null) = 106; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
107 }
108#endif
109
110 MOZ_ASSERT(recyclable_.length() < all_.length())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(recyclable_.length() < all_.length())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(recyclable_.length() < all_.length()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("recyclable_.length() < all_.length()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 110); AnnotateMozCrashReason("MOZ_ASSERT" "(" "recyclable_.length() < all_.length()"
")"); do { *((volatile int*)__null) = 110; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
111 // Reserved in allocateFresh.
112 recyclable_.infallibleAppend(*collection);
113 *collection = nullptr;
114 }
115};
116
117template <typename Wrapped>
118struct RecyclableAtomMapValueWrapper {
119 using WrappedType = Wrapped;
120
121 union {
122 Wrapped wrapped;
123 uint64_t dummy;
124 };
125
126 static void assertInvariant() {
127 static_assert(sizeof(Wrapped) <= sizeof(uint64_t),
128 "Can only recycle atom maps with values smaller than uint64");
129 }
130
131 RecyclableAtomMapValueWrapper() : dummy(0) { assertInvariant(); }
132
133 MOZ_IMPLICIT RecyclableAtomMapValueWrapper(Wrapped w) : wrapped(w) {
134 assertInvariant();
135 }
136
137 MOZ_IMPLICIT operator Wrapped&() { return wrapped; }
138
139 MOZ_IMPLICIT operator Wrapped&() const { return wrapped; }
140
141 Wrapped* operator->() { return &wrapped; }
142
143 const Wrapped* operator->() const { return &wrapped; }
144};
145
146template <typename MapValue>
147using RecyclableNameMapBase =
148 InlineMap<TrivialTaggedParserAtomIndex,
149 RecyclableAtomMapValueWrapper<MapValue>, 24,
150 TrivialTaggedParserAtomIndexHasher, SystemAllocPolicy>;
151
152// Define wrapper methods to accept TaggedParserAtomIndex.
153template <typename MapValue>
154class RecyclableNameMap : public RecyclableNameMapBase<MapValue> {
155 using Base = RecyclableNameMapBase<MapValue>;
156
157 public:
158 template <typename... Args>
159 [[nodiscard]] MOZ_ALWAYS_INLINEinline bool add(typename Base::AddPtr& p,
160 const TaggedParserAtomIndex& key,
161 Args&&... args) {
162 return Base::add(p, TrivialTaggedParserAtomIndex::from(key),
163 std::forward<Args>(args)...);
164 }
165
166 MOZ_ALWAYS_INLINEinline
167 typename Base::Ptr lookup(const TaggedParserAtomIndex& l) {
168 return Base::lookup(TrivialTaggedParserAtomIndex::from(l));
169 }
170
171 MOZ_ALWAYS_INLINEinline
172 typename Base::AddPtr lookupForAdd(const TaggedParserAtomIndex& l) {
173 return Base::lookupForAdd(TrivialTaggedParserAtomIndex::from(l));
174 }
175};
176
177using DeclaredNameMap = RecyclableNameMap<DeclaredNameInfo>;
178using NameLocationMap = RecyclableNameMap<NameLocation>;
179// Cannot use GCThingIndex here because it's not trivial type.
180using AtomIndexMap = RecyclableNameMap<uint32_t>;
181
182template <typename RepresentativeTable>
183class InlineTablePool
184 : public CollectionPool<RepresentativeTable,
185 InlineTablePool<RepresentativeTable>> {
186 template <typename>
187 struct IsRecyclableAtomMapValueWrapper : std::false_type {};
188
189 template <typename T>
190 struct IsRecyclableAtomMapValueWrapper<RecyclableAtomMapValueWrapper<T>>
191 : std::true_type {};
192
193 public:
194 template <typename Table>
195 static void assertInvariants() {
196 static_assert(
197 Table::SizeOfInlineEntries == RepresentativeTable::SizeOfInlineEntries,
198 "Only tables with the same size for inline entries are usable in the "
199 "pool.");
200
201 using EntryType = typename Table::Table::Entry;
202 using KeyType = typename EntryType::KeyType;
203 using ValueType = typename EntryType::ValueType;
204
205 static_assert(IsRecyclableAtomMapValueWrapper<ValueType>::value,
206 "Please adjust the static assertions below if you need to "
207 "support other types than RecyclableAtomMapValueWrapper");
208
209 using WrappedType = typename ValueType::WrappedType;
210
211 // We can't directly check |std::is_trivial<EntryType>|, because neither
212 // mozilla::HashMapEntry nor IsRecyclableAtomMapValueWrapper are trivially
213 // default constructible. Instead we check that the key and the unwrapped
214 // value are trivial and additionally ensure that the entry itself is
215 // trivially copyable and destructible.
216
217 static_assert(std::is_trivial_v<KeyType>,
218 "Only tables with trivial keys are usable in the pool.");
219 static_assert(std::is_trivial_v<WrappedType>,
220 "Only tables with trivial values are usable in the pool.");
221
222 static_assert(
223 std::is_trivially_copyable_v<EntryType>,
224 "Only tables with trivially copyable entries are usable in the pool.");
225 static_assert(std::is_trivially_destructible_v<EntryType>,
226 "Only tables with trivially destructible entries are usable "
227 "in the pool.");
228 }
229};
230
231template <typename RepresentativeVector>
232class VectorPool : public CollectionPool<RepresentativeVector,
233 VectorPool<RepresentativeVector>> {
234 public:
235 template <typename Vector>
236 static void assertInvariants() {
237 static_assert(
238 Vector::sMaxInlineStorage == RepresentativeVector::sMaxInlineStorage,
239 "Only vectors with the same size for inline entries are usable in the "
240 "pool.");
241
242 using ElementType = typename Vector::ElementType;
243
244 static_assert(std::is_trivial_v<ElementType>,
245 "Only vectors of trivial values are usable in the pool.");
246 static_assert(std::is_trivially_destructible_v<ElementType>,
247 "Only vectors of trivially destructible values are usable in "
248 "the pool.");
249
250 static_assert(
251 sizeof(ElementType) ==
252 sizeof(typename RepresentativeVector::ElementType),
253 "Only vectors with same-sized elements are usable in the pool.");
254 }
255};
256
257using AtomVector = Vector<TrivialTaggedParserAtomIndex, 24, SystemAllocPolicy>;
258
259using FunctionBoxVector = Vector<FunctionBox*, 24, SystemAllocPolicy>;
260
261class NameCollectionPool {
262 InlineTablePool<AtomIndexMap> mapPool_;
263 VectorPool<AtomVector> atomVectorPool_;
264 VectorPool<FunctionBoxVector> functionBoxVectorPool_;
265 uint32_t activeCompilations_;
266
267 public:
268 NameCollectionPool() : activeCompilations_(0) {}
269
270 bool hasActiveCompilation() const { return activeCompilations_ != 0; }
271
272 void addActiveCompilation() { activeCompilations_++; }
273
274 void removeActiveCompilation() {
275 MOZ_ASSERT(hasActiveCompilation())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasActiveCompilation())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasActiveCompilation()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("hasActiveCompilation()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 275); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasActiveCompilation()"
")"); do { *((volatile int*)__null) = 275; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
276 activeCompilations_--;
277 }
278
279 template <typename Map>
280 Map* acquireMap(FrontendContext* fc) {
281 MOZ_ASSERT(hasActiveCompilation())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasActiveCompilation())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasActiveCompilation()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("hasActiveCompilation()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 281); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasActiveCompilation()"
")"); do { *((volatile int*)__null) = 281; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
282 return mapPool_.acquire<Map>(fc);
283 }
284
285 template <typename Map>
286 void releaseMap(Map** map) {
287 MOZ_ASSERT(hasActiveCompilation())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasActiveCompilation())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasActiveCompilation()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("hasActiveCompilation()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 287); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasActiveCompilation()"
")"); do { *((volatile int*)__null) = 287; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
288 MOZ_ASSERT(map)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(map)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(map))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("map", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 288); AnnotateMozCrashReason("MOZ_ASSERT" "(" "map" ")"); do
{ *((volatile int*)__null) = 288; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
289 if (*map) {
290 mapPool_.release(map);
291 }
292 }
293
294 template <typename Vector>
295 inline Vector* acquireVector(FrontendContext* fc);
296
297 template <typename Vector>
298 inline void releaseVector(Vector** vec);
299
300 void purge() {
301 if (!hasActiveCompilation()) {
302 mapPool_.purgeAll();
303 atomVectorPool_.purgeAll();
304 functionBoxVectorPool_.purgeAll();
305 }
306 }
307};
308
309template <>
310inline AtomVector* NameCollectionPool::acquireVector<AtomVector>(
311 FrontendContext* fc) {
312 MOZ_ASSERT(hasActiveCompilation())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasActiveCompilation())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasActiveCompilation()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("hasActiveCompilation()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 312); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasActiveCompilation()"
")"); do { *((volatile int*)__null) = 312; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
313 return atomVectorPool_.acquire<AtomVector>(fc);
314}
315
316template <>
317inline void NameCollectionPool::releaseVector<AtomVector>(AtomVector** vec) {
318 MOZ_ASSERT(hasActiveCompilation())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasActiveCompilation())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasActiveCompilation()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("hasActiveCompilation()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 318); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasActiveCompilation()"
")"); do { *((volatile int*)__null) = 318; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
319 MOZ_ASSERT(vec)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(vec)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(vec))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("vec", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 319); AnnotateMozCrashReason("MOZ_ASSERT" "(" "vec" ")"); do
{ *((volatile int*)__null) = 319; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
320 if (*vec) {
321 atomVectorPool_.release(vec);
322 }
323}
324
325template <>
326inline FunctionBoxVector* NameCollectionPool::acquireVector<FunctionBoxVector>(
327 FrontendContext* fc) {
328 MOZ_ASSERT(hasActiveCompilation())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasActiveCompilation())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasActiveCompilation()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("hasActiveCompilation()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 328); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasActiveCompilation()"
")"); do { *((volatile int*)__null) = 328; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
329 return functionBoxVectorPool_.acquire<FunctionBoxVector>(fc);
330}
331
332template <>
333inline void NameCollectionPool::releaseVector<FunctionBoxVector>(
334 FunctionBoxVector** vec) {
335 MOZ_ASSERT(hasActiveCompilation())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hasActiveCompilation())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hasActiveCompilation()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("hasActiveCompilation()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 335); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hasActiveCompilation()"
")"); do { *((volatile int*)__null) = 335; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
336 MOZ_ASSERT(vec)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(vec)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(vec))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("vec", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 336); AnnotateMozCrashReason("MOZ_ASSERT" "(" "vec" ")"); do
{ *((volatile int*)__null) = 336; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
337 if (*vec) {
338 functionBoxVectorPool_.release(vec);
339 }
340}
341
342template <typename T, template <typename> typename Impl>
343class PooledCollectionPtr {
344 NameCollectionPool& pool_;
345 T* collection_ = nullptr;
346
347 protected:
348 ~PooledCollectionPtr() { Impl<T>::releaseCollection(pool_, &collection_); }
24
1st function call argument is an uninitialized value
349
350 T& collection() {
351 MOZ_ASSERT(collection_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(collection_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(collection_))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("collection_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 351); AnnotateMozCrashReason("MOZ_ASSERT" "(" "collection_"
")"); do { *((volatile int*)__null) = 351; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
352 return *collection_;
353 }
354
355 const T& collection() const {
356 MOZ_ASSERT(collection_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(collection_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(collection_))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("collection_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 356); AnnotateMozCrashReason("MOZ_ASSERT" "(" "collection_"
")"); do { *((volatile int*)__null) = 356; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
357 return *collection_;
358 }
359
360 public:
361 explicit PooledCollectionPtr(NameCollectionPool& pool) : pool_(pool) {}
362
363 bool acquire(FrontendContext* fc) {
364 MOZ_ASSERT(!collection_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!collection_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!collection_))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!collection_", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h"
, 364); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!collection_"
")"); do { *((volatile int*)__null) = 364; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
365 collection_ = Impl<T>::acquireCollection(fc, pool_);
366 return !!collection_;
367 }
368
369 explicit operator bool() const { return !!collection_; }
370
371 T* operator->() { return &collection(); }
372
373 const T* operator->() const { return &collection(); }
374
375 T& operator*() { return collection(); }
376
377 const T& operator*() const { return collection(); }
378};
379
380template <typename Map>
381class PooledMapPtr : public PooledCollectionPtr<Map, PooledMapPtr> {
382 friend class PooledCollectionPtr<Map, PooledMapPtr>;
383
384 static Map* acquireCollection(FrontendContext* fc, NameCollectionPool& pool) {
385 return pool.acquireMap<Map>(fc);
386 }
387
388 static void releaseCollection(NameCollectionPool& pool, Map** ptr) {
389 pool.releaseMap(ptr);
390 }
391
392 using Base = PooledCollectionPtr<Map, PooledMapPtr>;
393
394 public:
395 using Base::Base;
396
397 ~PooledMapPtr() = default;
398};
399
400template <typename Vector>
401class PooledVectorPtr : public PooledCollectionPtr<Vector, PooledVectorPtr> {
402 friend class PooledCollectionPtr<Vector, PooledVectorPtr>;
403
404 static Vector* acquireCollection(FrontendContext* fc,
405 NameCollectionPool& pool) {
406 return pool.acquireVector<Vector>(fc);
407 }
408
409 static void releaseCollection(NameCollectionPool& pool, Vector** ptr) {
410 pool.releaseVector(ptr);
411 }
412
413 using Base = PooledCollectionPtr<Vector, PooledVectorPtr>;
414 using Base::collection;
415
416 public:
417 using Base::Base;
418
419 ~PooledVectorPtr() = default;
23
Calling '~PooledCollectionPtr'
420
421 typename Vector::ElementType& operator[](size_t index) {
422 return collection()[index];
423 }
424
425 const typename Vector::ElementType& operator[](size_t index) const {
426 return collection()[index];
427 }
428};
429
430} // namespace js::frontend
431
432#endif // frontend_NameCollections_h