Bug Summary

File:var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/NameCollections.h
Warning:line 370, 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-18/lib/clang/18 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D DEBUG=1 -D WASM_SUPPORTS_HUGE_MEMORY -D JS_CACHEIR_SPEW -D JS_STRUCTURED_SPEW -D JS_HAS_CTYPES -D FFI_BUILDING -D EXPORT_JS_API -D MOZ_HAS_MOZGLUE -D MOZ_SUPPORT_LEAKCHECKING -I /var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src/frontend -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src -I /var/lib/jenkins/workspace/firefox-scan-build/js/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-07-27-022226-2793976-1 -x c++ /var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp

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

1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7/*
8 * JS parser.
9 *
10 * This is a recursive-descent parser for the JavaScript language specified by
11 * "The ECMAScript Language Specification" (Standard ECMA-262). It uses
12 * lexical and semantic feedback to disambiguate non-LL(1) structures. It
13 * generates trees of nodes induced by the recursive parsing (not precise
14 * syntax trees, see Parser.h). After tree construction, it rewrites trees to
15 * fold constants and evaluate compile-time expressions.
16 *
17 * This parser attempts no error recovery.
18 */
19
20#include "frontend/Parser.h"
21
22#include "mozilla/ArrayUtils.h"
23#include "mozilla/Assertions.h"
24#include "mozilla/Casting.h"
25#include "mozilla/Range.h"
26#include "mozilla/Sprintf.h"
27#include "mozilla/Try.h" // MOZ_TRY*
28#include "mozilla/Utf8.h"
29#include "mozilla/Variant.h"
30
31#include <memory>
32#include <new>
33#include <type_traits>
34
35#include "jsnum.h"
36#include "jstypes.h"
37
38#include "frontend/FoldConstants.h"
39#include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind
40#include "frontend/ModuleSharedContext.h"
41#include "frontend/ParseNode.h"
42#include "frontend/ParseNodeVerify.h"
43#include "frontend/Parser-macros.h" // MOZ_TRY_VAR_OR_RETURN
44#include "frontend/ParserAtom.h" // TaggedParserAtomIndex, ParserAtomsTable, ParserAtom
45#include "frontend/ScriptIndex.h" // ScriptIndex
46#include "frontend/TokenStream.h" // IsKeyword, ReservedWordTokenKind, ReservedWordToCharZ, DeprecatedContent, *TokenStream*, CharBuffer, TokenKindToDesc
47#include "irregexp/RegExpAPI.h"
48#include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin, JS::ColumnNumberOneOrigin
49#include "js/ErrorReport.h" // JSErrorBase
50#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
51#include "js/HashTable.h"
52#include "js/RegExpFlags.h" // JS::RegExpFlags
53#include "js/Stack.h" // JS::NativeStackLimit
54#include "util/StringBuffer.h" // StringBuffer
55#include "vm/BytecodeUtil.h"
56#include "vm/FunctionFlags.h" // js::FunctionFlags
57#include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind
58#include "vm/JSContext.h"
59#include "vm/JSScript.h"
60#include "vm/ModuleBuilder.h" // js::ModuleBuilder
61#include "vm/Scope.h" // GetScopeDataTrailingNames
62#include "wasm/AsmJS.h"
63
64#include "frontend/ParseContext-inl.h"
65#include "frontend/SharedContext-inl.h"
66
67using namespace js;
68
69using mozilla::AssertedCast;
70using mozilla::AsVariant;
71using mozilla::Maybe;
72using mozilla::Nothing;
73using mozilla::PointerRangeSize;
74using mozilla::Some;
75using mozilla::Utf8Unit;
76
77using JS::ReadOnlyCompileOptions;
78using JS::RegExpFlags;
79
80namespace js::frontend {
81
82using DeclaredNamePtr = ParseContext::Scope::DeclaredNamePtr;
83using AddDeclaredNamePtr = ParseContext::Scope::AddDeclaredNamePtr;
84using BindingIter = ParseContext::Scope::BindingIter;
85using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr;
86
87using ParserBindingNameVector = Vector<ParserBindingName, 6>;
88
89static inline void PropagateTransitiveParseFlags(const FunctionBox* inner,
90 SharedContext* outer) {
91 if (inner->bindingsAccessedDynamically()) {
92 outer->setBindingsAccessedDynamically();
93 }
94 if (inner->hasDirectEval()) {
95 outer->setHasDirectEval();
96 }
97}
98
99static bool StatementKindIsBraced(StatementKind kind) {
100 return kind == StatementKind::Block || kind == StatementKind::Switch ||
101 kind == StatementKind::Try || kind == StatementKind::Catch ||
102 kind == StatementKind::Finally;
103}
104
105template <class ParseHandler, typename Unit>
106inline typename GeneralParser<ParseHandler, Unit>::FinalParser*
107GeneralParser<ParseHandler, Unit>::asFinalParser() {
108 static_assert(
109 std::is_base_of_v<GeneralParser<ParseHandler, Unit>, FinalParser>,
110 "inheritance relationship required by the static_cast<> below");
111
112 return static_cast<FinalParser*>(this);
113}
114
115template <class ParseHandler, typename Unit>
116inline const typename GeneralParser<ParseHandler, Unit>::FinalParser*
117GeneralParser<ParseHandler, Unit>::asFinalParser() const {
118 static_assert(
119 std::is_base_of_v<GeneralParser<ParseHandler, Unit>, FinalParser>,
120 "inheritance relationship required by the static_cast<> below");
121
122 return static_cast<const FinalParser*>(this);
123}
124
125template <class ParseHandler, typename Unit>
126template <typename ConditionT, typename ErrorReportT>
127bool GeneralParser<ParseHandler, Unit>::mustMatchTokenInternal(
128 ConditionT condition, ErrorReportT errorReport) {
129 MOZ_ASSERT(condition(TokenKind::Div) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::Div) == false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(condition(TokenKind::Div) ==
false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("condition(TokenKind::Div) == false", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::Div) == false"
")"); do { *((volatile int*)__null) = 129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
130 MOZ_ASSERT(condition(TokenKind::DivAssign) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::DivAssign) == false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(condition(TokenKind::DivAssign) == false))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("condition(TokenKind::DivAssign) == false"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::DivAssign) == false"
")"); do { *((volatile int*)__null) = 130; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
131 MOZ_ASSERT(condition(TokenKind::RegExp) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::RegExp) == false)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(condition(TokenKind::RegExp) == false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("condition(TokenKind::RegExp) == false"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 131); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::RegExp) == false"
")"); do { *((volatile int*)__null) = 131; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
132
133 TokenKind actual;
134 if (!tokenStream.getToken(&actual, TokenStream::SlashIsInvalid)) {
135 return false;
136 }
137 if (!condition(actual)) {
138 errorReport(actual);
139 return false;
140 }
141 return true;
142}
143
144ParserSharedBase::ParserSharedBase(FrontendContext* fc,
145 CompilationState& compilationState,
146 Kind kind)
147 : fc_(fc),
148 alloc_(compilationState.parserAllocScope.alloc()),
149 compilationState_(compilationState),
150 pc_(nullptr),
151 usedNames_(compilationState.usedNames) {
152 fc_->nameCollectionPool().addActiveCompilation();
153}
154
155ParserSharedBase::~ParserSharedBase() {
156 fc_->nameCollectionPool().removeActiveCompilation();
157}
158
159#if defined(DEBUG1) || defined(JS_JITSPEW1)
160void ParserSharedBase::dumpAtom(TaggedParserAtomIndex index) const {
161 parserAtoms().dump(index);
162}
163#endif
164
165ParserBase::ParserBase(FrontendContext* fc,
166 const ReadOnlyCompileOptions& options,
167 bool foldConstants, CompilationState& compilationState)
168 : ParserSharedBase(fc, compilationState, ParserSharedBase::Kind::Parser),
169 anyChars(fc, options, this),
170 ss(nullptr),
171 foldConstants_(foldConstants),
172#ifdef DEBUG1
173 checkOptionsCalled_(false),
174#endif
175 isUnexpectedEOF_(false),
176 awaitHandling_(AwaitIsName),
177 inParametersOfAsyncFunction_(false) {
178}
179
180bool ParserBase::checkOptions() {
181#ifdef DEBUG1
182 checkOptionsCalled_ = true;
183#endif
184
185 return anyChars.checkOptions();
186}
187
188ParserBase::~ParserBase() { MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 188); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 188; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; }
189
190JSAtom* ParserBase::liftParserAtomToJSAtom(TaggedParserAtomIndex index) {
191 JSContext* cx = fc_->maybeCurrentJSContext();
192 MOZ_ASSERT(cx)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(cx)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(cx))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("cx", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 192); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cx" ")"); do
{ *((volatile int*)__null) = 192; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
193 return parserAtoms().toJSAtom(cx, fc_, index,
194 compilationState_.input.atomCache);
195}
196
197template <class ParseHandler>
198PerHandlerParser<ParseHandler>::PerHandlerParser(
199 FrontendContext* fc, const ReadOnlyCompileOptions& options,
200 bool foldConstants, CompilationState& compilationState,
201 void* internalSyntaxParser)
202 : ParserBase(fc, options, foldConstants, compilationState),
203 handler_(fc, compilationState),
204 internalSyntaxParser_(internalSyntaxParser) {
205 MOZ_ASSERT(compilationState.isInitialStencil() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(compilationState.isInitialStencil() == compilationState
.input.isInitialStencil())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(compilationState.isInitialStencil
() == compilationState.input.isInitialStencil()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 206); AnnotateMozCrashReason("MOZ_ASSERT" "(" "compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
")"); do { *((volatile int*)__null) = 206; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
206 compilationState.input.isInitialStencil())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(compilationState.isInitialStencil() == compilationState
.input.isInitialStencil())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(compilationState.isInitialStencil
() == compilationState.input.isInitialStencil()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 206); AnnotateMozCrashReason("MOZ_ASSERT" "(" "compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
")"); do { *((volatile int*)__null) = 206; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
207}
208
209template <class ParseHandler, typename Unit>
210GeneralParser<ParseHandler, Unit>::GeneralParser(
211 FrontendContext* fc, const ReadOnlyCompileOptions& options,
212 const Unit* units, size_t length, bool foldConstants,
213 CompilationState& compilationState, SyntaxParser* syntaxParser)
214 : Base(fc, options, foldConstants, compilationState, syntaxParser),
215 tokenStream(fc, &compilationState.parserAtoms, options, units, length) {}
216
217template <typename Unit>
218void Parser<SyntaxParseHandler, Unit>::setAwaitHandling(
219 AwaitHandling awaitHandling) {
220 this->awaitHandling_ = awaitHandling;
221}
222
223template <typename Unit>
224void Parser<FullParseHandler, Unit>::setAwaitHandling(
225 AwaitHandling awaitHandling) {
226 this->awaitHandling_ = awaitHandling;
227 if (SyntaxParser* syntaxParser = getSyntaxParser()) {
228 syntaxParser->setAwaitHandling(awaitHandling);
229 }
230}
231
232template <class ParseHandler, typename Unit>
233inline void GeneralParser<ParseHandler, Unit>::setAwaitHandling(
234 AwaitHandling awaitHandling) {
235 asFinalParser()->setAwaitHandling(awaitHandling);
236}
237
238template <typename Unit>
239void Parser<SyntaxParseHandler, Unit>::setInParametersOfAsyncFunction(
240 bool inParameters) {
241 this->inParametersOfAsyncFunction_ = inParameters;
242}
243
244template <typename Unit>
245void Parser<FullParseHandler, Unit>::setInParametersOfAsyncFunction(
246 bool inParameters) {
247 this->inParametersOfAsyncFunction_ = inParameters;
248 if (SyntaxParser* syntaxParser = getSyntaxParser()) {
249 syntaxParser->setInParametersOfAsyncFunction(inParameters);
250 }
251}
252
253template <class ParseHandler, typename Unit>
254inline void GeneralParser<ParseHandler, Unit>::setInParametersOfAsyncFunction(
255 bool inParameters) {
256 asFinalParser()->setInParametersOfAsyncFunction(inParameters);
257}
258
259template <class ParseHandler>
260FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
261 FunctionNodeType funNode, TaggedParserAtomIndex explicitName,
262 FunctionFlags flags, uint32_t toStringStart, Directives inheritedDirectives,
263 GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
264 MOZ_ASSERT(funNode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funNode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funNode))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("funNode", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 264); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funNode" ")"
); do { *((volatile int*)__null) = 264; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
265
266 ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
267 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
268 ReportAllocationOverflow(fc_);
269 return nullptr;
270 }
271 if (!compilationState_.appendScriptStencilAndData(fc_)) {
272 return nullptr;
273 }
274
275 bool isInitialStencil = compilationState_.isInitialStencil();
276
277 // This source extent will be further filled in during the remainder of parse.
278 SourceExtent extent;
279 extent.toStringStart = toStringStart;
280
281 FunctionBox* funbox = alloc_.new_<FunctionBox>(
282 fc_, extent, compilationState_, inheritedDirectives, generatorKind,
283 asyncKind, isInitialStencil, explicitName, flags, index);
284 if (!funbox) {
285 ReportOutOfMemory(fc_);
286 return nullptr;
287 }
288
289 handler_.setFunctionBox(funNode, funbox);
290
291 return funbox;
292}
293
294template <class ParseHandler>
295FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
296 FunctionNodeType funNode, const ScriptStencil& cachedScriptData,
297 const ScriptStencilExtra& cachedScriptExtra) {
298 MOZ_ASSERT(funNode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funNode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funNode))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("funNode", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 298); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funNode" ")"
); do { *((volatile int*)__null) = 298; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
299
300 ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
301 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
302 ReportAllocationOverflow(fc_);
303 return nullptr;
304 }
305 if (!compilationState_.appendScriptStencilAndData(fc_)) {
306 return nullptr;
307 }
308
309 FunctionBox* funbox = alloc_.new_<FunctionBox>(
310 fc_, cachedScriptExtra.extent, compilationState_,
311 Directives(/* strict = */ false), cachedScriptExtra.generatorKind(),
312 cachedScriptExtra.asyncKind(), compilationState_.isInitialStencil(),
313 cachedScriptData.functionAtom, cachedScriptData.functionFlags, index);
314 if (!funbox) {
315 ReportOutOfMemory(fc_);
316 return nullptr;
317 }
318
319 handler_.setFunctionBox(funNode, funbox);
320 funbox->initFromScriptStencilExtra(cachedScriptExtra);
321
322 return funbox;
323}
324
325bool ParserBase::setSourceMapInfo() {
326 // If support for source pragmas have been fully disabled, we can skip
327 // processing of all of these values.
328 if (!options().sourcePragmas()) {
329 return true;
330 }
331
332 // Not all clients initialize ss. Can't update info to an object that isn't
333 // there.
334 if (!ss) {
335 return true;
336 }
337
338 if (anyChars.hasDisplayURL()) {
339 if (!ss->setDisplayURL(fc_, anyChars.displayURL())) {
340 return false;
341 }
342 }
343
344 if (anyChars.hasSourceMapURL()) {
345 MOZ_ASSERT(!ss->hasSourceMapURL())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!ss->hasSourceMapURL())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!ss->hasSourceMapURL())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("!ss->hasSourceMapURL()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 345); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!ss->hasSourceMapURL()"
")"); do { *((volatile int*)__null) = 345; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
346 if (!ss->setSourceMapURL(fc_, anyChars.sourceMapURL())) {
347 return false;
348 }
349 }
350
351 /*
352 * Source map URLs passed as a compile option (usually via a HTTP source map
353 * header) override any source map urls passed as comment pragmas.
354 */
355 if (options().sourceMapURL()) {
356 // Warn about the replacement, but use the new one.
357 if (ss->hasSourceMapURL()) {
358 if (!warningNoOffset(JSMSG_ALREADY_HAS_PRAGMA, ss->filename(),
359 "//# sourceMappingURL")) {
360 return false;
361 }
362 }
363
364 if (!ss->setSourceMapURL(fc_, options().sourceMapURL())) {
365 return false;
366 }
367 }
368
369 return true;
370}
371
372/*
373 * Parse a top-level JS script.
374 */
375template <class ParseHandler, typename Unit>
376typename ParseHandler::ListNodeResult
377GeneralParser<ParseHandler, Unit>::parse() {
378 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 378); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 378; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
379
380 SourceExtent extent = SourceExtent::makeGlobalExtent(
381 /* len = */ 0, options().lineno,
382 JS::LimitedColumnNumberOneOrigin::fromUnlimited(
383 JS::ColumnNumberOneOrigin(options().column)));
384 Directives directives(options().forceStrictMode());
385 GlobalSharedContext globalsc(this->fc_, ScopeKind::Global, options(),
386 directives, extent);
387 SourceParseContext globalpc(this, &globalsc, /* newDirectives = */ nullptr);
388 if (!globalpc.init()) {
389 return errorResult();
390 }
391
392 ParseContext::VarScope varScope(this);
393 if (!varScope.init(pc_)) {
394 return errorResult();
395 }
396
397 ListNodeType stmtList;
398 MOZ_TRY_VAR(stmtList, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (stmtList) =
mozTryVarTempResult_.unwrap(); } while (0)
;
399
400 TokenKind tt;
401 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
402 return errorResult();
403 }
404 if (tt != TokenKind::Eof) {
405 error(JSMSG_GARBAGE_AFTER_INPUT, "script", TokenKindToDesc(tt));
406 return errorResult();
407 }
408
409 if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
410 return errorResult();
411 }
412
413 if (foldConstants_) {
414 Node node = stmtList;
415 // Don't constant-fold inside "use asm" code, as this could create a parse
416 // tree that doesn't type-check as asm.js.
417 if (!pc_->useAsmOrInsideUseAsm()) {
418 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
419 return errorResult();
420 }
421 }
422 stmtList = handler_.asListNode(node);
423 }
424
425 return stmtList;
426}
427
428/*
429 * Strict mode forbids introducing new definitions for 'eval', 'arguments',
430 * 'let', 'static', 'yield', or for any strict mode reserved word.
431 */
432bool ParserBase::isValidStrictBinding(TaggedParserAtomIndex name) {
433 TokenKind tt = ReservedWordTokenKind(name);
434 if (tt == TokenKind::Limit) {
435 return name != TaggedParserAtomIndex::WellKnown::eval() &&
436 name != TaggedParserAtomIndex::WellKnown::arguments();
437 }
438 return tt != TokenKind::Let && tt != TokenKind::Static &&
439 tt != TokenKind::Yield && !TokenKindIsStrictReservedWord(tt);
440}
441
442/*
443 * Returns true if all parameter names are valid strict mode binding names and
444 * no duplicate parameter names are present.
445 */
446bool ParserBase::hasValidSimpleStrictParameterNames() {
447 MOZ_ASSERT(pc_->isFunctionBox() &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox() && pc_->functionBox
()->hasSimpleParameterList())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox() &&
pc_->functionBox()->hasSimpleParameterList()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
")"); do { *((volatile int*)__null) = 448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
448 pc_->functionBox()->hasSimpleParameterList())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox() && pc_->functionBox
()->hasSimpleParameterList())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox() &&
pc_->functionBox()->hasSimpleParameterList()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
")"); do { *((volatile int*)__null) = 448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
449
450 if (pc_->functionBox()->hasDuplicateParameters) {
451 return false;
452 }
453
454 for (auto name : pc_->positionalFormalParameterNames()) {
455 MOZ_ASSERT(name)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(name))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("name", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 455); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name" ")"); do
{ *((volatile int*)__null) = 455; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
456 if (!isValidStrictBinding(name)) {
457 return false;
458 }
459 }
460 return true;
461}
462
463template <class ParseHandler, typename Unit>
464void GeneralParser<ParseHandler, Unit>::reportMissingClosing(
465 unsigned errorNumber, unsigned noteNumber, uint32_t openedPos) {
466 auto notes = MakeUnique<JSErrorNotes>();
467 if (!notes) {
468 ReportOutOfMemory(this->fc_);
469 return;
470 }
471
472 uint32_t line;
473 JS::LimitedColumnNumberOneOrigin column;
474 tokenStream.computeLineAndColumn(openedPos, &line, &column);
475
476 const size_t MaxWidth = sizeof("4294967295");
477 char columnNumber[MaxWidth];
478 SprintfLiteral(columnNumber, "%" PRIu32"u", column.oneOriginValue());
479 char lineNumber[MaxWidth];
480 SprintfLiteral(lineNumber, "%" PRIu32"u", line);
481
482 if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
483 JS::ColumnNumberOneOrigin(column), GetErrorMessage,
484 nullptr, noteNumber, lineNumber, columnNumber)) {
485 return;
486 }
487
488 errorWithNotes(std::move(notes), errorNumber);
489}
490
491template <class ParseHandler, typename Unit>
492void GeneralParser<ParseHandler, Unit>::reportRedeclarationHelper(
493 TaggedParserAtomIndex& name, DeclarationKind& prevKind, TokenPos& pos,
494 uint32_t& prevPos, const unsigned& errorNumber,
495 const unsigned& noteErrorNumber) {
496 UniqueChars bytes = this->parserAtoms().toPrintableString(name);
497 if (!bytes) {
498 ReportOutOfMemory(this->fc_);
499 return;
500 }
501
502 if (prevPos == DeclaredNameInfo::npos) {
503 errorAt(pos.begin, errorNumber, DeclarationKindString(prevKind),
504 bytes.get());
505 return;
506 }
507
508 auto notes = MakeUnique<JSErrorNotes>();
509 if (!notes) {
510 ReportOutOfMemory(this->fc_);
511 return;
512 }
513
514 uint32_t line;
515 JS::LimitedColumnNumberOneOrigin column;
516 tokenStream.computeLineAndColumn(prevPos, &line, &column);
517
518 const size_t MaxWidth = sizeof("4294967295");
519 char columnNumber[MaxWidth];
520 SprintfLiteral(columnNumber, "%" PRIu32"u", column.oneOriginValue());
521 char lineNumber[MaxWidth];
522 SprintfLiteral(lineNumber, "%" PRIu32"u", line);
523
524 if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
525 JS::ColumnNumberOneOrigin(column), GetErrorMessage,
526 nullptr, noteErrorNumber, lineNumber,
527 columnNumber)) {
528 return;
529 }
530
531 errorWithNotesAt(std::move(notes), pos.begin, errorNumber,
532 DeclarationKindString(prevKind), bytes.get());
533}
534
535template <class ParseHandler, typename Unit>
536void GeneralParser<ParseHandler, Unit>::reportRedeclaration(
537 TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
538 uint32_t prevPos) {
539 reportRedeclarationHelper(name, prevKind, pos, prevPos, JSMSG_REDECLARED_VAR,
540 JSMSG_PREV_DECLARATION);
541}
542
543template <class ParseHandler, typename Unit>
544void GeneralParser<ParseHandler, Unit>::reportMismatchedPlacement(
545 TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
546 uint32_t prevPos) {
547 reportRedeclarationHelper(name, prevKind, pos, prevPos,
548 JSMSG_MISMATCHED_PLACEMENT, JSMSG_PREV_DECLARATION);
549}
550
551// notePositionalFormalParameter is called for both the arguments of a regular
552// function definition and the arguments specified by the Function
553// constructor.
554//
555// The 'disallowDuplicateParams' bool indicates whether the use of another
556// feature (destructuring or default arguments) disables duplicate arguments.
557// (ECMA-262 requires us to support duplicate parameter names, but, for newer
558// features, we consider the code to have "opted in" to higher standards and
559// forbid duplicates.)
560template <class ParseHandler, typename Unit>
561bool GeneralParser<ParseHandler, Unit>::notePositionalFormalParameter(
562 FunctionNodeType funNode, TaggedParserAtomIndex name, uint32_t beginPos,
563 bool disallowDuplicateParams, bool* duplicatedParam) {
564 if (AddDeclaredNamePtr p =
565 pc_->functionScope().lookupDeclaredNameForAdd(name)) {
566 if (disallowDuplicateParams) {
567 error(JSMSG_BAD_DUP_ARGS);
568 return false;
569 }
570
571 // Strict-mode disallows duplicate args. We may not know whether we are
572 // in strict mode or not (since the function body hasn't been parsed).
573 // In such cases, report will queue up the potential error and return
574 // 'true'.
575 if (pc_->sc()->strict()) {
576 UniqueChars bytes = this->parserAtoms().toPrintableString(name);
577 if (!bytes) {
578 ReportOutOfMemory(this->fc_);
579 return false;
580 }
581 if (!strictModeError(JSMSG_DUPLICATE_FORMAL, bytes.get())) {
582 return false;
583 }
584 }
585
586 *duplicatedParam = true;
587 } else {
588 DeclarationKind kind = DeclarationKind::PositionalFormalParameter;
589 if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, beginPos)) {
590 return false;
591 }
592 }
593
594 if (!pc_->positionalFormalParameterNames().append(
595 TrivialTaggedParserAtomIndex::from(name))) {
596 ReportOutOfMemory(this->fc_);
597 return false;
598 }
599
600 NameNodeType paramNode;
601 MOZ_TRY_VAR_OR_RETURN(paramNode, newName(name), false)do { auto parserTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(paramNode) = parserTryVarTempResult_.unwrap(); } while (0)
;
602
603 handler_.addFunctionFormalParameter(funNode, paramNode);
604 return true;
605}
606
607template <class ParseHandler>
608bool PerHandlerParser<ParseHandler>::noteDestructuredPositionalFormalParameter(
609 FunctionNodeType funNode, Node destruct) {
610 // Append an empty name to the positional formals vector to keep track of
611 // argument slots when making FunctionScope::ParserData.
612 if (!pc_->positionalFormalParameterNames().append(
613 TrivialTaggedParserAtomIndex::null())) {
614 ReportOutOfMemory(fc_);
615 return false;
616 }
617
618 handler_.addFunctionFormalParameter(funNode, destruct);
619 return true;
620}
621
622template <class ParseHandler, typename Unit>
623bool GeneralParser<ParseHandler, Unit>::noteDeclaredName(
624 TaggedParserAtomIndex name, DeclarationKind kind, TokenPos pos,
625 ClosedOver isClosedOver) {
626 // The asm.js validator does all its own symbol-table management so, as an
627 // optimization, avoid doing any work here.
628 if (pc_->useAsmOrInsideUseAsm()) {
629 return true;
630 }
631
632 switch (kind) {
633 case DeclarationKind::Var:
634 case DeclarationKind::BodyLevelFunction: {
635 Maybe<DeclarationKind> redeclaredKind;
636 uint32_t prevPos;
637 if (!pc_->tryDeclareVar(name, this, kind, pos.begin, &redeclaredKind,
638 &prevPos)) {
639 return false;
640 }
641
642 if (redeclaredKind) {
643 reportRedeclaration(name, *redeclaredKind, pos, prevPos);
644 return false;
645 }
646
647 break;
648 }
649
650 case DeclarationKind::ModuleBodyLevelFunction: {
651 MOZ_ASSERT(pc_->atModuleLevel())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->atModuleLevel())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->atModuleLevel()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->atModuleLevel()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->atModuleLevel()"
")"); do { *((volatile int*)__null) = 651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
652
653 AddDeclaredNamePtr p = pc_->varScope().lookupDeclaredNameForAdd(name);
654 if (p) {
655 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
656 return false;
657 }
658
659 if (!pc_->varScope().addDeclaredName(pc_, p, name, kind, pos.begin,
660 isClosedOver)) {
661 return false;
662 }
663
664 // Body-level functions in modules are always closed over.
665 pc_->varScope().lookupDeclaredName(name)->value()->setClosedOver();
666
667 break;
668 }
669
670 case DeclarationKind::FormalParameter: {
671 // It is an early error if any non-positional formal parameter name
672 // (e.g., destructuring formal parameter) is duplicated.
673
674 AddDeclaredNamePtr p =
675 pc_->functionScope().lookupDeclaredNameForAdd(name);
676 if (p) {
677 error(JSMSG_BAD_DUP_ARGS);
678 return false;
679 }
680
681 if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, pos.begin,
682 isClosedOver)) {
683 return false;
684 }
685
686 break;
687 }
688
689 case DeclarationKind::LexicalFunction:
690 case DeclarationKind::PrivateName:
691 case DeclarationKind::Synthetic:
692 case DeclarationKind::PrivateMethod: {
693 ParseContext::Scope* scope = pc_->innermostScope();
694 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
695 if (p) {
696 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
697 return false;
698 }
699
700 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
701 isClosedOver)) {
702 return false;
703 }
704
705 break;
706 }
707
708 case DeclarationKind::SloppyLexicalFunction: {
709 // Functions in block have complex allowances in sloppy mode for being
710 // labelled that other lexical declarations do not have. Those checks
711 // are done in functionStmt.
712
713 ParseContext::Scope* scope = pc_->innermostScope();
714 if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
715 // It is usually an early error if there is another declaration
716 // with the same name in the same scope.
717 //
718 // Sloppy lexical functions may redeclare other sloppy lexical
719 // functions for web compatibility reasons.
720 if (p->value()->kind() != DeclarationKind::SloppyLexicalFunction) {
721 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
722 return false;
723 }
724 } else {
725 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
726 isClosedOver)) {
727 return false;
728 }
729 }
730
731 break;
732 }
733
734 case DeclarationKind::Let:
735 case DeclarationKind::Const:
736#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
737 case DeclarationKind::Using:
738 case DeclarationKind::AwaitUsing:
739#endif
740 case DeclarationKind::Class:
741 // The BoundNames of LexicalDeclaration and ForDeclaration must not
742 // contain 'let'. (CatchParameter is the only lexical binding form
743 // without this restriction.)
744 if (name == TaggedParserAtomIndex::WellKnown::let()) {
745 errorAt(pos.begin, JSMSG_LEXICAL_DECL_DEFINES_LET);
746 return false;
747 }
748
749 // For body-level lexically declared names in a function, it is an
750 // early error if there is a formal parameter of the same name. This
751 // needs a special check if there is an extra var scope due to
752 // parameter expressions.
753 if (pc_->isFunctionExtraBodyVarScopeInnermost()) {
754 DeclaredNamePtr p = pc_->functionScope().lookupDeclaredName(name);
755 if (p && DeclarationKindIsParameter(p->value()->kind())) {
756 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
757 return false;
758 }
759 }
760
761 [[fallthrough]];
762
763 case DeclarationKind::Import:
764 // Module code is always strict, so 'let' is always a keyword and never a
765 // name.
766 MOZ_ASSERT(name != TaggedParserAtomIndex::WellKnown::let())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name != TaggedParserAtomIndex::WellKnown::let())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(name != TaggedParserAtomIndex::WellKnown::let()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("name != TaggedParserAtomIndex::WellKnown::let()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 766); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name != TaggedParserAtomIndex::WellKnown::let()"
")"); do { *((volatile int*)__null) = 766; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
767 [[fallthrough]];
768
769 case DeclarationKind::SimpleCatchParameter:
770 case DeclarationKind::CatchParameter: {
771 ParseContext::Scope* scope = pc_->innermostScope();
772
773 // It is an early error if there is another declaration with the same
774 // name in the same scope.
775 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
776 if (p) {
777 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
778 return false;
779 }
780
781 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
782 isClosedOver)) {
783 return false;
784 }
785
786 break;
787 }
788
789 case DeclarationKind::CoverArrowParameter:
790 // CoverArrowParameter is only used as a placeholder declaration kind.
791 break;
792
793 case DeclarationKind::PositionalFormalParameter:
794 MOZ_CRASH(do { do { } while (false); MOZ_ReportCrash("" "Positional formal parameter names should use "
"notePositionalFormalParameter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 796); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 796; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
795 "Positional formal parameter names should use "do { do { } while (false); MOZ_ReportCrash("" "Positional formal parameter names should use "
"notePositionalFormalParameter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 796); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 796; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
796 "notePositionalFormalParameter")do { do { } while (false); MOZ_ReportCrash("" "Positional formal parameter names should use "
"notePositionalFormalParameter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 796); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 796; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
;
797 break;
798
799 case DeclarationKind::VarForAnnexBLexicalFunction:
800 MOZ_CRASH(do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 803); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 803; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
801 "Synthesized Annex B vars should go through "do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 803); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 803; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
802 "addPossibleAnnexBFunctionBox, and "do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 803); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 803; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
803 "propagateAndMarkAnnexBFunctionBoxes")do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 803); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 803; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
804 break;
805 }
806
807 return true;
808}
809
810template <class ParseHandler, typename Unit>
811bool GeneralParser<ParseHandler, Unit>::noteDeclaredPrivateName(
812 Node nameNode, TaggedParserAtomIndex name, PropertyType propType,
813 FieldPlacement placement, TokenPos pos) {
814 ParseContext::Scope* scope = pc_->innermostScope();
815 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
816
817 DeclarationKind declKind = DeclarationKind::PrivateName;
818
819 // Our strategy for enabling debugger functionality is to mark names as closed
820 // over, even if they don't necessarily need to be, to ensure that they are
821 // included in the environment object. This allows us to easily look them up
822 // by name when needed, even if there is no corresponding property on an
823 // object, as is the case with getter, setters and private methods.
824 ClosedOver closedOver = ClosedOver::Yes;
825 PrivateNameKind kind;
826 switch (propType) {
827 case PropertyType::Field:
828 kind = PrivateNameKind::Field;
829 closedOver = ClosedOver::No;
830 break;
831 case PropertyType::FieldWithAccessor:
832 // In this case, we create a new private field for the underlying storage,
833 // and use the current name for the getter and setter.
834 kind = PrivateNameKind::GetterSetter;
835 break;
836 case PropertyType::Method:
837 case PropertyType::GeneratorMethod:
838 case PropertyType::AsyncMethod:
839 case PropertyType::AsyncGeneratorMethod:
840 if (placement == FieldPlacement::Instance) {
841 // Optimized private method. Non-optimized paths still get
842 // DeclarationKind::Synthetic.
843 declKind = DeclarationKind::PrivateMethod;
844 }
845 kind = PrivateNameKind::Method;
846 break;
847 case PropertyType::Getter:
848 kind = PrivateNameKind::Getter;
849 break;
850 case PropertyType::Setter:
851 kind = PrivateNameKind::Setter;
852 break;
853 default:
854 MOZ_CRASH("Invalid Property Type for noteDeclarePrivateName")do { do { } while (false); MOZ_ReportCrash("" "Invalid Property Type for noteDeclarePrivateName"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 854); AnnotateMozCrashReason("MOZ_CRASH(" "Invalid Property Type for noteDeclarePrivateName"
")"); do { *((volatile int*)__null) = 854; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
855 }
856
857 if (p) {
858 PrivateNameKind prevKind = p->value()->privateNameKind();
859 if ((prevKind == PrivateNameKind::Getter &&
860 kind == PrivateNameKind::Setter) ||
861 (prevKind == PrivateNameKind::Setter &&
862 kind == PrivateNameKind::Getter)) {
863 // Private methods demands that
864 //
865 // class A {
866 // static set #x(_) {}
867 // get #x() { }
868 // }
869 //
870 // Report a SyntaxError.
871 if (placement == p->value()->placement()) {
872 p->value()->setPrivateNameKind(PrivateNameKind::GetterSetter);
873 handler_.setPrivateNameKind(nameNode, PrivateNameKind::GetterSetter);
874 return true;
875 }
876 }
877
878 reportMismatchedPlacement(name, p->value()->kind(), pos, p->value()->pos());
879 return false;
880 }
881
882 if (!scope->addDeclaredName(pc_, p, name, declKind, pos.begin, closedOver)) {
883 return false;
884 }
885
886 DeclaredNamePtr declared = scope->lookupDeclaredName(name);
887 declared->value()->setPrivateNameKind(kind);
888 declared->value()->setFieldPlacement(placement);
889 handler_.setPrivateNameKind(nameNode, kind);
890
891 return true;
892}
893
894bool ParserBase::noteUsedNameInternal(TaggedParserAtomIndex name,
895 NameVisibility visibility,
896 mozilla::Maybe<TokenPos> tokenPosition) {
897 // The asm.js validator does all its own symbol-table management so, as an
898 // optimization, avoid doing any work here.
899 if (pc_->useAsmOrInsideUseAsm()) {
900 return true;
901 }
902
903 // Global bindings are properties and not actual bindings; we don't need
904 // to know if they are closed over. So no need to track used name at the
905 // global scope. It is not incorrect to track them, this is an
906 // optimization.
907 //
908 // Exceptions:
909 // (a) Track private name references, as the used names tracker is used to
910 // provide early errors for undeclared private name references
911 // (b) If the script has extra bindings, track all references to detect
912 // references to extra bindings
913 ParseContext::Scope* scope = pc_->innermostScope();
914 if (pc_->sc()->isGlobalContext() && scope == &pc_->varScope() &&
915 visibility == NameVisibility::Public &&
916 !this->compilationState_.input.hasExtraBindings()) {
917 return true;
918 }
919
920 return usedNames_.noteUse(fc_, name, visibility, pc_->scriptId(), scope->id(),
921 tokenPosition);
922}
923
924template <class ParseHandler>
925bool PerHandlerParser<ParseHandler>::
926 propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope) {
927 // Now that we have all the declared names in the scope, check which
928 // functions should exhibit Annex B semantics.
929 if (!scope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
930 return false;
931 }
932
933 if (handler_.reuseClosedOverBindings()) {
934 MOZ_ASSERT(pc_->isOutermostOfCurrentCompile())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isOutermostOfCurrentCompile())>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(pc_->isOutermostOfCurrentCompile()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->isOutermostOfCurrentCompile()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 934); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isOutermostOfCurrentCompile()"
")"); do { *((volatile int*)__null) = 934; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
935
936 // Closed over bindings for all scopes are stored in a contiguous array, in
937 // the same order as the order in which scopes are visited, and seprated by
938 // TaggedParserAtomIndex::null().
939 uint32_t slotCount = scope.declaredCount();
940 while (auto parserAtom = handler_.nextLazyClosedOverBinding()) {
941 scope.lookupDeclaredName(parserAtom)->value()->setClosedOver();
942 MOZ_ASSERT(slotCount > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(slotCount > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(slotCount > 0))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("slotCount > 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 942); AnnotateMozCrashReason("MOZ_ASSERT" "(" "slotCount > 0"
")"); do { *((volatile int*)__null) = 942; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
943 slotCount--;
944 }
945
946 if (pc_->isGeneratorOrAsync()) {
947 scope.setOwnStackSlotCount(slotCount);
948 }
949 return true;
950 }
951
952 constexpr bool isSyntaxParser =
953 std::is_same_v<ParseHandler, SyntaxParseHandler>;
954 uint32_t scriptId = pc_->scriptId();
955 uint32_t scopeId = scope.id();
956
957 uint32_t slotCount = 0;
958 for (BindingIter bi = scope.bindings(pc_); bi; bi++) {
959 bool closedOver = false;
960 if (UsedNamePtr p = usedNames_.lookup(bi.name())) {
961 p->value().noteBoundInScope(scriptId, scopeId, &closedOver);
962 if (closedOver) {
963 bi.setClosedOver();
964
965 if constexpr (isSyntaxParser) {
966 if (!pc_->closedOverBindingsForLazy().append(
967 TrivialTaggedParserAtomIndex::from(bi.name()))) {
968 ReportOutOfMemory(fc_);
969 return false;
970 }
971 }
972 }
973 }
974
975 if constexpr (!isSyntaxParser) {
976 if (!closedOver) {
977 slotCount++;
978 }
979 }
980 }
981 if constexpr (!isSyntaxParser) {
982 if (pc_->isGeneratorOrAsync()) {
983 scope.setOwnStackSlotCount(slotCount);
984 }
985 }
986
987 // Append a nullptr to denote end-of-scope.
988 if constexpr (isSyntaxParser) {
989 if (!pc_->closedOverBindingsForLazy().append(
990 TrivialTaggedParserAtomIndex::null())) {
991 ReportOutOfMemory(fc_);
992 return false;
993 }
994 }
995
996 return true;
997}
998
999template <typename Unit>
1000bool Parser<FullParseHandler, Unit>::checkStatementsEOF() {
1001 // This is designed to be paired with parsing a statement list at the top
1002 // level.
1003 //
1004 // The statementList() call breaks on TokenKind::RightCurly, so make sure
1005 // we've reached EOF here.
1006 TokenKind tt;
1007 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
1008 return false;
1009 }
1010 if (tt != TokenKind::Eof) {
1011 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
1012 return false;
1013 }
1014 return true;
1015}
1016
1017template <typename ScopeT>
1018typename ScopeT::ParserData* NewEmptyBindingData(FrontendContext* fc,
1019 LifoAlloc& alloc,
1020 uint32_t numBindings) {
1021 using Data = typename ScopeT::ParserData;
1022 size_t allocSize = SizeOfScopeData<Data>(numBindings);
1023 auto* bindings = alloc.newWithSize<Data>(allocSize, numBindings);
1024 if (!bindings) {
1025 ReportOutOfMemory(fc);
1026 }
1027 return bindings;
1028}
1029
1030GlobalScope::ParserData* NewEmptyGlobalScopeData(FrontendContext* fc,
1031 LifoAlloc& alloc,
1032 uint32_t numBindings) {
1033 return NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
1034}
1035
1036LexicalScope::ParserData* NewEmptyLexicalScopeData(FrontendContext* fc,
1037 LifoAlloc& alloc,
1038 uint32_t numBindings) {
1039 return NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
1040}
1041
1042FunctionScope::ParserData* NewEmptyFunctionScopeData(FrontendContext* fc,
1043 LifoAlloc& alloc,
1044 uint32_t numBindings) {
1045 return NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
1046}
1047
1048namespace detail {
1049
1050template <class SlotInfo>
1051static MOZ_ALWAYS_INLINEinline ParserBindingName* InitializeIndexedBindings(
1052 SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor) {
1053 return cursor;
1054}
1055
1056template <class SlotInfo, typename UnsignedInteger, typename... Step>
1057static MOZ_ALWAYS_INLINEinline ParserBindingName* InitializeIndexedBindings(
1058 SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor,
1059 UnsignedInteger SlotInfo::*field, const ParserBindingNameVector& bindings,
1060 Step&&... step) {
1061 slotInfo.*field =
1062 AssertedCast<UnsignedInteger>(PointerRangeSize(start, cursor));
1063
1064 ParserBindingName* newCursor =
1065 std::uninitialized_copy(bindings.begin(), bindings.end(), cursor);
1066
1067 return InitializeIndexedBindings(slotInfo, start, newCursor,
1068 std::forward<Step>(step)...);
1069}
1070
1071} // namespace detail
1072
1073// Initialize the trailing name bindings of |data|, then set |data->length| to
1074// the count of bindings added (which must equal |count|).
1075//
1076// First, |firstBindings| are added to the trailing names. Then any
1077// "steps" present are performed first to last. Each step is 1) a pointer to a
1078// member of |data| to be set to the current number of bindings added, and 2) a
1079// vector of |ParserBindingName|s to then copy into |data->trailingNames|.
1080// (Thus each |data| member field indicates where the corresponding vector's
1081// names start.)
1082template <class Data, typename... Step>
1083static MOZ_ALWAYS_INLINEinline void InitializeBindingData(
1084 Data* data, uint32_t count, const ParserBindingNameVector& firstBindings,
1085 Step&&... step) {
1086 MOZ_ASSERT(data->length == 0, "data shouldn't be filled yet")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(data->length == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(data->length == 0))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("data->length == 0"
" (" "data shouldn't be filled yet" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1086); AnnotateMozCrashReason("MOZ_ASSERT" "(" "data->length == 0"
") (" "data shouldn't be filled yet" ")"); do { *((volatile int
*)__null) = 1086; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1087
1088 ParserBindingName* start = GetScopeDataTrailingNamesPointer(data);
1089 ParserBindingName* cursor = std::uninitialized_copy(
1090 firstBindings.begin(), firstBindings.end(), start);
1091
1092#ifdef DEBUG1
1093 ParserBindingName* end =
1094#endif
1095 detail::InitializeIndexedBindings(data->slotInfo, start, cursor,
1096 std::forward<Step>(step)...);
1097
1098 MOZ_ASSERT(PointerRangeSize(start, end) == count)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(PointerRangeSize(start, end) == count)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(PointerRangeSize(start, end) == count))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("PointerRangeSize(start, end) == count"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1098); AnnotateMozCrashReason("MOZ_ASSERT" "(" "PointerRangeSize(start, end) == count"
")"); do { *((volatile int*)__null) = 1098; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1099 data->length = count;
1100}
1101
1102static Maybe<GlobalScope::ParserData*> NewGlobalScopeData(
1103 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1104 ParseContext* pc) {
1105 ParserBindingNameVector vars(fc);
1106 ParserBindingNameVector lets(fc);
1107 ParserBindingNameVector consts(fc);
1108
1109 bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
1110 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1111 bool closedOver = allBindingsClosedOver || bi.closedOver();
1112
1113 switch (bi.kind()) {
1114 case BindingKind::Var: {
1115 bool isTopLevelFunction =
1116 bi.declarationKind() == DeclarationKind::BodyLevelFunction;
1117
1118 ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
1119 if (!vars.append(binding)) {
1120 return Nothing();
1121 }
1122 break;
1123 }
1124 case BindingKind::Let: {
1125 ParserBindingName binding(bi.name(), closedOver);
1126 if (!lets.append(binding)) {
1127 return Nothing();
1128 }
1129 break;
1130 }
1131 case BindingKind::Const: {
1132 ParserBindingName binding(bi.name(), closedOver);
1133 if (!consts.append(binding)) {
1134 return Nothing();
1135 }
1136 break;
1137 }
1138 default:
1139 MOZ_CRASH("Bad global scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "Bad global scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1139); AnnotateMozCrashReason("MOZ_CRASH(" "Bad global scope BindingKind"
")"); do { *((volatile int*)__null) = 1139; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1140 }
1141 }
1142
1143 GlobalScope::ParserData* bindings = nullptr;
1144 uint32_t numBindings = vars.length() + lets.length() + consts.length();
1145
1146 if (numBindings > 0) {
1147 bindings = NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
1148 if (!bindings) {
1149 return Nothing();
1150 }
1151
1152 // The ordering here is important. See comments in GlobalScope.
1153 InitializeBindingData(bindings, numBindings, vars,
1154 &ParserGlobalScopeSlotInfo::letStart, lets,
1155 &ParserGlobalScopeSlotInfo::constStart, consts);
1156 }
1157
1158 return Some(bindings);
1159}
1160
1161Maybe<GlobalScope::ParserData*> ParserBase::newGlobalScopeData(
1162 ParseContext::Scope& scope) {
1163 return NewGlobalScopeData(fc_, scope, stencilAlloc(), pc_);
1164}
1165
1166static Maybe<ModuleScope::ParserData*> NewModuleScopeData(
1167 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1168 ParseContext* pc) {
1169 ParserBindingNameVector imports(fc);
1170 ParserBindingNameVector vars(fc);
1171 ParserBindingNameVector lets(fc);
1172 ParserBindingNameVector consts(fc);
1173#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1174 ParserBindingNameVector usings(fc);
1175#endif
1176
1177 bool allBindingsClosedOver =
1178 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1179
1180 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1181 // Imports are indirect bindings and must not be given known slots.
1182 ParserBindingName binding(bi.name(),
1183 (allBindingsClosedOver || bi.closedOver()) &&
1184 bi.kind() != BindingKind::Import);
1185 switch (bi.kind()) {
1186 case BindingKind::Import:
1187 if (!imports.append(binding)) {
1188 return Nothing();
1189 }
1190 break;
1191 case BindingKind::Var:
1192 if (!vars.append(binding)) {
1193 return Nothing();
1194 }
1195 break;
1196 case BindingKind::Let:
1197 if (!lets.append(binding)) {
1198 return Nothing();
1199 }
1200 break;
1201 case BindingKind::Const:
1202 if (!consts.append(binding)) {
1203 return Nothing();
1204 }
1205 break;
1206#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1207 case BindingKind::Using:
1208 if (!usings.append(binding)) {
1209 return Nothing();
1210 }
1211 break;
1212#endif
1213 default:
1214 MOZ_CRASH("Bad module scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "Bad module scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1214); AnnotateMozCrashReason("MOZ_CRASH(" "Bad module scope BindingKind"
")"); do { *((volatile int*)__null) = 1214; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1215 }
1216 }
1217
1218 ModuleScope::ParserData* bindings = nullptr;
1219 uint32_t numBindings = imports.length() + vars.length() + lets.length() +
1220 consts.length()
1221#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1222 + usings.length()
1223#endif
1224 ;
1225
1226 if (numBindings > 0) {
1227 bindings = NewEmptyBindingData<ModuleScope>(fc, alloc, numBindings);
1228 if (!bindings) {
1229 return Nothing();
1230 }
1231
1232 // The ordering here is important. See comments in ModuleScope.
1233 InitializeBindingData(bindings, numBindings, imports,
1234 &ParserModuleScopeSlotInfo::varStart, vars,
1235 &ParserModuleScopeSlotInfo::letStart, lets,
1236 &ParserModuleScopeSlotInfo::constStart, consts
1237#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1238 ,
1239 &ParserModuleScopeSlotInfo::usingStart, usings
1240#endif
1241 );
1242 }
1243
1244 return Some(bindings);
1245}
1246
1247Maybe<ModuleScope::ParserData*> ParserBase::newModuleScopeData(
1248 ParseContext::Scope& scope) {
1249 return NewModuleScopeData(fc_, scope, stencilAlloc(), pc_);
1250}
1251
1252static Maybe<EvalScope::ParserData*> NewEvalScopeData(
1253 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1254 ParseContext* pc) {
1255 ParserBindingNameVector vars(fc);
1256
1257 // Treat all bindings as closed over in non-strict eval.
1258 bool allBindingsClosedOver =
1259 !pc->sc()->strict() || pc->sc()->allBindingsClosedOver();
1260 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1261 // Eval scopes only contain 'var' bindings.
1262 MOZ_ASSERT(bi.kind() == BindingKind::Var)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Var)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(bi.kind() == BindingKind::Var
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"bi.kind() == BindingKind::Var", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1262); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Var"
")"); do { *((volatile int*)__null) = 1262; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1263 bool isTopLevelFunction =
1264 bi.declarationKind() == DeclarationKind::BodyLevelFunction;
1265 bool closedOver = allBindingsClosedOver || bi.closedOver();
1266
1267 ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
1268 if (!vars.append(binding)) {
1269 return Nothing();
1270 }
1271 }
1272
1273 EvalScope::ParserData* bindings = nullptr;
1274 uint32_t numBindings = vars.length();
1275
1276 if (numBindings > 0) {
1277 bindings = NewEmptyBindingData<EvalScope>(fc, alloc, numBindings);
1278 if (!bindings) {
1279 return Nothing();
1280 }
1281
1282 InitializeBindingData(bindings, numBindings, vars);
1283 }
1284
1285 return Some(bindings);
1286}
1287
1288Maybe<EvalScope::ParserData*> ParserBase::newEvalScopeData(
1289 ParseContext::Scope& scope) {
1290 return NewEvalScopeData(fc_, scope, stencilAlloc(), pc_);
1291}
1292
1293static Maybe<FunctionScope::ParserData*> NewFunctionScopeData(
1294 FrontendContext* fc, ParseContext::Scope& scope, bool hasParameterExprs,
1295 LifoAlloc& alloc, ParseContext* pc) {
1296 ParserBindingNameVector positionalFormals(fc);
1297 ParserBindingNameVector formals(fc);
1298 ParserBindingNameVector vars(fc);
1299
1300 bool allBindingsClosedOver =
1301 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1302 bool argumentBindingsClosedOver =
1303 allBindingsClosedOver || pc->isGeneratorOrAsync();
1304 bool hasDuplicateParams = pc->functionBox()->hasDuplicateParameters;
1305
1306 // Positional parameter names must be added in order of appearance as they are
1307 // referenced using argument slots.
1308 for (size_t i = 0; i < pc->positionalFormalParameterNames().length(); i++) {
1309 TaggedParserAtomIndex name = pc->positionalFormalParameterNames()[i];
1310
1311 ParserBindingName bindName;
1312 if (name) {
1313 DeclaredNamePtr p = scope.lookupDeclaredName(name);
1314
1315 // Do not consider any positional formal parameters closed over if
1316 // there are parameter defaults. It is the binding in the defaults
1317 // scope that is closed over instead.
1318 bool closedOver =
1319 argumentBindingsClosedOver || (p && p->value()->closedOver());
1320
1321 // If the parameter name has duplicates, only the final parameter
1322 // name should be on the environment, as otherwise the environment
1323 // object would have multiple, same-named properties.
1324 if (hasDuplicateParams) {
1325 for (size_t j = pc->positionalFormalParameterNames().length() - 1;
1326 j > i; j--) {
1327 if (TaggedParserAtomIndex(pc->positionalFormalParameterNames()[j]) ==
1328 name) {
1329 closedOver = false;
1330 break;
1331 }
1332 }
1333 }
1334
1335 bindName = ParserBindingName(name, closedOver);
1336 }
1337
1338 if (!positionalFormals.append(bindName)) {
1339 return Nothing();
1340 }
1341 }
1342
1343 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1344 ParserBindingName binding(bi.name(),
1345 allBindingsClosedOver || bi.closedOver());
1346 switch (bi.kind()) {
1347 case BindingKind::FormalParameter:
1348 // Positional parameter names are already handled above.
1349 if (bi.declarationKind() == DeclarationKind::FormalParameter) {
1350 if (!formals.append(binding)) {
1351 return Nothing();
1352 }
1353 }
1354 break;
1355 case BindingKind::Var:
1356 // The only vars in the function scope when there are parameter
1357 // exprs, which induces a separate var environment, should be the
1358 // special bindings.
1359 MOZ_ASSERT_IF(hasParameterExprs,do { if (hasParameterExprs) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(FunctionScope::isSpecialName
(bi.name()))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(FunctionScope::isSpecialName(bi.name
())))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("FunctionScope::isSpecialName(bi.name())", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1360); AnnotateMozCrashReason("MOZ_ASSERT" "(" "FunctionScope::isSpecialName(bi.name())"
")"); do { *((volatile int*)__null) = 1360; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1360 FunctionScope::isSpecialName(bi.name()))do { if (hasParameterExprs) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(FunctionScope::isSpecialName
(bi.name()))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(FunctionScope::isSpecialName(bi.name
())))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("FunctionScope::isSpecialName(bi.name())", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1360); AnnotateMozCrashReason("MOZ_ASSERT" "(" "FunctionScope::isSpecialName(bi.name())"
")"); do { *((volatile int*)__null) = 1360; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1361 if (!vars.append(binding)) {
1362 return Nothing();
1363 }
1364 break;
1365 case BindingKind::Let:
1366 case BindingKind::Const:
1367#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1368 case BindingKind::Using:
1369#endif
1370 break;
1371 default:
1372 MOZ_CRASH("bad function scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "bad function scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1372); AnnotateMozCrashReason("MOZ_CRASH(" "bad function scope BindingKind"
")"); do { *((volatile int*)__null) = 1372; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1373 break;
1374 }
1375 }
1376
1377 FunctionScope::ParserData* bindings = nullptr;
1378 uint32_t numBindings =
1379 positionalFormals.length() + formals.length() + vars.length();
1380
1381 if (numBindings > 0) {
1382 bindings = NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
1383 if (!bindings) {
1384 return Nothing();
1385 }
1386
1387 // The ordering here is important. See comments in FunctionScope.
1388 InitializeBindingData(
1389 bindings, numBindings, positionalFormals,
1390 &ParserFunctionScopeSlotInfo::nonPositionalFormalStart, formals,
1391 &ParserFunctionScopeSlotInfo::varStart, vars);
1392 }
1393
1394 return Some(bindings);
1395}
1396
1397// Compute if `NewFunctionScopeData` would return any binding list with any
1398// entry marked as closed-over. This is done without the need to allocate the
1399// binding list. If true, an EnvironmentObject will be needed at runtime.
1400bool FunctionScopeHasClosedOverBindings(ParseContext* pc) {
1401 bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver() ||
1402 pc->functionScope().tooBigToOptimize();
1403
1404 for (BindingIter bi = pc->functionScope().bindings(pc); bi; bi++) {
1405 switch (bi.kind()) {
1406 case BindingKind::FormalParameter:
1407 case BindingKind::Var:
1408 if (allBindingsClosedOver || bi.closedOver()) {
1409 return true;
1410 }
1411 break;
1412
1413 default:
1414 break;
1415 }
1416 }
1417
1418 return false;
1419}
1420
1421Maybe<FunctionScope::ParserData*> ParserBase::newFunctionScopeData(
1422 ParseContext::Scope& scope, bool hasParameterExprs) {
1423 return NewFunctionScopeData(fc_, scope, hasParameterExprs, stencilAlloc(),
1424 pc_);
1425}
1426
1427VarScope::ParserData* NewEmptyVarScopeData(FrontendContext* fc,
1428 LifoAlloc& alloc,
1429 uint32_t numBindings) {
1430 return NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
1431}
1432
1433static Maybe<VarScope::ParserData*> NewVarScopeData(FrontendContext* fc,
1434 ParseContext::Scope& scope,
1435 LifoAlloc& alloc,
1436 ParseContext* pc) {
1437 ParserBindingNameVector vars(fc);
1438
1439 bool allBindingsClosedOver =
1440 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1441
1442 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1443 if (bi.kind() == BindingKind::Var) {
1444 ParserBindingName binding(bi.name(),
1445 allBindingsClosedOver || bi.closedOver());
1446 if (!vars.append(binding)) {
1447 return Nothing();
1448 }
1449 } else {
1450 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1452); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1452; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1451 bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1452); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1452; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1452 "bad var scope BindingKind")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1452); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1452; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1453 }
1454 }
1455
1456 VarScope::ParserData* bindings = nullptr;
1457 uint32_t numBindings = vars.length();
1458
1459 if (numBindings > 0) {
1460 bindings = NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
1461 if (!bindings) {
1462 return Nothing();
1463 }
1464
1465 InitializeBindingData(bindings, numBindings, vars);
1466 }
1467
1468 return Some(bindings);
1469}
1470
1471// Compute if `NewVarScopeData` would return any binding list. This is done
1472// without allocate the binding list.
1473static bool VarScopeHasBindings(ParseContext* pc) {
1474 for (BindingIter bi = pc->varScope().bindings(pc); bi; bi++) {
1475 if (bi.kind() == BindingKind::Var) {
1476 return true;
1477 }
1478 }
1479
1480 return false;
1481}
1482
1483Maybe<VarScope::ParserData*> ParserBase::newVarScopeData(
1484 ParseContext::Scope& scope) {
1485 return NewVarScopeData(fc_, scope, stencilAlloc(), pc_);
1486}
1487
1488static Maybe<LexicalScope::ParserData*> NewLexicalScopeData(
1489 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1490 ParseContext* pc) {
1491 ParserBindingNameVector lets(fc);
1492 ParserBindingNameVector consts(fc);
1493#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1494 ParserBindingNameVector usings(fc);
1495#endif
1496
1497 bool allBindingsClosedOver =
1498 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1499
1500 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1501 ParserBindingName binding(bi.name(),
1502 allBindingsClosedOver || bi.closedOver());
1503 switch (bi.kind()) {
1504 case BindingKind::Let:
1505 if (!lets.append(binding)) {
1506 return Nothing();
1507 }
1508 break;
1509 case BindingKind::Const:
1510 if (!consts.append(binding)) {
1511 return Nothing();
1512 }
1513 break;
1514#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1515 case BindingKind::Using:
1516 if (!usings.append(binding)) {
1517 return Nothing();
1518 }
1519 break;
1520#endif
1521 case BindingKind::Var:
1522 case BindingKind::FormalParameter:
1523 break;
1524 default:
1525 MOZ_CRASH("Bad lexical scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "Bad lexical scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1525); AnnotateMozCrashReason("MOZ_CRASH(" "Bad lexical scope BindingKind"
")"); do { *((volatile int*)__null) = 1525; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1526 break;
1527 }
1528 }
1529
1530 LexicalScope::ParserData* bindings = nullptr;
1531 uint32_t numBindings = lets.length() + consts.length()
1532#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1533 + usings.length()
1534#endif
1535 ;
1536
1537 if (numBindings > 0) {
1538 bindings = NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
1539 if (!bindings) {
1540 return Nothing();
1541 }
1542
1543 // The ordering here is important. See comments in LexicalScope.
1544 InitializeBindingData(bindings, numBindings, lets,
1545 &ParserLexicalScopeSlotInfo::constStart, consts
1546#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
1547 ,
1548 &ParserLexicalScopeSlotInfo::usingStart, usings
1549#endif
1550 );
1551 }
1552
1553 return Some(bindings);
1554}
1555
1556// Compute if `NewLexicalScopeData` would return any binding list with any entry
1557// marked as closed-over. This is done without the need to allocate the binding
1558// list. If true, an EnvironmentObject will be needed at runtime.
1559bool LexicalScopeHasClosedOverBindings(ParseContext* pc,
1560 ParseContext::Scope& scope) {
1561 bool allBindingsClosedOver =
1562 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1563
1564 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1565 switch (bi.kind()) {
1566 case BindingKind::Let:
1567 case BindingKind::Const:
1568 if (allBindingsClosedOver || bi.closedOver()) {
1569 return true;
1570 }
1571 break;
1572
1573 default:
1574 break;
1575 }
1576 }
1577
1578 return false;
1579}
1580
1581Maybe<LexicalScope::ParserData*> ParserBase::newLexicalScopeData(
1582 ParseContext::Scope& scope) {
1583 return NewLexicalScopeData(fc_, scope, stencilAlloc(), pc_);
1584}
1585
1586static Maybe<ClassBodyScope::ParserData*> NewClassBodyScopeData(
1587 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1588 ParseContext* pc) {
1589 ParserBindingNameVector privateBrand(fc);
1590 ParserBindingNameVector synthetics(fc);
1591 ParserBindingNameVector privateMethods(fc);
1592
1593 bool allBindingsClosedOver =
1594 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1595
1596 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1597 ParserBindingName binding(bi.name(),
1598 allBindingsClosedOver || bi.closedOver());
1599 switch (bi.kind()) {
1600 case BindingKind::Synthetic:
1601 if (bi.name() ==
1602 TaggedParserAtomIndex::WellKnown::dot_privateBrand_()) {
1603 MOZ_ASSERT(privateBrand.empty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(privateBrand.empty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(privateBrand.empty()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("privateBrand.empty()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1603); AnnotateMozCrashReason("MOZ_ASSERT" "(" "privateBrand.empty()"
")"); do { *((volatile int*)__null) = 1603; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1604 if (!privateBrand.append(binding)) {
1605 return Nothing();
1606 }
1607 } else {
1608 if (!synthetics.append(binding)) {
1609 return Nothing();
1610 }
1611 }
1612 break;
1613
1614 case BindingKind::PrivateMethod:
1615 if (!privateMethods.append(binding)) {
1616 return Nothing();
1617 }
1618 break;
1619
1620 default:
1621 MOZ_CRASH("bad class body scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "bad class body scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1621); AnnotateMozCrashReason("MOZ_CRASH(" "bad class body scope BindingKind"
")"); do { *((volatile int*)__null) = 1621; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1622 break;
1623 }
1624 }
1625
1626 // We should have zero or one private brands.
1627 MOZ_ASSERT(privateBrand.length() == 0 || privateBrand.length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(privateBrand.length() == 0 || privateBrand.length() ==
1)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(privateBrand.length() == 0 || privateBrand.length() ==
1))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("privateBrand.length() == 0 || privateBrand.length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1627); AnnotateMozCrashReason("MOZ_ASSERT" "(" "privateBrand.length() == 0 || privateBrand.length() == 1"
")"); do { *((volatile int*)__null) = 1627; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1628
1629 ClassBodyScope::ParserData* bindings = nullptr;
1630 uint32_t numBindings =
1631 privateBrand.length() + synthetics.length() + privateMethods.length();
1632
1633 if (numBindings > 0) {
1634 bindings = NewEmptyBindingData<ClassBodyScope>(fc, alloc, numBindings);
1635 if (!bindings) {
1636 return Nothing();
1637 }
1638 // To simplify initialization of the bindings, we concatenate the
1639 // synthetics+privateBrand vector such that the private brand is always the
1640 // first element, as ordering is important. See comments in ClassBodyScope.
1641 ParserBindingNameVector brandAndSynthetics(fc);
1642 if (!brandAndSynthetics.appendAll(privateBrand)) {
1643 return Nothing();
1644 }
1645 if (!brandAndSynthetics.appendAll(synthetics)) {
1646 return Nothing();
1647 }
1648
1649 // The ordering here is important. See comments in ClassBodyScope.
1650 InitializeBindingData(bindings, numBindings, brandAndSynthetics,
1651 &ParserClassBodyScopeSlotInfo::privateMethodStart,
1652 privateMethods);
1653 }
1654
1655 // `EmitterScope::lookupPrivate()` requires `.privateBrand` to be stored in a
1656 // predictable slot: the first slot available in the environment object,
1657 // `ClassBodyLexicalEnvironmentObject::privateBrandSlot()`. We assume that
1658 // if `.privateBrand` is first in the scope, it will be stored there.
1659 MOZ_ASSERT_IF(!privateBrand.empty(),do { if (!privateBrand.empty()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(GetScopeDataTrailingNames
(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex
::WellKnown::dot_privateBrand_()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1660 GetScopeDataTrailingNames(bindings)[0].name() ==do { if (!privateBrand.empty()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(GetScopeDataTrailingNames
(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex
::WellKnown::dot_privateBrand_()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1661 TaggedParserAtomIndex::WellKnown::dot_privateBrand_())do { if (!privateBrand.empty()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(GetScopeDataTrailingNames
(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex
::WellKnown::dot_privateBrand_()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1661); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1661; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1662
1663 return Some(bindings);
1664}
1665
1666Maybe<ClassBodyScope::ParserData*> ParserBase::newClassBodyScopeData(
1667 ParseContext::Scope& scope) {
1668 return NewClassBodyScopeData(fc_, scope, stencilAlloc(), pc_);
1669}
1670
1671template <>
1672SyntaxParseHandler::LexicalScopeNodeResult
1673PerHandlerParser<SyntaxParseHandler>::finishLexicalScope(
1674 ParseContext::Scope& scope, Node body, ScopeKind kind) {
1675 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1676 return errorResult();
1677 }
1678
1679 return handler_.newLexicalScope(body);
1680}
1681
1682template <>
1683FullParseHandler::LexicalScopeNodeResult
1684PerHandlerParser<FullParseHandler>::finishLexicalScope(
1685 ParseContext::Scope& scope, ParseNode* body, ScopeKind kind) {
1686 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1687 return errorResult();
1688 }
1689
1690 Maybe<LexicalScope::ParserData*> bindings = newLexicalScopeData(scope);
1691 if (!bindings) {
1692 return errorResult();
1693 }
1694
1695 return handler_.newLexicalScope(*bindings, body, kind);
1696}
1697
1698template <>
1699SyntaxParseHandler::ClassBodyScopeNodeResult
1700PerHandlerParser<SyntaxParseHandler>::finishClassBodyScope(
1701 ParseContext::Scope& scope, ListNodeType body) {
1702 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1703 return errorResult();
1704 }
1705
1706 return handler_.newClassBodyScope(body);
1707}
1708
1709template <>
1710FullParseHandler::ClassBodyScopeNodeResult
1711PerHandlerParser<FullParseHandler>::finishClassBodyScope(
1712 ParseContext::Scope& scope, ListNode* body) {
1713 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1714 return errorResult();
1715 }
1716
1717 Maybe<ClassBodyScope::ParserData*> bindings = newClassBodyScopeData(scope);
1718 if (!bindings) {
1719 return errorResult();
1720 }
1721
1722 return handler_.newClassBodyScope(*bindings, body);
1723}
1724
1725template <class ParseHandler>
1726bool PerHandlerParser<ParseHandler>::checkForUndefinedPrivateFields(
1727 EvalSharedContext* evalSc) {
1728 if (!this->compilationState_.isInitialStencil()) {
1729 // We're delazifying -- so we already checked private names during first
1730 // parse.
1731 return true;
1732 }
1733
1734 Vector<UnboundPrivateName, 8> unboundPrivateNames(fc_);
1735 if (!usedNames_.getUnboundPrivateNames(unboundPrivateNames)) {
1736 return false;
1737 }
1738
1739 // No unbound names, let's get out of here!
1740 if (unboundPrivateNames.empty()) {
1741 return true;
1742 }
1743
1744 // It is an early error if there's private name references unbound,
1745 // unless it's an eval, in which case we need to check the scope
1746 // chain.
1747 if (!evalSc) {
1748 // The unbound private names are sorted, so just grab the first one.
1749 UnboundPrivateName minimum = unboundPrivateNames[0];
1750 UniqueChars str = this->parserAtoms().toPrintableString(minimum.atom);
1751 if (!str) {
1752 ReportOutOfMemory(this->fc_);
1753 return false;
1754 }
1755
1756 errorAt(minimum.position.begin, JSMSG_MISSING_PRIVATE_DECL, str.get());
1757 return false;
1758 }
1759
1760 // It's important that the unbound private names are sorted, as we
1761 // want our errors to always be issued to the first textually.
1762 for (UnboundPrivateName unboundName : unboundPrivateNames) {
1763 // If the enclosingScope is non-syntactic, then we are in a
1764 // Debugger.Frame.prototype.eval call. In order to find the declared private
1765 // names, we must use the effective scope that was determined when creating
1766 // the scopeContext.
1767 if (!this->compilationState_.scopeContext
1768 .effectiveScopePrivateFieldCacheHas(unboundName.atom)) {
1769 UniqueChars str = this->parserAtoms().toPrintableString(unboundName.atom);
1770 if (!str) {
1771 ReportOutOfMemory(this->fc_);
1772 return false;
1773 }
1774 errorAt(unboundName.position.begin, JSMSG_MISSING_PRIVATE_DECL,
1775 str.get());
1776 return false;
1777 }
1778 }
1779
1780 return true;
1781}
1782
1783template <typename Unit>
1784FullParseHandler::LexicalScopeNodeResult
1785Parser<FullParseHandler, Unit>::evalBody(EvalSharedContext* evalsc) {
1786 SourceParseContext evalpc(this, evalsc, /* newDirectives = */ nullptr);
1787 if (!evalpc.init()) {
1788 return errorResult();
1789 }
1790
1791 ParseContext::VarScope varScope(this);
1792 if (!varScope.init(pc_)) {
1793 return errorResult();
1794 }
1795
1796 LexicalScopeNode* body;
1797 {
1798 // All evals have an implicit non-extensible lexical scope.
1799 ParseContext::Scope lexicalScope(this);
1800 if (!lexicalScope.init(pc_)) {
1801 return errorResult();
1802 }
1803
1804 ListNode* list;
1805 MOZ_TRY_VAR(list, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (list) = mozTryVarTempResult_
.unwrap(); } while (0)
;
1806
1807 if (!checkStatementsEOF()) {
1808 return errorResult();
1809 }
1810
1811 // Private names not lexically defined must trigger a syntax error.
1812 if (!checkForUndefinedPrivateFields(evalsc)) {
1813 return errorResult();
1814 }
1815
1816 MOZ_TRY_VAR(body, finishLexicalScope(lexicalScope, list))do { auto mozTryVarTempResult_ = (finishLexicalScope(lexicalScope
, list)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (body
) = mozTryVarTempResult_.unwrap(); } while (0)
;
1817 }
1818
1819#ifdef DEBUG1
1820 if (evalpc.superScopeNeedsHomeObject() &&
1821 !this->compilationState_.input.enclosingScope.isNull()) {
1822 // If superScopeNeedsHomeObject_ is set and we are an entry-point
1823 // ParseContext, then we must be emitting an eval script, and the
1824 // outer function must already be marked as needing a home object
1825 // since it contains an eval.
1826 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1829; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1827 this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1829; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1828 "Eval must have found an enclosing function box scope that "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1829; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1829 "allows super.property")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1829); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1829; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
1830 }
1831#endif
1832
1833 if (!CheckParseTree(this->fc_, alloc_, body)) {
1834 return errorResult();
1835 }
1836
1837 ParseNode* node = body;
1838 // Don't constant-fold inside "use asm" code, as this could create a parse
1839 // tree that doesn't type-check as asm.js.
1840 if (!pc_->useAsmOrInsideUseAsm()) {
1841 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
1842 return errorResult();
1843 }
1844 }
1845 body = handler_.asLexicalScopeNode(node);
1846
1847 if (!this->setSourceMapInfo()) {
1848 return errorResult();
1849 }
1850
1851 if (pc_->sc()->strict()) {
1852 if (!propagateFreeNamesAndMarkClosedOverBindings(varScope)) {
1853 return errorResult();
1854 }
1855 } else {
1856 // For non-strict eval scripts, since all bindings are automatically
1857 // considered closed over, we don't need to call propagateFreeNames-
1858 // AndMarkClosedOverBindings. However, Annex B.3.3 functions still need to
1859 // be marked.
1860 if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
1861 return errorResult();
1862 }
1863 }
1864
1865 Maybe<EvalScope::ParserData*> bindings = newEvalScopeData(pc_->varScope());
1866 if (!bindings) {
1867 return errorResult();
1868 }
1869 evalsc->bindings = *bindings;
1870
1871 return body;
1872}
1873
1874template <typename Unit>
1875FullParseHandler::ListNodeResult Parser<FullParseHandler, Unit>::globalBody(
1876 GlobalSharedContext* globalsc) {
1877 SourceParseContext globalpc(this, globalsc, /* newDirectives = */ nullptr);
1878 if (!globalpc.init()) {
1879 return errorResult();
1880 }
1881
1882 ParseContext::VarScope varScope(this);
1883 if (!varScope.init(pc_)) {
1884 return errorResult();
1885 }
1886
1887 ListNode* body;
1888 MOZ_TRY_VAR(body, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
1889
1890 if (!checkStatementsEOF()) {
1891 return errorResult();
1892 }
1893
1894 if (!CheckParseTree(this->fc_, alloc_, body)) {
1895 return errorResult();
1896 }
1897
1898 if (!checkForUndefinedPrivateFields()) {
1899 return errorResult();
1900 }
1901
1902 ParseNode* node = body;
1903 // Don't constant-fold inside "use asm" code, as this could create a parse
1904 // tree that doesn't type-check as asm.js.
1905 if (!pc_->useAsmOrInsideUseAsm()) {
1906 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
1907 return errorResult();
1908 }
1909 }
1910 body = &node->as<ListNode>();
1911
1912 if (!this->setSourceMapInfo()) {
1913 return errorResult();
1914 }
1915
1916 // For global scripts, whether bindings are closed over or not doesn't
1917 // matter, so no need to call propagateFreeNamesAndMarkClosedOver-
1918 // Bindings. However, Annex B.3.3 functions still need to be marked.
1919 if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
1920 return errorResult();
1921 }
1922
1923 Maybe<GlobalScope::ParserData*> bindings =
1924 newGlobalScopeData(pc_->varScope());
1925 if (!bindings) {
1926 return errorResult();
1927 }
1928 globalsc->bindings = *bindings;
1929
1930 return body;
1931}
1932
1933template <typename Unit>
1934FullParseHandler::ModuleNodeResult Parser<FullParseHandler, Unit>::moduleBody(
1935 ModuleSharedContext* modulesc) {
1936 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1936); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 1936; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1937
1938 this->compilationState_.moduleMetadata =
1939 fc_->getAllocator()->template new_<StencilModuleMetadata>();
1940 if (!this->compilationState_.moduleMetadata) {
1941 return errorResult();
1942 }
1943
1944 SourceParseContext modulepc(this, modulesc, nullptr);
1945 if (!modulepc.init()) {
1946 return errorResult();
1947 }
1948
1949 ParseContext::VarScope varScope(this);
1950 if (!varScope.init(pc_)) {
1951 return errorResult();
1952 }
1953
1954 ModuleNodeType moduleNode;
1955 MOZ_TRY_VAR(moduleNode, handler_.newModule(pos()))do { auto mozTryVarTempResult_ = (handler_.newModule(pos()));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (moduleNode)
= mozTryVarTempResult_.unwrap(); } while (0)
;
1956
1957 AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(
1958 this, AwaitIsModuleKeyword);
1959 ListNode* stmtList;
1960 MOZ_TRY_VAR(stmtList, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (stmtList) =
mozTryVarTempResult_.unwrap(); } while (0)
;
1961
1962 MOZ_ASSERT(stmtList->isKind(ParseNodeKind::StatementList))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(stmtList->isKind(ParseNodeKind::StatementList))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(stmtList->isKind(ParseNodeKind::StatementList))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("stmtList->isKind(ParseNodeKind::StatementList)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1962); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stmtList->isKind(ParseNodeKind::StatementList)"
")"); do { *((volatile int*)__null) = 1962; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1963 moduleNode->setBody(&stmtList->template as<ListNode>());
1964
1965 if (pc_->isAsync()) {
1966 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_generator_())) {
1967 return errorResult();
1968 }
1969
1970 if (!pc_->declareTopLevelDotGeneratorName()) {
1971 return errorResult();
1972 }
1973 }
1974
1975 TokenKind tt;
1976 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
1977 return errorResult();
1978 }
1979 if (tt != TokenKind::Eof) {
1980 error(JSMSG_GARBAGE_AFTER_INPUT, "module", TokenKindToDesc(tt));
1981 return errorResult();
1982 }
1983
1984 // Set the module to async if an await keyword was found at the top level.
1985 if (pc_->isAsync()) {
1986 pc_->sc()->asModuleContext()->builder.noteAsync(
1987 *this->compilationState_.moduleMetadata);
1988 }
1989
1990 // Generate the Import/Export tables and store in CompilationState.
1991 if (!modulesc->builder.buildTables(*this->compilationState_.moduleMetadata)) {
1992 return errorResult();
1993 }
1994
1995 // Check exported local bindings exist and mark them as closed over.
1996 StencilModuleMetadata& moduleMetadata =
1997 *this->compilationState_.moduleMetadata;
1998 for (auto entry : moduleMetadata.localExportEntries) {
1999 DeclaredNamePtr p = modulepc.varScope().lookupDeclaredName(entry.localName);
2000 if (!p) {
2001 UniqueChars str = this->parserAtoms().toPrintableString(entry.localName);
2002 if (!str) {
2003 ReportOutOfMemory(this->fc_);
2004 return errorResult();
2005 }
2006
2007 errorNoOffset(JSMSG_MISSING_EXPORT, str.get());
2008 return errorResult();
2009 }
2010
2011 p->value()->setClosedOver();
2012 }
2013
2014 // Reserve an environment slot for a "*namespace*" psuedo-binding and mark as
2015 // closed-over. We do not know until module linking if this will be used.
2016 if (!noteDeclaredName(
2017 TaggedParserAtomIndex::WellKnown::star_namespace_star_(),
2018 DeclarationKind::Const, pos())) {
2019 return errorResult();
2020 }
2021 modulepc.varScope()
2022 .lookupDeclaredName(
2023 TaggedParserAtomIndex::WellKnown::star_namespace_star_())
2024 ->value()
2025 ->setClosedOver();
2026
2027 if (options().deoptimizeModuleGlobalVars) {
2028 for (BindingIter bi = modulepc.varScope().bindings(pc_); bi; bi++) {
2029 bi.setClosedOver();
2030 }
2031 }
2032
2033 if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
2034 return errorResult();
2035 }
2036
2037 ParseNode* node = stmtList;
2038 // Don't constant-fold inside "use asm" code, as this could create a parse
2039 // tree that doesn't type-check as asm.js.
2040 if (!pc_->useAsmOrInsideUseAsm()) {
2041 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
2042 return errorResult();
2043 }
2044 }
2045 stmtList = &node->as<ListNode>();
2046
2047 if (!this->setSourceMapInfo()) {
2048 return errorResult();
2049 }
2050
2051 // Private names not lexically defined must trigger a syntax error.
2052 if (!checkForUndefinedPrivateFields()) {
2053 return errorResult();
2054 }
2055
2056 if (!propagateFreeNamesAndMarkClosedOverBindings(modulepc.varScope())) {
2057 return errorResult();
2058 }
2059
2060 Maybe<ModuleScope::ParserData*> bindings =
2061 newModuleScopeData(modulepc.varScope());
2062 if (!bindings) {
2063 return errorResult();
2064 }
2065
2066 modulesc->bindings = *bindings;
2067 return moduleNode;
2068}
2069
2070template <typename Unit>
2071SyntaxParseHandler::ModuleNodeResult
2072Parser<SyntaxParseHandler, Unit>::moduleBody(ModuleSharedContext* modulesc) {
2073 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2073); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 2073; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
2074 return errorResult();
2075}
2076
2077template <class ParseHandler>
2078typename ParseHandler::NameNodeResult
2079PerHandlerParser<ParseHandler>::newInternalDotName(TaggedParserAtomIndex name) {
2080 NameNodeType nameNode;
2081 MOZ_TRY_VAR(nameNode, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nameNode) = mozTryVarTempResult_.unwrap()
; } while (0)
;
2082 if (!noteUsedName(name)) {
2083 return errorResult();
2084 }
2085 return nameNode;
2086}
2087
2088template <class ParseHandler>
2089typename ParseHandler::NameNodeResult
2090PerHandlerParser<ParseHandler>::newThisName() {
2091 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_this_());
2092}
2093
2094template <class ParseHandler>
2095typename ParseHandler::NameNodeResult
2096PerHandlerParser<ParseHandler>::newNewTargetName() {
2097 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_newTarget_());
2098}
2099
2100template <class ParseHandler>
2101typename ParseHandler::NameNodeResult
2102PerHandlerParser<ParseHandler>::newDotGeneratorName() {
2103 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_generator_());
2104}
2105
2106template <class ParseHandler>
2107bool PerHandlerParser<ParseHandler>::finishFunctionScopes(
2108 bool isStandaloneFunction) {
2109 FunctionBox* funbox = pc_->functionBox();
2110
2111 if (funbox->hasParameterExprs) {
2112 if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->functionScope())) {
2113 return false;
2114 }
2115
2116 // Functions with parameter expressions utilize the FunctionScope for vars
2117 // generated by sloppy-direct-evals, as well as arguments (which are
2118 // lexicals bindings). If the function body has var bindings (or has a
2119 // sloppy-direct-eval that might), then an extra VarScope must be created
2120 // for them.
2121 if (VarScopeHasBindings(pc_) ||
2122 funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings()) {
2123 funbox->setFunctionHasExtraBodyVarScope();
2124 }
2125 }
2126
2127 // See: JSFunction::needsCallObject()
2128 if (FunctionScopeHasClosedOverBindings(pc_) ||
2129 funbox->needsCallObjectRegardlessOfBindings()) {
2130 funbox->setNeedsFunctionEnvironmentObjects();
2131 }
2132
2133 if (funbox->isNamedLambda() && !isStandaloneFunction) {
2134 if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->namedLambdaScope())) {
2135 return false;
2136 }
2137
2138 // See: JSFunction::needsNamedLambdaEnvironment()
2139 if (LexicalScopeHasClosedOverBindings(pc_, pc_->namedLambdaScope())) {
2140 funbox->setNeedsFunctionEnvironmentObjects();
2141 }
2142 }
2143
2144 return true;
2145}
2146
2147template <>
2148bool PerHandlerParser<FullParseHandler>::finishFunction(
2149 bool isStandaloneFunction /* = false */) {
2150 if (!finishFunctionScopes(isStandaloneFunction)) {
2151 return false;
2152 }
2153
2154 FunctionBox* funbox = pc_->functionBox();
2155 ScriptStencil& script = funbox->functionStencil();
2156
2157 if (funbox->isInterpreted()) {
2158 // BCE will need to generate bytecode for this.
2159 funbox->emitBytecode = true;
2160 this->compilationState_.nonLazyFunctionCount++;
2161 }
2162
2163 bool hasParameterExprs = funbox->hasParameterExprs;
2164
2165 if (hasParameterExprs) {
2166 Maybe<VarScope::ParserData*> bindings = newVarScopeData(pc_->varScope());
2167 if (!bindings) {
2168 return false;
2169 }
2170 funbox->setExtraVarScopeBindings(*bindings);
2171
2172 MOZ_ASSERT(bool(*bindings) == VarScopeHasBindings(pc_))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bool(*bindings) == VarScopeHasBindings(pc_))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(bool(*bindings) == VarScopeHasBindings(pc_)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("bool(*bindings) == VarScopeHasBindings(pc_)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2172); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == VarScopeHasBindings(pc_)"
")"); do { *((volatile int*)__null) = 2172; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2173 MOZ_ASSERT_IF(!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings(),do { if (!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings
()) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(bool(*bindings) == funbox->functionHasExtraBodyVarScope
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bool(*bindings) == funbox->functionHasExtraBodyVarScope
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2174); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
")"); do { *((volatile int*)__null) = 2174; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2174 bool(*bindings) == funbox->functionHasExtraBodyVarScope())do { if (!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings
()) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(bool(*bindings) == funbox->functionHasExtraBodyVarScope
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bool(*bindings) == funbox->functionHasExtraBodyVarScope
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2174); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
")"); do { *((volatile int*)__null) = 2174; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2175 }
2176
2177 {
2178 Maybe<FunctionScope::ParserData*> bindings =
2179 newFunctionScopeData(pc_->functionScope(), hasParameterExprs);
2180 if (!bindings) {
2181 return false;
2182 }
2183 funbox->setFunctionScopeBindings(*bindings);
2184 }
2185
2186 if (funbox->isNamedLambda() && !isStandaloneFunction) {
2187 Maybe<LexicalScope::ParserData*> bindings =
2188 newLexicalScopeData(pc_->namedLambdaScope());
2189 if (!bindings) {
2190 return false;
2191 }
2192 funbox->setNamedLambdaBindings(*bindings);
2193 }
2194
2195 funbox->finishScriptFlags();
2196 funbox->copyFunctionFields(script);
2197
2198 if (this->compilationState_.isInitialStencil()) {
2199 ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
2200 funbox->copyFunctionExtraFields(scriptExtra);
2201 funbox->copyScriptExtraFields(scriptExtra);
2202 }
2203
2204 return true;
2205}
2206
2207template <>
2208bool PerHandlerParser<SyntaxParseHandler>::finishFunction(
2209 bool isStandaloneFunction /* = false */) {
2210 // The BaseScript for a lazily parsed function needs to know its set of
2211 // free variables and inner functions so that when it is fully parsed, we
2212 // can skip over any already syntax parsed inner functions and still
2213 // retain correct scope information.
2214
2215 if (!finishFunctionScopes(isStandaloneFunction)) {
2216 return false;
2217 }
2218
2219 FunctionBox* funbox = pc_->functionBox();
2220 ScriptStencil& script = funbox->functionStencil();
2221
2222 funbox->finishScriptFlags();
2223 funbox->copyFunctionFields(script);
2224
2225 ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
2226 funbox->copyFunctionExtraFields(scriptExtra);
2227 funbox->copyScriptExtraFields(scriptExtra);
2228
2229 // Elide nullptr sentinels from end of binding list. These are inserted for
2230 // each scope regardless of if any bindings are actually closed over.
2231 {
2232 AtomVector& closedOver = pc_->closedOverBindingsForLazy();
2233 while (!closedOver.empty() && !closedOver.back()) {
2234 closedOver.popBack();
2235 }
2236 }
2237
2238 // Check if we will overflow the `ngcthings` field later.
2239 mozilla::CheckedUint32 ngcthings =
2240 mozilla::CheckedUint32(pc_->innerFunctionIndexesForLazy.length()) +
2241 mozilla::CheckedUint32(pc_->closedOverBindingsForLazy().length());
2242 if (!ngcthings.isValid()) {
2243 ReportAllocationOverflow(fc_);
2244 return false;
2245 }
2246
2247 // If there are no script-things, we can return early without allocating.
2248 if (ngcthings.value() == 0) {
2249 MOZ_ASSERT(!script.hasGCThings())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!script.hasGCThings())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!script.hasGCThings()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!script.hasGCThings()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2249); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!script.hasGCThings()"
")"); do { *((volatile int*)__null) = 2249; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2250 return true;
2251 }
2252
2253 TaggedScriptThingIndex* cursor = nullptr;
2254 if (!this->compilationState_.allocateGCThingsUninitialized(
2255 fc_, funbox->index(), ngcthings.value(), &cursor)) {
2256 return false;
2257 }
2258
2259 // Copy inner-function and closed-over-binding info for the stencil. The order
2260 // is important here. We emit functions first, followed by the bindings info.
2261 // The bindings list uses nullptr as delimiter to separates the bindings per
2262 // scope.
2263 //
2264 // See: FullParseHandler::nextLazyInnerFunction(),
2265 // FullParseHandler::nextLazyClosedOverBinding()
2266 for (const ScriptIndex& index : pc_->innerFunctionIndexesForLazy) {
2267 void* raw = &(*cursor++);
2268 new (raw) TaggedScriptThingIndex(index);
2269 }
2270 for (auto binding : pc_->closedOverBindingsForLazy()) {
2271 void* raw = &(*cursor++);
2272 if (binding) {
2273 this->parserAtoms().markUsedByStencil(binding, ParserAtom::Atomize::Yes);
2274 new (raw) TaggedScriptThingIndex(binding);
2275 } else {
2276 new (raw) TaggedScriptThingIndex();
2277 }
2278 }
2279
2280 return true;
2281}
2282
2283static YieldHandling GetYieldHandling(GeneratorKind generatorKind) {
2284 if (generatorKind == GeneratorKind::NotGenerator) {
2285 return YieldIsName;
2286 }
2287 return YieldIsKeyword;
2288}
2289
2290static AwaitHandling GetAwaitHandling(FunctionAsyncKind asyncKind) {
2291 if (asyncKind == FunctionAsyncKind::SyncFunction) {
2292 return AwaitIsName;
2293 }
2294 return AwaitIsKeyword;
2295}
2296
2297static FunctionFlags InitialFunctionFlags(FunctionSyntaxKind kind,
2298 GeneratorKind generatorKind,
2299 FunctionAsyncKind asyncKind,
2300 bool isSelfHosting) {
2301 FunctionFlags flags = {};
2302
2303 switch (kind) {
2304 case FunctionSyntaxKind::Expression:
2305 flags = (generatorKind == GeneratorKind::NotGenerator &&
2306 asyncKind == FunctionAsyncKind::SyncFunction
2307 ? FunctionFlags::INTERPRETED_LAMBDA
2308 : FunctionFlags::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC);
2309 break;
2310 case FunctionSyntaxKind::Arrow:
2311 flags = FunctionFlags::INTERPRETED_LAMBDA_ARROW;
2312 break;
2313 case FunctionSyntaxKind::Method:
2314 case FunctionSyntaxKind::FieldInitializer:
2315 case FunctionSyntaxKind::StaticClassBlock:
2316 flags = FunctionFlags::INTERPRETED_METHOD;
2317 break;
2318 case FunctionSyntaxKind::ClassConstructor:
2319 case FunctionSyntaxKind::DerivedClassConstructor:
2320 flags = FunctionFlags::INTERPRETED_CLASS_CTOR;
2321 break;
2322 case FunctionSyntaxKind::Getter:
2323 flags = FunctionFlags::INTERPRETED_GETTER;
2324 break;
2325 case FunctionSyntaxKind::Setter:
2326 flags = FunctionFlags::INTERPRETED_SETTER;
2327 break;
2328 default:
2329 MOZ_ASSERT(kind == FunctionSyntaxKind::Statement)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == FunctionSyntaxKind::Statement)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(kind == FunctionSyntaxKind::Statement))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("kind == FunctionSyntaxKind::Statement"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2329); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == FunctionSyntaxKind::Statement"
")"); do { *((volatile int*)__null) = 2329; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2330 flags = (generatorKind == GeneratorKind::NotGenerator &&
2331 asyncKind == FunctionAsyncKind::SyncFunction
2332 ? FunctionFlags::INTERPRETED_NORMAL
2333 : FunctionFlags::INTERPRETED_GENERATOR_OR_ASYNC);
2334 }
2335
2336 if (isSelfHosting) {
2337 flags.setIsSelfHostedBuiltin();
2338 }
2339
2340 return flags;
2341}
2342
2343template <typename Unit>
2344FullParseHandler::FunctionNodeResult
2345Parser<FullParseHandler, Unit>::standaloneFunction(
2346 const Maybe<uint32_t>& parameterListEnd, FunctionSyntaxKind syntaxKind,
2347 GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
2348 Directives inheritedDirectives, Directives* newDirectives) {
2349 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 2349; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2350 // Skip prelude.
2351 TokenKind tt;
2352 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2353 return errorResult();
2354 }
2355 if (asyncKind == FunctionAsyncKind::AsyncFunction) {
2356 MOZ_ASSERT(tt == TokenKind::Async)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::Async)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::Async))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("tt == TokenKind::Async"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2356); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Async"
")"); do { *((volatile int*)__null) = 2356; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2357 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2358 return errorResult();
2359 }
2360 }
2361 MOZ_ASSERT(tt == TokenKind::Function)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::Function)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::Function)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("tt == TokenKind::Function"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2361); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Function"
")"); do { *((volatile int*)__null) = 2361; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2362
2363 if (!tokenStream.getToken(&tt)) {
2364 return errorResult();
2365 }
2366 if (generatorKind == GeneratorKind::Generator) {
2367 MOZ_ASSERT(tt == TokenKind::Mul)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::Mul)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::Mul))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("tt == TokenKind::Mul"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2367); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Mul"
")"); do { *((volatile int*)__null) = 2367; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2368 if (!tokenStream.getToken(&tt)) {
2369 return errorResult();
2370 }
2371 }
2372
2373 // Skip function name, if present.
2374 TaggedParserAtomIndex explicitName;
2375 if (TokenKindIsPossibleIdentifierName(tt)) {
2376 explicitName = anyChars.currentName();
2377 } else {
2378 anyChars.ungetToken();
2379 }
2380
2381 FunctionNodeType funNode;
2382 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
2383
2384 ParamsBodyNodeType argsbody;
2385 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(pos()))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(pos(
))); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
2386 funNode->setBody(argsbody);
2387
2388 bool isSelfHosting = options().selfHostingMode;
2389 FunctionFlags flags =
2390 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
2391 FunctionBox* funbox =
2392 newFunctionBox(funNode, explicitName, flags, /* toStringStart = */ 0,
2393 inheritedDirectives, generatorKind, asyncKind);
2394 if (!funbox) {
2395 return errorResult();
2396 }
2397
2398 // Function is not syntactically part of another script.
2399 MOZ_ASSERT(funbox->index() == CompilationStencil::TopLevelIndex)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->index() == CompilationStencil::TopLevelIndex
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(funbox->index() == CompilationStencil::TopLevelIndex
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"funbox->index() == CompilationStencil::TopLevelIndex", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2399); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->index() == CompilationStencil::TopLevelIndex"
")"); do { *((volatile int*)__null) = 2399; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2400
2401 funbox->initStandalone(this->compilationState_.scopeContext, syntaxKind);
2402
2403 SourceParseContext funpc(this, funbox, newDirectives);
2404 if (!funpc.init()) {
2405 return errorResult();
2406 }
2407
2408 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
2409 AwaitHandling awaitHandling = GetAwaitHandling(asyncKind);
2410 AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(this,
2411 awaitHandling);
2412 if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
2413 syntaxKind, parameterListEnd,
2414 /* isStandaloneFunction = */ true)) {
2415 return errorResult();
2416 }
2417
2418 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2419 return errorResult();
2420 }
2421 if (tt != TokenKind::Eof) {
2422 error(JSMSG_GARBAGE_AFTER_INPUT, "function body", TokenKindToDesc(tt));
2423 return errorResult();
2424 }
2425
2426 if (!CheckParseTree(this->fc_, alloc_, funNode)) {
2427 return errorResult();
2428 }
2429
2430 ParseNode* node = funNode;
2431 // Don't constant-fold inside "use asm" code, as this could create a parse
2432 // tree that doesn't type-check as asm.js.
2433 if (!pc_->useAsmOrInsideUseAsm()) {
2434 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
2435 return errorResult();
2436 }
2437 }
2438 funNode = &node->as<FunctionNode>();
2439
2440 if (!checkForUndefinedPrivateFields(nullptr)) {
2441 return errorResult();
2442 }
2443
2444 if (!this->setSourceMapInfo()) {
2445 return errorResult();
2446 }
2447
2448 return funNode;
2449}
2450
2451template <class ParseHandler, typename Unit>
2452typename ParseHandler::LexicalScopeNodeResult
2453GeneralParser<ParseHandler, Unit>::functionBody(InHandling inHandling,
2454 YieldHandling yieldHandling,
2455 FunctionSyntaxKind kind,
2456 FunctionBodyType type) {
2457 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2457); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 2457; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2458
2459#ifdef DEBUG1
2460 uint32_t startYieldOffset = pc_->lastYieldOffset;
2461#endif
2462
2463 Node body;
2464 if (type == StatementListBody) {
2465 bool inheritedStrict = pc_->sc()->strict();
2466 MOZ_TRY_VAR(body, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
2467
2468 // When we transitioned from non-strict to strict mode, we need to
2469 // validate that all parameter names are valid strict mode names.
2470 if (!inheritedStrict && pc_->sc()->strict()) {
2471 MOZ_ASSERT(pc_->sc()->hasExplicitUseStrict(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2473; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2472 "strict mode should only change when a 'use strict' directive "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2473; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2473 "is present")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2473; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
2474 if (!hasValidSimpleStrictParameterNames()) {
2475 // Request that this function be reparsed as strict to report
2476 // the invalid parameter name at the correct source location.
2477 pc_->newDirectives->setStrict();
2478 return errorResult();
2479 }
2480 }
2481 } else {
2482 MOZ_ASSERT(type == ExpressionBody)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type == ExpressionBody)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(type == ExpressionBody))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("type == ExpressionBody"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2482); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == ExpressionBody"
")"); do { *((volatile int*)__null) = 2482; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2483
2484 // Async functions are implemented as generators, and generators are
2485 // assumed to be statement lists, to prepend initial `yield`.
2486 ListNodeType stmtList = null();
2487 if (pc_->isAsync()) {
2488 MOZ_TRY_VAR(stmtList, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
2489 }
2490
2491 Node kid;
2492 MOZ_TRY_VAR(kid,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
2493 assignExpr(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
2494
2495 MOZ_TRY_VAR(body, handler_.newExpressionBody(kid))do { auto mozTryVarTempResult_ = (handler_.newExpressionBody(
kid)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr())
, 0))) { return mozTryVarTempResult_.propagateErr(); } (body)
= mozTryVarTempResult_.unwrap(); } while (0)
;
2496
2497 if (pc_->isAsync()) {
2498 handler_.addStatementToList(stmtList, body);
2499 body = stmtList;
2500 }
2501 }
2502
2503 MOZ_ASSERT_IF(!pc_->isGenerator() && !pc_->isAsync(),do { if (!pc_->isGenerator() && !pc_->isAsync()
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(pc_->lastYieldOffset == startYieldOffset)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->lastYieldOffset == startYieldOffset))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("pc_->lastYieldOffset == startYieldOffset"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2504); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->lastYieldOffset == startYieldOffset"
")"); do { *((volatile int*)__null) = 2504; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2504 pc_->lastYieldOffset == startYieldOffset)do { if (!pc_->isGenerator() && !pc_->isAsync()
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(pc_->lastYieldOffset == startYieldOffset)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->lastYieldOffset == startYieldOffset))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("pc_->lastYieldOffset == startYieldOffset"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2504); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->lastYieldOffset == startYieldOffset"
")"); do { *((volatile int*)__null) = 2504; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2505 MOZ_ASSERT_IF(pc_->isGenerator(), kind != FunctionSyntaxKind::Arrow)do { if (pc_->isGenerator()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(kind != FunctionSyntaxKind
::Arrow)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind != FunctionSyntaxKind::Arrow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("kind != FunctionSyntaxKind::Arrow"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2505); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind != FunctionSyntaxKind::Arrow"
")"); do { *((volatile int*)__null) = 2505; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2506 MOZ_ASSERT_IF(pc_->isGenerator(), type == StatementListBody)do { if (pc_->isGenerator()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(type == StatementListBody
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == StatementListBody))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("type == StatementListBody", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2506); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == StatementListBody"
")"); do { *((volatile int*)__null) = 2506; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2507
2508 if (pc_->needsDotGeneratorName()) {
2509 MOZ_ASSERT_IF(!pc_->isAsync(), type == StatementListBody)do { if (!pc_->isAsync()) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(type == StatementListBody
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == StatementListBody))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("type == StatementListBody", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2509); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == StatementListBody"
")"); do { *((volatile int*)__null) = 2509; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2510 if (!pc_->declareDotGeneratorName()) {
2511 return errorResult();
2512 }
2513 if (pc_->isGenerator()) {
2514 NameNodeType generator;
2515 MOZ_TRY_VAR(generator, newDotGeneratorName())do { auto mozTryVarTempResult_ = (newDotGeneratorName()); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (generator) = mozTryVarTempResult_
.unwrap(); } while (0)
;
2516 if (!handler_.prependInitialYield(handler_.asListNode(body), generator)) {
2517 return errorResult();
2518 }
2519 }
2520 }
2521
2522 if (pc_->numberOfArgumentsNames > 0 || kind == FunctionSyntaxKind::Arrow) {
2523 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2523); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 2523; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2524 pc_->sc()->setIneligibleForArgumentsLength();
2525 }
2526
2527 // Declare the 'arguments', 'this', and 'new.target' bindings if necessary
2528 // before finishing up the scope so these special bindings get marked as
2529 // closed over if necessary. Arrow functions don't have these bindings.
2530 if (kind != FunctionSyntaxKind::Arrow) {
2531 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
2532 if (!pc_->declareFunctionArgumentsObject(usedNames_,
2533 canSkipLazyClosedOverBindings)) {
2534 return errorResult();
2535 }
2536 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
2537 return errorResult();
2538 }
2539 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
2540 return errorResult();
2541 }
2542 }
2543
2544 return finishLexicalScope(pc_->varScope(), body, ScopeKind::FunctionLexical);
2545}
2546
2547template <class ParseHandler, typename Unit>
2548bool GeneralParser<ParseHandler, Unit>::matchOrInsertSemicolon(
2549 Modifier modifier /* = TokenStream::SlashIsRegExp */) {
2550 TokenKind tt = TokenKind::Eof;
2551 if (!tokenStream.peekTokenSameLine(&tt, modifier)) {
2552 return false;
2553 }
2554 if (tt != TokenKind::Eof && tt != TokenKind::Eol && tt != TokenKind::Semi &&
2555 tt != TokenKind::RightCurly) {
2556 /*
2557 * When current token is `await` and it's outside of async function,
2558 * it's possibly intended to be an await expression.
2559 *
2560 * await f();
2561 * ^
2562 * |
2563 * tried to insert semicolon here
2564 *
2565 * Detect this situation and throw an understandable error. Otherwise
2566 * we'd throw a confusing "unexpected token: (unexpected token)" error.
2567 */
2568 if (!pc_->isAsync() && anyChars.currentToken().type == TokenKind::Await) {
2569 error(JSMSG_AWAIT_OUTSIDE_ASYNC_OR_MODULE);
2570 return false;
2571 }
2572 if (!yieldExpressionsSupported() &&
2573 anyChars.currentToken().type == TokenKind::Yield) {
2574 error(JSMSG_YIELD_OUTSIDE_GENERATOR);
2575 return false;
2576 }
2577
2578#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
2579 if (!this->pc_->isUsingSyntaxAllowed() &&
2580 anyChars.currentToken().type == TokenKind::Using) {
2581 error(JSMSG_USING_OUTSIDE_BLOCK_OR_MODULE);
2582 return false;
2583 }
2584#endif
2585
2586 /* Advance the scanner for proper error location reporting. */
2587 tokenStream.consumeKnownToken(tt, modifier);
2588 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(tt));
2589 return false;
2590 }
2591 bool matched;
2592 return tokenStream.matchToken(&matched, TokenKind::Semi, modifier);
2593}
2594
2595bool ParserBase::leaveInnerFunction(ParseContext* outerpc) {
2596 MOZ_ASSERT(pc_ != outerpc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_ != outerpc)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_ != outerpc))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("pc_ != outerpc"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_ != outerpc"
")"); do { *((volatile int*)__null) = 2596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2597
2598 MOZ_ASSERT_IF(outerpc->isFunctionBox(),do { if (outerpc->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(outerpc->functionBox
()->index() < pc_->functionBox()->index())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(outerpc->functionBox()->index() < pc_->functionBox
()->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("outerpc->functionBox()->index() < pc_->functionBox()->index()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2599); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outerpc->functionBox()->index() < pc_->functionBox()->index()"
")"); do { *((volatile int*)__null) = 2599; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2599 outerpc->functionBox()->index() < pc_->functionBox()->index())do { if (outerpc->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(outerpc->functionBox
()->index() < pc_->functionBox()->index())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(outerpc->functionBox()->index() < pc_->functionBox
()->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("outerpc->functionBox()->index() < pc_->functionBox()->index()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2599); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outerpc->functionBox()->index() < pc_->functionBox()->index()"
")"); do { *((volatile int*)__null) = 2599; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2600
2601 // If the current function allows super.property but cannot have a home
2602 // object, i.e., it is an arrow function, we need to propagate the flag to
2603 // the outer ParseContext.
2604 if (pc_->superScopeNeedsHomeObject()) {
2605 if (!pc_->isArrowFunction()) {
2606 MOZ_ASSERT(pc_->functionBox()->needsHomeObject())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->functionBox()->needsHomeObject())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->functionBox()->needsHomeObject()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("pc_->functionBox()->needsHomeObject()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2606); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->needsHomeObject()"
")"); do { *((volatile int*)__null) = 2606; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2607 } else {
2608 outerpc->setSuperScopeNeedsHomeObject();
2609 }
2610 }
2611
2612 // Lazy functions inner to another lazy function need to be remembered by
2613 // the inner function so that if the outer function is eventually parsed
2614 // we do not need any further parsing or processing of the inner function.
2615 //
2616 // Append the inner function index here unconditionally; the vector is only
2617 // used if the Parser using outerpc is a syntax parsing. See
2618 // GeneralParser<SyntaxParseHandler>::finishFunction.
2619 if (!outerpc->innerFunctionIndexesForLazy.append(
2620 pc_->functionBox()->index())) {
2621 return false;
2622 }
2623
2624 PropagateTransitiveParseFlags(pc_->functionBox(), outerpc->sc());
2625
2626 return true;
2627}
2628
2629TaggedParserAtomIndex ParserBase::prefixAccessorName(
2630 PropertyType propType, TaggedParserAtomIndex propAtom) {
2631 StringBuffer prefixed(fc_);
2632 if (propType == PropertyType::Setter) {
2633 if (!prefixed.append("set ")) {
2634 return TaggedParserAtomIndex::null();
2635 }
2636 } else {
2637 if (!prefixed.append("get ")) {
2638 return TaggedParserAtomIndex::null();
2639 }
2640 }
2641 if (!prefixed.append(this->parserAtoms(), propAtom)) {
2642 return TaggedParserAtomIndex::null();
2643 }
2644 return prefixed.finishParserAtom(this->parserAtoms(), fc_);
2645}
2646
2647template <class ParseHandler, typename Unit>
2648void GeneralParser<ParseHandler, Unit>::setFunctionStartAtPosition(
2649 FunctionBox* funbox, TokenPos pos) const {
2650 uint32_t startLine;
2651 JS::LimitedColumnNumberOneOrigin startColumn;
2652 tokenStream.computeLineAndColumn(pos.begin, &startLine, &startColumn);
2653
2654 // NOTE: `Debugger::CallData::findScripts` relies on sourceStart and
2655 // lineno/column referring to the same location.
2656 funbox->setStart(pos.begin, startLine, startColumn);
2657}
2658
2659template <class ParseHandler, typename Unit>
2660void GeneralParser<ParseHandler, Unit>::setFunctionStartAtCurrentToken(
2661 FunctionBox* funbox) const {
2662 setFunctionStartAtPosition(funbox, anyChars.currentToken().pos);
2663}
2664
2665template <class ParseHandler, typename Unit>
2666bool GeneralParser<ParseHandler, Unit>::functionArguments(
2667 YieldHandling yieldHandling, FunctionSyntaxKind kind,
2668 FunctionNodeType funNode) {
2669 FunctionBox* funbox = pc_->functionBox();
2670
2671 // Modifier for the following tokens.
2672 // TokenStream::SlashIsDiv for the following cases:
2673 // async a => 1
2674 // ^
2675 //
2676 // (a) => 1
2677 // ^
2678 //
2679 // async (a) => 1
2680 // ^
2681 //
2682 // function f(a) {}
2683 // ^
2684 //
2685 // TokenStream::SlashIsRegExp for the following case:
2686 // a => 1
2687 // ^
2688 Modifier firstTokenModifier =
2689 kind != FunctionSyntaxKind::Arrow || funbox->isAsync()
2690 ? TokenStream::SlashIsDiv
2691 : TokenStream::SlashIsRegExp;
2692 TokenKind tt;
2693 if (!tokenStream.getToken(&tt, firstTokenModifier)) {
2694 return false;
2695 }
2696
2697 if (kind == FunctionSyntaxKind::Arrow && TokenKindIsPossibleIdentifier(tt)) {
2698 // Record the start of function source (for FunctionToString).
2699 setFunctionStartAtCurrentToken(funbox);
2700
2701 ParamsBodyNodeType argsbody;
2702 MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newParamsBody(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2703 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
2704
2705 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
2706 if (!name) {
2707 return false;
2708 }
2709
2710 constexpr bool disallowDuplicateParams = true;
2711 bool duplicatedParam = false;
2712 if (!notePositionalFormalParameter(funNode, name, pos().begin,
2713 disallowDuplicateParams,
2714 &duplicatedParam)) {
2715 return false;
2716 }
2717 MOZ_ASSERT(!duplicatedParam)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!duplicatedParam)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!duplicatedParam))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!duplicatedParam"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2717); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!duplicatedParam"
")"); do { *((volatile int*)__null) = 2717; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2718 MOZ_ASSERT(pc_->positionalFormalParameterNames().length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->positionalFormalParameterNames().length() ==
1)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->positionalFormalParameterNames().length() ==
1))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->positionalFormalParameterNames().length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2718); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->positionalFormalParameterNames().length() == 1"
")"); do { *((volatile int*)__null) = 2718; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2719
2720 funbox->setLength(1);
2721 funbox->setArgCount(1);
2722 return true;
2723 }
2724
2725 if (tt != TokenKind::LeftParen) {
2726 error(kind == FunctionSyntaxKind::Arrow ? JSMSG_BAD_ARROW_ARGS
2727 : JSMSG_PAREN_BEFORE_FORMAL);
2728 return false;
2729 }
2730
2731 // Record the start of function source (for FunctionToString).
2732 setFunctionStartAtCurrentToken(funbox);
2733
2734 ParamsBodyNodeType argsbody;
2735 MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newParamsBody(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2736 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
2737
2738 bool matched;
2739 if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
2740 TokenStream::SlashIsRegExp)) {
2741 return false;
2742 }
2743 if (!matched) {
2744 bool hasRest = false;
2745 bool hasDefault = false;
2746 bool duplicatedParam = false;
2747 bool disallowDuplicateParams =
2748 kind == FunctionSyntaxKind::Arrow ||
2749 kind == FunctionSyntaxKind::Method ||
2750 kind == FunctionSyntaxKind::FieldInitializer ||
2751 kind == FunctionSyntaxKind::ClassConstructor;
2752 AtomVector& positionalFormals = pc_->positionalFormalParameterNames();
2753
2754 if (kind == FunctionSyntaxKind::Getter) {
2755 error(JSMSG_ACCESSOR_WRONG_ARGS, "getter", "no", "s");
2756 return false;
2757 }
2758
2759 while (true) {
2760 if (hasRest) {
2761 error(JSMSG_PARAMETER_AFTER_REST);
2762 return false;
2763 }
2764
2765 TokenKind tt;
2766 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2767 return false;
2768 }
2769
2770 if (tt == TokenKind::TripleDot) {
2771 if (kind == FunctionSyntaxKind::Setter) {
2772 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2773 return false;
2774 }
2775
2776 disallowDuplicateParams = true;
2777 if (duplicatedParam) {
2778 // Has duplicated args before the rest parameter.
2779 error(JSMSG_BAD_DUP_ARGS);
2780 return false;
2781 }
2782
2783 hasRest = true;
2784 funbox->setHasRest();
2785
2786 if (!tokenStream.getToken(&tt)) {
2787 return false;
2788 }
2789
2790 if (!TokenKindIsPossibleIdentifier(tt) &&
2791 tt != TokenKind::LeftBracket && tt != TokenKind::LeftCurly) {
2792 error(JSMSG_NO_REST_NAME);
2793 return false;
2794 }
2795 }
2796
2797 switch (tt) {
2798 case TokenKind::LeftBracket:
2799 case TokenKind::LeftCurly: {
2800 disallowDuplicateParams = true;
2801 if (duplicatedParam) {
2802 // Has duplicated args before the destructuring parameter.
2803 error(JSMSG_BAD_DUP_ARGS);
2804 return false;
2805 }
2806
2807 funbox->hasDestructuringArgs = true;
2808
2809 Node destruct;
2810 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2811 destruct,do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2812 destructuringDeclarationWithoutYieldOrAwait(do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2813 DeclarationKind::FormalParameter, yieldHandling, tt),do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2814 false)do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
;
2815
2816 if (!noteDestructuredPositionalFormalParameter(funNode, destruct)) {
2817 return false;
2818 }
2819
2820 break;
2821 }
2822
2823 default: {
2824 if (!TokenKindIsPossibleIdentifier(tt)) {
2825 error(JSMSG_MISSING_FORMAL);
2826 return false;
2827 }
2828
2829 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
2830 if (!name) {
2831 return false;
2832 }
2833
2834 if (!notePositionalFormalParameter(funNode, name, pos().begin,
2835 disallowDuplicateParams,
2836 &duplicatedParam)) {
2837 return false;
2838 }
2839 if (duplicatedParam) {
2840 funbox->hasDuplicateParameters = true;
2841 }
2842
2843 break;
2844 }
2845 }
2846
2847 if (positionalFormals.length() >= ARGNO_LIMIT) {
2848 error(JSMSG_TOO_MANY_FUN_ARGS);
2849 return false;
2850 }
2851
2852 bool matched;
2853 if (!tokenStream.matchToken(&matched, TokenKind::Assign,
2854 TokenStream::SlashIsRegExp)) {
2855 return false;
2856 }
2857 if (matched) {
2858 if (hasRest) {
2859 error(JSMSG_REST_WITH_DEFAULT);
2860 return false;
2861 }
2862 disallowDuplicateParams = true;
2863 if (duplicatedParam) {
2864 error(JSMSG_BAD_DUP_ARGS);
2865 return false;
2866 }
2867
2868 if (!hasDefault) {
2869 hasDefault = true;
2870
2871 // The Function.length property is the number of formals
2872 // before the first default argument.
2873 funbox->setLength(positionalFormals.length() - 1);
2874 }
2875 funbox->hasParameterExprs = true;
2876
2877 Node def_expr;
2878 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (assignExprWithoutYieldOrAwait
(yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (def_expr) = parserTryVarTempResult_
.unwrap(); } while (0)
2879 def_expr, assignExprWithoutYieldOrAwait(yieldHandling), false)do { auto parserTryVarTempResult_ = (assignExprWithoutYieldOrAwait
(yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (def_expr) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2880 if (!handler_.setLastFunctionFormalParameterDefault(funNode,
2881 def_expr)) {
2882 return false;
2883 }
2884 }
2885
2886 // Setter syntax uniquely requires exactly one argument.
2887 if (kind == FunctionSyntaxKind::Setter) {
2888 break;
2889 }
2890
2891 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
2892 TokenStream::SlashIsRegExp)) {
2893 return false;
2894 }
2895 if (!matched) {
2896 break;
2897 }
2898
2899 if (!hasRest) {
2900 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
2901 return false;
2902 }
2903 if (tt == TokenKind::RightParen) {
2904 break;
2905 }
2906 }
2907 }
2908
2909 TokenKind tt;
2910 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2911 return false;
2912 }
2913 if (tt != TokenKind::RightParen) {
2914 if (kind == FunctionSyntaxKind::Setter) {
2915 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2916 return false;
2917 }
2918
2919 error(JSMSG_PAREN_AFTER_FORMAL);
2920 return false;
2921 }
2922
2923 if (!hasDefault) {
2924 funbox->setLength(positionalFormals.length() - hasRest);
2925 }
2926
2927 funbox->setArgCount(positionalFormals.length());
2928 } else if (kind == FunctionSyntaxKind::Setter) {
2929 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2930 return false;
2931 }
2932
2933 return true;
2934}
2935
2936template <typename Unit>
2937bool Parser<FullParseHandler, Unit>::skipLazyInnerFunction(
2938 FunctionNode* funNode, uint32_t toStringStart, bool tryAnnexB) {
2939 // When a lazily-parsed function is called, we only fully parse (and emit)
2940 // that function, not any of its nested children. The initial syntax-only
2941 // parse recorded the free variables of nested functions and their extents,
2942 // so we can skip over them after accounting for their free variables.
2943
2944 MOZ_ASSERT(pc_->isOutermostOfCurrentCompile())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isOutermostOfCurrentCompile())>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(pc_->isOutermostOfCurrentCompile()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->isOutermostOfCurrentCompile()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2944); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isOutermostOfCurrentCompile()"
")"); do { *((volatile int*)__null) = 2944; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2945 handler_.nextLazyInnerFunction();
2946 const ScriptStencil& cachedData = handler_.cachedScriptData();
2947 const ScriptStencilExtra& cachedExtra = handler_.cachedScriptExtra();
2948 MOZ_ASSERT(toStringStart == cachedExtra.extent.toStringStart)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(toStringStart == cachedExtra.extent.toStringStart)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(toStringStart == cachedExtra.extent.toStringStart)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("toStringStart == cachedExtra.extent.toStringStart"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2948); AnnotateMozCrashReason("MOZ_ASSERT" "(" "toStringStart == cachedExtra.extent.toStringStart"
")"); do { *((volatile int*)__null) = 2948; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2949
2950 FunctionBox* funbox = newFunctionBox(funNode, cachedData, cachedExtra);
2951 if (!funbox) {
2952 return false;
2953 }
2954
2955 ScriptStencil& script = funbox->functionStencil();
2956 funbox->copyFunctionFields(script);
2957
2958 // If the inner lazy function is class constructor, connect it to the class
2959 // statement/expression we are parsing.
2960 if (funbox->isClassConstructor()) {
2961 auto classStmt =
2962 pc_->template findInnermostStatement<ParseContext::ClassStatement>();
2963 MOZ_ASSERT(!classStmt->constructorBox)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!classStmt->constructorBox)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!classStmt->constructorBox
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!classStmt->constructorBox", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!classStmt->constructorBox"
")"); do { *((volatile int*)__null) = 2963; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2964 classStmt->constructorBox = funbox;
2965 }
2966
2967 MOZ_ASSERT_IF(pc_->isFunctionBox(),do { if (pc_->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(pc_->functionBox
()->index() < funbox->index())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->functionBox()->index
() < funbox->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->functionBox()->index() < funbox->index()",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2968); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->index() < funbox->index()"
")"); do { *((volatile int*)__null) = 2968; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2968 pc_->functionBox()->index() < funbox->index())do { if (pc_->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(pc_->functionBox
()->index() < funbox->index())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->functionBox()->index
() < funbox->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->functionBox()->index() < funbox->index()",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2968); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->index() < funbox->index()"
")"); do { *((volatile int*)__null) = 2968; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2969
2970 PropagateTransitiveParseFlags(funbox, pc_->sc());
2971
2972 if (!tokenStream.advance(funbox->extent().sourceEnd)) {
2973 return false;
2974 }
2975
2976 // Append possible Annex B function box only upon successfully parsing.
2977 if (tryAnnexB &&
2978 !pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
2979 return false;
2980 }
2981
2982 return true;
2983}
2984
2985template <typename Unit>
2986bool Parser<SyntaxParseHandler, Unit>::skipLazyInnerFunction(
2987 FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
2988 MOZ_CRASH("Cannot skip lazy inner functions when syntax parsing")do { do { } while (false); MOZ_ReportCrash("" "Cannot skip lazy inner functions when syntax parsing"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2988); AnnotateMozCrashReason("MOZ_CRASH(" "Cannot skip lazy inner functions when syntax parsing"
")"); do { *((volatile int*)__null) = 2988; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
2989}
2990
2991template <class ParseHandler, typename Unit>
2992bool GeneralParser<ParseHandler, Unit>::skipLazyInnerFunction(
2993 FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
2994 return asFinalParser()->skipLazyInnerFunction(funNode, toStringStart,
2995 tryAnnexB);
2996}
2997
2998template <class ParseHandler, typename Unit>
2999bool GeneralParser<ParseHandler, Unit>::addExprAndGetNextTemplStrToken(
3000 YieldHandling yieldHandling, ListNodeType nodeList, TokenKind* ttp) {
3001 Node pn;
3002 MOZ_TRY_VAR_OR_RETURN(pn, expr(InAllowed, yieldHandling, TripledotProhibited),do { auto parserTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (pn) = parserTryVarTempResult_
.unwrap(); } while (0)
3003 false)do { auto parserTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (pn) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3004 handler_.addList(nodeList, pn);
3005
3006 TokenKind tt;
3007 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
3008 return false;
3009 }
3010 if (tt != TokenKind::RightCurly) {
3011 error(JSMSG_TEMPLSTR_UNTERM_EXPR);
3012 return false;
3013 }
3014
3015 return tokenStream.getTemplateToken(ttp);
3016}
3017
3018template <class ParseHandler, typename Unit>
3019bool GeneralParser<ParseHandler, Unit>::taggedTemplate(
3020 YieldHandling yieldHandling, ListNodeType tagArgsList, TokenKind tt) {
3021 CallSiteNodeType callSiteObjNode;
3022 MOZ_TRY_VAR_OR_RETURN(callSiteObjNode,do { auto parserTryVarTempResult_ = (handler_.newCallSiteObject
(pos().begin)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (callSiteObjNode) = parserTryVarTempResult_
.unwrap(); } while (0)
3023 handler_.newCallSiteObject(pos().begin), false)do { auto parserTryVarTempResult_ = (handler_.newCallSiteObject
(pos().begin)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (callSiteObjNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3024 handler_.addList(tagArgsList, callSiteObjNode);
3025
3026 pc_->sc()->setHasCallSiteObj();
3027
3028 while (true) {
3029 if (!appendToCallSiteObj(callSiteObjNode)) {
3030 return false;
3031 }
3032 if (tt != TokenKind::TemplateHead) {
3033 break;
3034 }
3035
3036 if (!addExprAndGetNextTemplStrToken(yieldHandling, tagArgsList, &tt)) {
3037 return false;
3038 }
3039 }
3040 handler_.setEndPosition(tagArgsList, callSiteObjNode);
3041 return true;
3042}
3043
3044template <class ParseHandler, typename Unit>
3045typename ParseHandler::ListNodeResult
3046GeneralParser<ParseHandler, Unit>::templateLiteral(
3047 YieldHandling yieldHandling) {
3048 NameNodeType literal;
3049 MOZ_TRY_VAR(literal, noSubstitutionUntaggedTemplate())do { auto mozTryVarTempResult_ = (noSubstitutionUntaggedTemplate
()); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
3050
3051 ListNodeType nodeList;
3052 MOZ_TRY_VAR(nodeList,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::TemplateStringListExpr, literal)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nodeList) = mozTryVarTempResult_.unwrap()
; } while (0)
3053 handler_.newList(ParseNodeKind::TemplateStringListExpr, literal))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::TemplateStringListExpr, literal)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nodeList) = mozTryVarTempResult_.unwrap()
; } while (0)
;
3054
3055 TokenKind tt;
3056 do {
3057 if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt)) {
3058 return errorResult();
3059 }
3060
3061 MOZ_TRY_VAR(literal, noSubstitutionUntaggedTemplate())do { auto mozTryVarTempResult_ = (noSubstitutionUntaggedTemplate
()); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
3062
3063 handler_.addList(nodeList, literal);
3064 } while (tt == TokenKind::TemplateHead);
3065 return nodeList;
3066}
3067
3068template <class ParseHandler, typename Unit>
3069typename ParseHandler::FunctionNodeResult
3070GeneralParser<ParseHandler, Unit>::functionDefinition(
3071 FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
3072 YieldHandling yieldHandling, TaggedParserAtomIndex funName,
3073 FunctionSyntaxKind kind, GeneratorKind generatorKind,
3074 FunctionAsyncKind asyncKind, bool tryAnnexB /* = false */) {
3075 MOZ_ASSERT_IF(kind == FunctionSyntaxKind::Statement, funName)do { if (kind == FunctionSyntaxKind::Statement) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(funName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(funName))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3075); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funName" ")"
); do { *((volatile int*)__null) = 3075; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3076
3077 // If we see any inner function, note it on our current context. The bytecode
3078 // emitter may eliminate the function later, but we use a conservative
3079 // definition for consistency between lazy and full parsing.
3080 pc_->sc()->setHasInnerFunctions();
3081
3082 // When fully parsing a lazy script, we do not fully reparse its inner
3083 // functions, which are also lazy. Instead, their free variables and source
3084 // extents are recorded and may be skipped.
3085 if (handler_.reuseLazyInnerFunctions()) {
3086 if (!skipLazyInnerFunction(funNode, toStringStart, tryAnnexB)) {
3087 return errorResult();
3088 }
3089
3090 return funNode;
3091 }
3092
3093 bool isSelfHosting = options().selfHostingMode;
3094 FunctionFlags flags =
3095 InitialFunctionFlags(kind, generatorKind, asyncKind, isSelfHosting);
3096
3097 // Self-hosted functions with special function names require extended slots
3098 // for various purposes.
3099 bool forceExtended =
3100 isSelfHosting && funName &&
3101 this->parserAtoms().isExtendedUnclonedSelfHostedFunctionName(funName);
3102 if (forceExtended) {
3103 flags.setIsExtended();
3104 }
3105
3106 // Speculatively parse using the directives of the parent parsing context.
3107 // If a directive is encountered (e.g., "use strict") that changes how the
3108 // function should have been parsed, we backup and reparse with the new set
3109 // of directives.
3110 Directives directives(pc_);
3111 Directives newDirectives = directives;
3112
3113 Position start(tokenStream);
3114 auto startObj = this->compilationState_.getPosition();
3115
3116 // Parse the inner function. The following is a loop as we may attempt to
3117 // reparse a function due to failed syntax parsing and encountering new
3118 // "use foo" directives.
3119 while (true) {
3120 if (trySyntaxParseInnerFunction(&funNode, funName, flags, toStringStart,
3121 inHandling, yieldHandling, kind,
3122 generatorKind, asyncKind, tryAnnexB,
3123 directives, &newDirectives)) {
3124 break;
3125 }
3126
3127 // Return on error.
3128 if (anyChars.hadError() || directives == newDirectives) {
3129 return errorResult();
3130 }
3131
3132 // Assignment must be monotonic to prevent infinitely attempting to
3133 // reparse.
3134 MOZ_ASSERT_IF(directives.strict(), newDirectives.strict())do { if (directives.strict()) { do { static_assert( mozilla::
detail::AssertionConditionType<decltype(newDirectives.strict
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(newDirectives.strict()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("newDirectives.strict()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3134); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newDirectives.strict()"
")"); do { *((volatile int*)__null) = 3134; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3135 MOZ_ASSERT_IF(directives.asmJS(), newDirectives.asmJS())do { if (directives.asmJS()) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(newDirectives.asmJS())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(newDirectives.asmJS()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("newDirectives.asmJS()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3135); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newDirectives.asmJS()"
")"); do { *((volatile int*)__null) = 3135; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3136 directives = newDirectives;
3137
3138 // Rewind to retry parsing with new directives applied.
3139 tokenStream.rewind(start);
3140 this->compilationState_.rewind(startObj);
3141
3142 // functionFormalParametersAndBody may have already set body before failing.
3143 handler_.setFunctionFormalParametersAndBody(funNode, null());
3144 }
3145
3146 return funNode;
3147}
3148
3149template <typename Unit>
3150bool Parser<FullParseHandler, Unit>::advancePastSyntaxParsedFunction(
3151 SyntaxParser* syntaxParser) {
3152 MOZ_ASSERT(getSyntaxParser() == syntaxParser)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(getSyntaxParser() == syntaxParser)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(getSyntaxParser() == syntaxParser
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"getSyntaxParser() == syntaxParser", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3152); AnnotateMozCrashReason("MOZ_ASSERT" "(" "getSyntaxParser() == syntaxParser"
")"); do { *((volatile int*)__null) = 3152; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3153
3154 // Advance this parser over tokens processed by the syntax parser.
3155 Position currentSyntaxPosition(syntaxParser->tokenStream);
3156 if (!tokenStream.fastForward(currentSyntaxPosition, syntaxParser->anyChars)) {
3157 return false;
3158 }
3159
3160 anyChars.adoptState(syntaxParser->anyChars);
3161 tokenStream.adoptState(syntaxParser->tokenStream);
3162 return true;
3163}
3164
3165template <typename Unit>
3166bool Parser<FullParseHandler, Unit>::trySyntaxParseInnerFunction(
3167 FunctionNode** funNode, TaggedParserAtomIndex explicitName,
3168 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3169 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3170 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3171 Directives inheritedDirectives, Directives* newDirectives) {
3172 // Try a syntax parse for this inner function.
3173 do {
3174 // If we're assuming this function is an IIFE, always perform a full
3175 // parse to avoid the overhead of a lazy syntax-only parse. Although
3176 // the prediction may be incorrect, IIFEs are common enough that it
3177 // pays off for lots of code.
3178 if ((*funNode)->isLikelyIIFE() &&
3179 generatorKind == GeneratorKind::NotGenerator &&
3180 asyncKind == FunctionAsyncKind::SyncFunction) {
3181 break;
3182 }
3183
3184 SyntaxParser* syntaxParser = getSyntaxParser();
3185 if (!syntaxParser) {
3186 break;
3187 }
3188
3189 UsedNameTracker::RewindToken token = usedNames_.getRewindToken();
3190 auto statePosition = this->compilationState_.getPosition();
3191
3192 // Move the syntax parser to the current position in the stream. In the
3193 // common case this seeks forward, but it'll also seek backward *at least*
3194 // when arrow functions appear inside arrow function argument defaults
3195 // (because we rewind to reparse arrow functions once we're certain they're
3196 // arrow functions):
3197 //
3198 // var x = (y = z => 2) => q;
3199 // // ^ we first seek to here to syntax-parse this function
3200 // // ^ then we seek back to here to syntax-parse the outer function
3201 Position currentPosition(tokenStream);
3202 if (!syntaxParser->tokenStream.seekTo(currentPosition, anyChars)) {
3203 return false;
3204 }
3205
3206 // Make a FunctionBox before we enter the syntax parser, because |pn|
3207 // still expects a FunctionBox to be attached to it during BCE, and
3208 // the syntax parser cannot attach one to it.
3209 FunctionBox* funbox =
3210 newFunctionBox(*funNode, explicitName, flags, toStringStart,
3211 inheritedDirectives, generatorKind, asyncKind);
3212 if (!funbox) {
3213 return false;
3214 }
3215 funbox->initWithEnclosingParseContext(pc_, kind);
3216
3217 auto syntaxNodeResult = syntaxParser->innerFunctionForFunctionBox(
3218 SyntaxParseHandler::Node::NodeGeneric, pc_, funbox, inHandling,
3219 yieldHandling, kind, newDirectives);
3220 if (syntaxNodeResult.isErr()) {
3221 if (syntaxParser->hadAbortedSyntaxParse()) {
3222 // Try again with a full parse. UsedNameTracker needs to be
3223 // rewound to just before we tried the syntax parse for
3224 // correctness.
3225 syntaxParser->clearAbortedSyntaxParse();
3226 usedNames_.rewind(token);
3227 this->compilationState_.rewind(statePosition);
3228 MOZ_ASSERT(!fc_->hadErrors())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!fc_->hadErrors())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!fc_->hadErrors()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!fc_->hadErrors()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3228); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!fc_->hadErrors()"
")"); do { *((volatile int*)__null) = 3228; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3229 break;
3230 }
3231 return false;
3232 }
3233
3234 if (!advancePastSyntaxParsedFunction(syntaxParser)) {
3235 return false;
3236 }
3237
3238 // Update the end position of the parse node.
3239 (*funNode)->pn_pos.end = anyChars.currentToken().pos.end;
3240
3241 // Append possible Annex B function box only upon successfully parsing.
3242 if (tryAnnexB) {
3243 if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
3244 return false;
3245 }
3246 }
3247
3248 return true;
3249 } while (false);
3250
3251 // We failed to do a syntax parse above, so do the full parse.
3252 FunctionNodeType innerFunc;
3253 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3254 innerFunc,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3255 innerFunction(*funNode, pc_, explicitName, flags, toStringStart,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3256 inHandling, yieldHandling, kind, generatorKind, asyncKind,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3257 tryAnnexB, inheritedDirectives, newDirectives),do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3258 false)do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3259
3260 *funNode = innerFunc;
3261 return true;
3262}
3263
3264template <typename Unit>
3265bool Parser<SyntaxParseHandler, Unit>::trySyntaxParseInnerFunction(
3266 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
3267 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3268 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3269 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3270 Directives inheritedDirectives, Directives* newDirectives) {
3271 // This is already a syntax parser, so just parse the inner function.
3272 FunctionNodeType innerFunc;
3273 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3274 innerFunc,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3275 innerFunction(*funNode, pc_, explicitName, flags, toStringStart,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3276 inHandling, yieldHandling, kind, generatorKind, asyncKind,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3277 tryAnnexB, inheritedDirectives, newDirectives),do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3278 false)do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3279
3280 *funNode = innerFunc;
3281 return true;
3282}
3283
3284template <class ParseHandler, typename Unit>
3285inline bool GeneralParser<ParseHandler, Unit>::trySyntaxParseInnerFunction(
3286 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
3287 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3288 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3289 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3290 Directives inheritedDirectives, Directives* newDirectives) {
3291 return asFinalParser()->trySyntaxParseInnerFunction(
3292 funNode, explicitName, flags, toStringStart, inHandling, yieldHandling,
3293 kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives,
3294 newDirectives);
3295}
3296
3297template <class ParseHandler, typename Unit>
3298typename ParseHandler::FunctionNodeResult
3299GeneralParser<ParseHandler, Unit>::innerFunctionForFunctionBox(
3300 FunctionNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
3301 InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
3302 Directives* newDirectives) {
3303 // Note that it is possible for outerpc != this->pc_, as we may be
3304 // attempting to syntax parse an inner function from an outer full
3305 // parser. In that case, outerpc is a SourceParseContext from the full parser
3306 // instead of the current top of the stack of the syntax parser.
3307
3308 // Push a new ParseContext.
3309 SourceParseContext funpc(this, funbox, newDirectives);
3310 if (!funpc.init()) {
3311 return errorResult();
3312 }
3313
3314 if (!functionFormalParametersAndBody(inHandling, yieldHandling, &funNode,
3315 kind)) {
3316 return errorResult();
3317 }
3318
3319 if (!leaveInnerFunction(outerpc)) {
3320 return errorResult();
3321 }
3322
3323 return funNode;
3324}
3325
3326template <class ParseHandler, typename Unit>
3327typename ParseHandler::FunctionNodeResult
3328GeneralParser<ParseHandler, Unit>::innerFunction(
3329 FunctionNodeType funNode, ParseContext* outerpc,
3330 TaggedParserAtomIndex explicitName, FunctionFlags flags,
3331 uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
3332 FunctionSyntaxKind kind, GeneratorKind generatorKind,
3333 FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
3334 Directives* newDirectives) {
3335 // Note that it is possible for outerpc != this->pc_, as we may be
3336 // attempting to syntax parse an inner function from an outer full
3337 // parser. In that case, outerpc is a SourceParseContext from the full parser
3338 // instead of the current top of the stack of the syntax parser.
3339
3340 FunctionBox* funbox =
3341 newFunctionBox(funNode, explicitName, flags, toStringStart,
3342 inheritedDirectives, generatorKind, asyncKind);
3343 if (!funbox) {
3344 return errorResult();
3345 }
3346 funbox->initWithEnclosingParseContext(outerpc, kind);
3347
3348 FunctionNodeType innerFunc;
3349 MOZ_TRY_VAR(innerFunc,do { auto mozTryVarTempResult_ = (innerFunctionForFunctionBox
(funNode, outerpc, funbox, inHandling, yieldHandling, kind, newDirectives
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerFunc
) = mozTryVarTempResult_.unwrap(); } while (0)
3350 innerFunctionForFunctionBox(funNode, outerpc, funbox, inHandling,do { auto mozTryVarTempResult_ = (innerFunctionForFunctionBox
(funNode, outerpc, funbox, inHandling, yieldHandling, kind, newDirectives
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerFunc
) = mozTryVarTempResult_.unwrap(); } while (0)
3351 yieldHandling, kind, newDirectives))do { auto mozTryVarTempResult_ = (innerFunctionForFunctionBox
(funNode, outerpc, funbox, inHandling, yieldHandling, kind, newDirectives
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerFunc
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3352
3353 // Append possible Annex B function box only upon successfully parsing.
3354 if (tryAnnexB) {
3355 if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
3356 return errorResult();
3357 }
3358 }
3359
3360 return innerFunc;
3361}
3362
3363template <class ParseHandler, typename Unit>
3364bool GeneralParser<ParseHandler, Unit>::appendToCallSiteObj(
3365 CallSiteNodeType callSiteObj) {
3366 Node cookedNode;
3367 MOZ_TRY_VAR_OR_RETURN(cookedNode, noSubstitutionTaggedTemplate(), false)do { auto parserTryVarTempResult_ = (noSubstitutionTaggedTemplate
()); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()
), 0))) { return (false); } (cookedNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3368
3369 auto atom = tokenStream.getRawTemplateStringAtom();
3370 if (!atom) {
3371 return false;
3372 }
3373 NameNodeType rawNode;
3374 MOZ_TRY_VAR_OR_RETURN(rawNode, handler_.newTemplateStringLiteral(atom, pos()),do { auto parserTryVarTempResult_ = (handler_.newTemplateStringLiteral
(atom, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (rawNode) = parserTryVarTempResult_
.unwrap(); } while (0)
3375 false)do { auto parserTryVarTempResult_ = (handler_.newTemplateStringLiteral
(atom, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (rawNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3376
3377 handler_.addToCallSiteObject(callSiteObj, rawNode, cookedNode);
3378 return true;
3379}
3380
3381template <typename Unit>
3382FullParseHandler::FunctionNodeResult
3383Parser<FullParseHandler, Unit>::standaloneLazyFunction(
3384 CompilationInput& input, uint32_t toStringStart, bool strict,
3385 GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
3386 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3386); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 3386; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3387
3388 FunctionSyntaxKind syntaxKind = input.functionSyntaxKind();
3389 FunctionNodeType funNode;
3390 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3391
3392 TaggedParserAtomIndex displayAtom =
3393 this->getCompilationState().previousParseCache.displayAtom();
3394
3395 Directives directives(strict);
3396 FunctionBox* funbox =
3397 newFunctionBox(funNode, displayAtom, input.functionFlags(), toStringStart,
3398 directives, generatorKind, asyncKind);
3399 if (!funbox) {
3400 return errorResult();
3401 }
3402 const ScriptStencilExtra& funExtra =
3403 this->getCompilationState().previousParseCache.funExtra();
3404 funbox->initFromLazyFunction(
3405 funExtra, this->getCompilationState().scopeContext, syntaxKind);
3406 if (funbox->useMemberInitializers()) {
3407 funbox->setMemberInitializers(funExtra.memberInitializers());
3408 }
3409
3410 Directives newDirectives = directives;
3411 SourceParseContext funpc(this, funbox, &newDirectives);
3412 if (!funpc.init()) {
3413 return errorResult();
3414 }
3415
3416 // Our tokenStream has no current token, so funNode's position is garbage.
3417 // Substitute the position of the first token in our source. If the
3418 // function is a not-async arrow, use TokenStream::SlashIsRegExp to keep
3419 // verifyConsistentModifier from complaining (we will use
3420 // TokenStream::SlashIsRegExp in functionArguments).
3421 Modifier modifier = (input.functionFlags().isArrow() &&
3422 asyncKind == FunctionAsyncKind::SyncFunction)
3423 ? TokenStream::SlashIsRegExp
3424 : TokenStream::SlashIsDiv;
3425 if (!tokenStream.peekTokenPos(&funNode->pn_pos, modifier)) {
3426 return errorResult();
3427 }
3428
3429 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
3430
3431 if (funbox->isSyntheticFunction()) {
3432 // Currently default class constructors are the only synthetic function that
3433 // supports delazification.
3434 MOZ_ASSERT(funbox->isClassConstructor())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isClassConstructor())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isClassConstructor
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isClassConstructor()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3434); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isClassConstructor()"
")"); do { *((volatile int*)__null) = 3434; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3435 MOZ_ASSERT(funbox->extent().toStringStart == funbox->extent().sourceStart)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->extent().toStringStart == funbox->extent
().sourceStart)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(funbox->extent().toStringStart
== funbox->extent().sourceStart))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("funbox->extent().toStringStart == funbox->extent().sourceStart"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3435); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->extent().toStringStart == funbox->extent().sourceStart"
")"); do { *((volatile int*)__null) = 3435; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3436
3437 HasHeritage hasHeritage = funbox->isDerivedClassConstructor()
3438 ? HasHeritage::Yes
3439 : HasHeritage::No;
3440 TokenPos synthesizedBodyPos(funbox->extent().toStringStart,
3441 funbox->extent().toStringEnd);
3442
3443 // Reset pos() to the `class` keyword for predictable results.
3444 tokenStream.consumeKnownToken(TokenKind::Class);
3445
3446 if (!this->synthesizeConstructorBody(synthesizedBodyPos, hasHeritage,
3447 funNode, funbox)) {
3448 return errorResult();
3449 }
3450 } else {
3451 if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
3452 syntaxKind)) {
3453 MOZ_ASSERT(directives == newDirectives)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(directives == newDirectives)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(directives == newDirectives)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("directives == newDirectives"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3453); AnnotateMozCrashReason("MOZ_ASSERT" "(" "directives == newDirectives"
")"); do { *((volatile int*)__null) = 3453; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3454 return errorResult();
3455 }
3456 }
3457
3458 if (!CheckParseTree(this->fc_, alloc_, funNode)) {
3459 return errorResult();
3460 }
3461
3462 ParseNode* node = funNode;
3463 // Don't constant-fold inside "use asm" code, as this could create a parse
3464 // tree that doesn't type-check as asm.js.
3465 if (!pc_->useAsmOrInsideUseAsm()) {
3466 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
3467 return errorResult();
3468 }
3469 }
3470 funNode = &node->as<FunctionNode>();
3471
3472 return funNode;
3473}
3474
3475void ParserBase::setFunctionEndFromCurrentToken(FunctionBox* funbox) const {
3476 if (compilationState_.isInitialStencil()) {
3477 MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type != TokenKind::Eof)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type != TokenKind::Eof))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type != TokenKind::Eof"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3477); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type != TokenKind::Eof"
")"); do { *((volatile int*)__null) = 3477; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3478 MOZ_ASSERT(anyChars.currentToken().type < TokenKind::Limit)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type < TokenKind::Limit)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type < TokenKind::Limit))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type < TokenKind::Limit"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3478); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type < TokenKind::Limit"
")"); do { *((volatile int*)__null) = 3478; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3479 funbox->setEnd(anyChars.currentToken().pos.end);
3480 } else {
3481 // If we're delazifying an arrow function with expression body and
3482 // the expression is also a function, we arrive here immediately after
3483 // skipping the function by Parser::skipLazyInnerFunction.
3484 //
3485 // a => b => c
3486 // ^
3487 // |
3488 // we're here
3489 //
3490 // In that case, the current token's type field is either Limit or
3491 // poisoned.
3492 // We shouldn't read the value if it's poisoned.
3493 // See TokenStreamSpecific<Unit, AnyCharsAccess>::advance and
3494 // mfbt/MemoryChecking.h for more details.
3495 //
3496 // Also, in delazification, the FunctionBox should already have the
3497 // correct extent, and we shouldn't overwrite it here.
3498 // See ScriptStencil variant of PerHandlerParser::newFunctionBox.
3499#if !defined(MOZ_ASAN) && !defined(MOZ_MSAN) && !defined(MOZ_VALGRIND)
3500 MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type != TokenKind::Eof)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type != TokenKind::Eof))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type != TokenKind::Eof"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3500); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type != TokenKind::Eof"
")"); do { *((volatile int*)__null) = 3500; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3501#endif
3502 MOZ_ASSERT(funbox->extent().sourceEnd == anyChars.currentToken().pos.end)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->extent().sourceEnd == anyChars.currentToken
().pos.end)>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(funbox->extent().sourceEnd == anyChars
.currentToken().pos.end))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->extent().sourceEnd == anyChars.currentToken().pos.end"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3502); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->extent().sourceEnd == anyChars.currentToken().pos.end"
")"); do { *((volatile int*)__null) = 3502; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3503 }
3504}
3505
3506template <class ParseHandler, typename Unit>
3507bool GeneralParser<ParseHandler, Unit>::functionFormalParametersAndBody(
3508 InHandling inHandling, YieldHandling yieldHandling,
3509 FunctionNodeType* funNode, FunctionSyntaxKind kind,
3510 const Maybe<uint32_t>& parameterListEnd /* = Nothing() */,
3511 bool isStandaloneFunction /* = false */) {
3512 // Given a properly initialized parse context, try to parse an actual
3513 // function without concern for conversion to strict mode, use of lazy
3514 // parsing and such.
3515
3516 FunctionBox* funbox = pc_->functionBox();
3517
3518 if (kind == FunctionSyntaxKind::ClassConstructor ||
3519 kind == FunctionSyntaxKind::DerivedClassConstructor) {
3520 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
3521 return false;
3522 }
3523#ifdef ENABLE_DECORATORS
3524 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
3525 dot_instanceExtraInitializers_())) {
3526 return false;
3527 }
3528#endif
3529 }
3530
3531 // See below for an explanation why arrow function parameters and arrow
3532 // function bodies are parsed with different yield/await settings.
3533 {
3534 AwaitHandling awaitHandling =
3535 kind == FunctionSyntaxKind::StaticClassBlock ? AwaitIsDisallowed
3536 : (funbox->isAsync() ||
3537 (kind == FunctionSyntaxKind::Arrow && awaitIsKeyword()))
3538 ? AwaitIsKeyword
3539 : AwaitIsName;
3540 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this, awaitHandling);
3541 AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(
3542 this, funbox->isAsync());
3543 if (!functionArguments(yieldHandling, kind, *funNode)) {
3544 return false;
3545 }
3546 }
3547
3548 Maybe<ParseContext::VarScope> varScope;
3549 if (funbox->hasParameterExprs) {
3550 varScope.emplace(this);
3551 if (!varScope->init(pc_)) {
3552 return false;
3553 }
3554 } else {
3555 pc_->functionScope().useAsVarScope(pc_);
3556 }
3557
3558 if (kind == FunctionSyntaxKind::Arrow) {
3559 TokenKind tt;
3560 if (!tokenStream.peekTokenSameLine(&tt)) {
3561 return false;
3562 }
3563
3564 if (tt == TokenKind::Eol) {
3565 error(JSMSG_UNEXPECTED_TOKEN,
3566 "'=>' on the same line after an argument list",
3567 TokenKindToDesc(tt));
3568 return false;
3569 }
3570 if (tt != TokenKind::Arrow) {
3571 error(JSMSG_BAD_ARROW_ARGS);
3572 return false;
3573 }
3574 tokenStream.consumeKnownToken(TokenKind::Arrow);
3575 }
3576
3577 // When parsing something for new Function() we have to make sure to
3578 // only treat a certain part of the source as a parameter list.
3579 if (parameterListEnd.isSome() && parameterListEnd.value() != pos().begin) {
3580 error(JSMSG_UNEXPECTED_PARAMLIST_END);
3581 return false;
3582 }
3583
3584 // Parse the function body.
3585 FunctionBodyType bodyType = StatementListBody;
3586 TokenKind tt;
3587 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
3588 return false;
3589 }
3590 uint32_t openedPos = 0;
3591 if (tt != TokenKind::LeftCurly) {
3592 if (kind != FunctionSyntaxKind::Arrow) {
3593 error(JSMSG_CURLY_BEFORE_BODY);
3594 return false;
3595 }
3596
3597 anyChars.ungetToken();
3598 bodyType = ExpressionBody;
3599 funbox->setHasExprBody();
3600 } else {
3601 openedPos = pos().begin;
3602 }
3603
3604 // Arrow function parameters inherit yieldHandling from the enclosing
3605 // context, but the arrow body doesn't. E.g. in |(a = yield) => yield|,
3606 // |yield| in the parameters is either a name or keyword, depending on
3607 // whether the arrow function is enclosed in a generator function or not.
3608 // Whereas the |yield| in the function body is always parsed as a name.
3609 // The same goes when parsing |await| in arrow functions.
3610 YieldHandling bodyYieldHandling = GetYieldHandling(pc_->generatorKind());
3611 AwaitHandling bodyAwaitHandling = GetAwaitHandling(pc_->asyncKind());
3612 bool inheritedStrict = pc_->sc()->strict();
3613 LexicalScopeNodeType body;
3614 {
3615 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this,
3616 bodyAwaitHandling);
3617 AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(this,
3618 false);
3619 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
3620 body, functionBody(inHandling, bodyYieldHandling, kind, bodyType),do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
3621 false)do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
;
3622 }
3623
3624 // Revalidate the function name when we transitioned to strict mode.
3625 if ((kind == FunctionSyntaxKind::Statement ||
3626 kind == FunctionSyntaxKind::Expression) &&
3627 funbox->explicitName() && !inheritedStrict && pc_->sc()->strict()) {
3628 MOZ_ASSERT(pc_->sc()->hasExplicitUseStrict(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3630); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3630; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
3629 "strict mode should only change when a 'use strict' directive "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3630); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3630; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
3630 "is present")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3630); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3630; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
3631
3632 auto propertyName = funbox->explicitName();
3633 YieldHandling nameYieldHandling;
3634 if (kind == FunctionSyntaxKind::Expression) {
3635 // Named lambda has binding inside it.
3636 nameYieldHandling = bodyYieldHandling;
3637 } else {
3638 // Otherwise YieldHandling cannot be checked at this point
3639 // because of different context.
3640 // It should already be checked before this point.
3641 nameYieldHandling = YieldIsName;
3642 }
3643
3644 // We already use the correct await-handling at this point, therefore
3645 // we don't need call AutoAwaitIsKeyword here.
3646
3647 uint32_t nameOffset = handler_.getFunctionNameOffset(*funNode, anyChars);
3648 if (!checkBindingIdentifier(propertyName, nameOffset, nameYieldHandling)) {
3649 return false;
3650 }
3651 }
3652
3653 if (bodyType == StatementListBody) {
3654 // Cannot use mustMatchToken here because of internal compiler error on
3655 // gcc 6.4.0, with linux 64 SM hazard build.
3656 TokenKind actual;
3657 if (!tokenStream.getToken(&actual, TokenStream::SlashIsRegExp)) {
3658 return false;
3659 }
3660 if (actual != TokenKind::RightCurly) {
3661 reportMissingClosing(JSMSG_CURLY_AFTER_BODY, JSMSG_CURLY_OPENED,
3662 openedPos);
3663 return false;
3664 }
3665
3666 setFunctionEndFromCurrentToken(funbox);
3667 } else {
3668 MOZ_ASSERT(kind == FunctionSyntaxKind::Arrow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == FunctionSyntaxKind::Arrow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == FunctionSyntaxKind::
Arrow))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == FunctionSyntaxKind::Arrow", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3668); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == FunctionSyntaxKind::Arrow"
")"); do { *((volatile int*)__null) = 3668; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3669
3670 if (anyChars.hadError()) {
3671 return false;
3672 }
3673
3674 setFunctionEndFromCurrentToken(funbox);
3675
3676 if (kind == FunctionSyntaxKind::Statement) {
3677 if (!matchOrInsertSemicolon()) {
3678 return false;
3679 }
3680 }
3681 }
3682
3683 if (IsMethodDefinitionKind(kind) && pc_->superScopeNeedsHomeObject()) {
3684 funbox->setNeedsHomeObject();
3685 }
3686
3687 if (!finishFunction(isStandaloneFunction)) {
3688 return false;
3689 }
3690
3691 handler_.setEndPosition(body, pos().begin);
3692 handler_.setEndPosition(*funNode, pos().end);
3693 handler_.setFunctionBody(*funNode, body);
3694
3695 return true;
3696}
3697
3698template <class ParseHandler, typename Unit>
3699typename ParseHandler::FunctionNodeResult
3700GeneralParser<ParseHandler, Unit>::functionStmt(uint32_t toStringStart,
3701 YieldHandling yieldHandling,
3702 DefaultHandling defaultHandling,
3703 FunctionAsyncKind asyncKind) {
3704 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3704); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 3704; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3705
3706 // In sloppy mode, Annex B.3.2 allows labelled function declarations.
3707 // Otherwise it's a parse error.
3708 ParseContext::Statement* declaredInStmt = pc_->innermostStatement();
3709 if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
3710 MOZ_ASSERT(!pc_->sc()->strict(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!pc_->sc()->strict())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!pc_->sc()->strict()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!pc_->sc()->strict()"
" (" "labeled functions shouldn't be parsed in strict mode" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3711); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc_->sc()->strict()"
") (" "labeled functions shouldn't be parsed in strict mode"
")"); do { *((volatile int*)__null) = 3711; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3711 "labeled functions shouldn't be parsed in strict mode")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!pc_->sc()->strict())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!pc_->sc()->strict()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!pc_->sc()->strict()"
" (" "labeled functions shouldn't be parsed in strict mode" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3711); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc_->sc()->strict()"
") (" "labeled functions shouldn't be parsed in strict mode"
")"); do { *((volatile int*)__null) = 3711; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3712
3713 // Find the innermost non-label statement. Report an error if it's
3714 // unbraced: functions can't appear in it. Otherwise the statement
3715 // (or its absence) determines the scope the function's bound in.
3716 while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
3717 declaredInStmt = declaredInStmt->enclosing();
3718 }
3719
3720 if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
3721 error(JSMSG_SLOPPY_FUNCTION_LABEL);
3722 return errorResult();
3723 }
3724 }
3725
3726 TokenKind tt;
3727 if (!tokenStream.getToken(&tt)) {
3728 return errorResult();
3729 }
3730
3731 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
3732 if (tt == TokenKind::Mul) {
3733 generatorKind = GeneratorKind::Generator;
3734 if (!tokenStream.getToken(&tt)) {
3735 return errorResult();
3736 }
3737 }
3738
3739 TaggedParserAtomIndex name;
3740 if (TokenKindIsPossibleIdentifier(tt)) {
3741 name = bindingIdentifier(yieldHandling);
3742 if (!name) {
3743 return errorResult();
3744 }
3745 } else if (defaultHandling == AllowDefaultName) {
3746 name = TaggedParserAtomIndex::WellKnown::default_();
3747 anyChars.ungetToken();
3748 } else {
3749 /* Unnamed function expressions are forbidden in statement context. */
3750 error(JSMSG_UNNAMED_FUNCTION_STMT);
3751 return errorResult();
3752 }
3753
3754 // Note the declared name and check for early errors.
3755 DeclarationKind kind;
3756 if (declaredInStmt) {
3757 MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(declaredInStmt->kind() != StatementKind::Label)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(declaredInStmt->kind() != StatementKind::Label)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("declaredInStmt->kind() != StatementKind::Label"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3757); AnnotateMozCrashReason("MOZ_ASSERT" "(" "declaredInStmt->kind() != StatementKind::Label"
")"); do { *((volatile int*)__null) = 3757; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3758 MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StatementKindIsBraced(declaredInStmt->kind()))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(StatementKindIsBraced(declaredInStmt->kind())))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("StatementKindIsBraced(declaredInStmt->kind())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3758); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StatementKindIsBraced(declaredInStmt->kind())"
")"); do { *((volatile int*)__null) = 3758; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3759
3760 kind =
3761 (!pc_->sc()->strict() && generatorKind == GeneratorKind::NotGenerator &&
3762 asyncKind == FunctionAsyncKind::SyncFunction)
3763 ? DeclarationKind::SloppyLexicalFunction
3764 : DeclarationKind::LexicalFunction;
3765 } else {
3766 kind = pc_->atModuleLevel() ? DeclarationKind::ModuleBodyLevelFunction
3767 : DeclarationKind::BodyLevelFunction;
3768 }
3769
3770 if (!noteDeclaredName(name, kind, pos())) {
3771 return errorResult();
3772 }
3773
3774 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
3775 FunctionNodeType funNode;
3776 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3777
3778 // Under sloppy mode, try Annex B.3.3 semantics. If making an additional
3779 // 'var' binding of the same name does not throw an early error, do so.
3780 // This 'var' binding would be assigned the function object when its
3781 // declaration is reached, not at the start of the block.
3782 //
3783 // This semantics is implemented upon Scope exit in
3784 // Scope::propagateAndMarkAnnexBFunctionBoxes.
3785 bool tryAnnexB = kind == DeclarationKind::SloppyLexicalFunction;
3786
3787 YieldHandling newYieldHandling = GetYieldHandling(generatorKind);
3788 return functionDefinition(funNode, toStringStart, InAllowed, newYieldHandling,
3789 name, syntaxKind, generatorKind, asyncKind,
3790 tryAnnexB);
3791}
3792
3793template <class ParseHandler, typename Unit>
3794typename ParseHandler::FunctionNodeResult
3795GeneralParser<ParseHandler, Unit>::functionExpr(uint32_t toStringStart,
3796 InvokedPrediction invoked,
3797 FunctionAsyncKind asyncKind) {
3798 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3798); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 3798; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3799
3800 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(
3801 this, GetAwaitHandling(asyncKind));
3802 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
3803 TokenKind tt;
3804 if (!tokenStream.getToken(&tt)) {
3805 return errorResult();
3806 }
3807
3808 if (tt == TokenKind::Mul) {
3809 generatorKind = GeneratorKind::Generator;
3810 if (!tokenStream.getToken(&tt)) {
3811 return errorResult();
3812 }
3813 }
3814
3815 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
3816
3817 TaggedParserAtomIndex name;
3818 if (TokenKindIsPossibleIdentifier(tt)) {
3819 name = bindingIdentifier(yieldHandling);
3820 if (!name) {
3821 return errorResult();
3822 }
3823 } else {
3824 anyChars.ungetToken();
3825 }
3826
3827 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Expression;
3828 FunctionNodeType funNode;
3829 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3830
3831 if (invoked) {
3832 funNode = handler_.setLikelyIIFE(funNode);
3833 }
3834
3835 return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
3836 name, syntaxKind, generatorKind, asyncKind);
3837}
3838
3839/*
3840 * Return true if this node, known to be an unparenthesized string literal
3841 * that never contain escape sequences, could be the string of a directive in a
3842 * Directive Prologue. Directive strings never contain escape sequences or line
3843 * continuations.
3844 */
3845static inline bool IsUseStrictDirective(const TokenPos& pos,
3846 TaggedParserAtomIndex atom) {
3847 // the length of "use strict", including quotation.
3848 static constexpr size_t useStrictLength = 12;
3849 return atom == TaggedParserAtomIndex::WellKnown::use_strict_() &&
3850 pos.begin + useStrictLength == pos.end;
3851}
3852static inline bool IsUseAsmDirective(const TokenPos& pos,
3853 TaggedParserAtomIndex atom) {
3854 // the length of "use asm", including quotation.
3855 static constexpr size_t useAsmLength = 9;
3856 return atom == TaggedParserAtomIndex::WellKnown::use_asm_() &&
3857 pos.begin + useAsmLength == pos.end;
3858}
3859
3860template <typename Unit>
3861bool Parser<SyntaxParseHandler, Unit>::asmJS(ListNodeType list) {
3862 // While asm.js could technically be validated and compiled during syntax
3863 // parsing, we have no guarantee that some later JS wouldn't abort the
3864 // syntax parse and cause us to re-parse (and re-compile) the asm.js module.
3865 // For simplicity, unconditionally abort the syntax parse when "use asm" is
3866 // encountered so that asm.js is always validated/compiled exactly once
3867 // during a full parse.
3868 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3868); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 3868; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
3869 return false;
3870}
3871
3872template <typename Unit>
3873bool Parser<FullParseHandler, Unit>::asmJS(ListNodeType list) {
3874 // Disable syntax parsing in anything nested inside the asm.js module.
3875 disableSyntaxParser();
3876
3877 // We should be encountering the "use asm" directive for the first time; if
3878 // the directive is already, we must have failed asm.js validation and we're
3879 // reparsing. In that case, don't try to validate again. A non-null
3880 // newDirectives means we're not in a normal function.
3881 if (!pc_->newDirectives || pc_->newDirectives->asmJS()) {
3882 return true;
3883 }
3884
3885 // If there is no ScriptSource, then we are doing a non-compiling parse and
3886 // so we shouldn't (and can't, without a ScriptSource) compile.
3887 if (ss == nullptr) {
3888 return true;
3889 }
3890
3891 pc_->functionBox()->useAsm = true;
3892
3893 // Attempt to validate and compile this asm.js module. On success, the
3894 // tokenStream has been advanced to the closing }. On failure, the
3895 // tokenStream is in an indeterminate state and we must reparse the
3896 // function from the beginning. Reparsing is triggered by marking that a
3897 // new directive has been encountered and returning 'false'.
3898 bool validated;
3899 if (!CompileAsmJS(this->fc_, this->parserAtoms(), *this, list, &validated)) {
3900 return false;
3901 }
3902 if (!validated) {
3903 pc_->newDirectives->setAsmJS();
3904 return false;
3905 }
3906
3907 return true;
3908}
3909
3910template <class ParseHandler, typename Unit>
3911inline bool GeneralParser<ParseHandler, Unit>::asmJS(ListNodeType list) {
3912 return asFinalParser()->asmJS(list);
3913}
3914
3915/*
3916 * Recognize Directive Prologue members and directives. Assuming |pn| is a
3917 * candidate for membership in a directive prologue, recognize directives and
3918 * set |pc_|'s flags accordingly. If |pn| is indeed part of a prologue, set its
3919 * |prologue| flag.
3920 *
3921 * Note that the following is a strict mode function:
3922 *
3923 * function foo() {
3924 * "blah" // inserted semi colon
3925 * "blurgh"
3926 * "use\x20loose"
3927 * "use strict"
3928 * }
3929 *
3930 * That is, even though "use\x20loose" can never be a directive, now or in the
3931 * future (because of the hex escape), the Directive Prologue extends through it
3932 * to the "use strict" statement, which is indeed a directive.
3933 */
3934template <class ParseHandler, typename Unit>
3935bool GeneralParser<ParseHandler, Unit>::maybeParseDirective(
3936 ListNodeType list, Node possibleDirective, bool* cont) {
3937 TokenPos directivePos;
3938 TaggedParserAtomIndex directive =
3939 handler_.isStringExprStatement(possibleDirective, &directivePos);
3940
3941 *cont = !!directive;
3942 if (!*cont) {
3943 return true;
3944 }
3945
3946 if (IsUseStrictDirective(directivePos, directive)) {
3947 // Functions with non-simple parameter lists (destructuring,
3948 // default or rest parameters) must not contain a "use strict"
3949 // directive.
3950 if (pc_->isFunctionBox()) {
3951 FunctionBox* funbox = pc_->functionBox();
3952 if (!funbox->hasSimpleParameterList()) {
3953 const char* parameterKind = funbox->hasDestructuringArgs
3954 ? "destructuring"
3955 : funbox->hasParameterExprs ? "default"
3956 : "rest";
3957 errorAt(directivePos.begin, JSMSG_STRICT_NON_SIMPLE_PARAMS,
3958 parameterKind);
3959 return false;
3960 }
3961 }
3962
3963 // We're going to be in strict mode. Note that this scope explicitly
3964 // had "use strict";
3965 pc_->sc()->setExplicitUseStrict();
3966 if (!pc_->sc()->strict()) {
3967 // Some strict mode violations can appear before a Use Strict Directive
3968 // is applied. (See the |DeprecatedContent| enum initializers.) These
3969 // violations can manifest in two ways.
3970 //
3971 // First, the violation can appear *before* the Use Strict Directive.
3972 // Numeric literals (and therefore octal literals) can only precede a
3973 // Use Strict Directive if this function's parameter list is not simple,
3974 // but we reported an error for non-simple parameter lists above, so
3975 // octal literals present no issue. But octal escapes and \8 and \9 can
3976 // appear in the directive prologue before a Use Strict Directive:
3977 //
3978 // function f()
3979 // {
3980 // "hell\157 world"; // octal escape
3981 // "\8"; "\9"; // NonOctalDecimalEscape
3982 // "use strict"; // retroactively makes all the above errors
3983 // }
3984 //
3985 // Second, the violation can appear *after* the Use Strict Directive but
3986 // *before* the directive is recognized as terminated. This only
3987 // happens when a directive is terminated by ASI, and the next token
3988 // contains a violation:
3989 //
3990 // function a()
3991 // {
3992 // "use strict" // ASI
3993 // 0755;
3994 // }
3995 // function b()
3996 // {
3997 // "use strict" // ASI
3998 // "hell\157 world";
3999 // }
4000 // function c()
4001 // {
4002 // "use strict" // ASI
4003 // "\8";
4004 // }
4005 //
4006 // We note such violations when tokenizing. Then, if a violation has
4007 // been observed at the time a "use strict" is applied, we report the
4008 // error.
4009 switch (anyChars.sawDeprecatedContent()) {
4010 case DeprecatedContent::None:
4011 break;
4012 case DeprecatedContent::OctalLiteral:
4013 error(JSMSG_DEPRECATED_OCTAL_LITERAL);
4014 return false;
4015 case DeprecatedContent::OctalEscape:
4016 error(JSMSG_DEPRECATED_OCTAL_ESCAPE);
4017 return false;
4018 case DeprecatedContent::EightOrNineEscape:
4019 error(JSMSG_DEPRECATED_EIGHT_OR_NINE_ESCAPE);
4020 return false;
4021 }
4022
4023 pc_->sc()->setStrictScript();
4024 }
4025 } else if (IsUseAsmDirective(directivePos, directive)) {
4026 if (pc_->isFunctionBox()) {
4027 return asmJS(list);
4028 }
4029 return warningAt(directivePos.begin, JSMSG_USE_ASM_DIRECTIVE_FAIL);
4030 }
4031 return true;
4032}
4033
4034template <class ParseHandler, typename Unit>
4035typename ParseHandler::ListNodeResult
4036GeneralParser<ParseHandler, Unit>::statementList(YieldHandling yieldHandling) {
4037 AutoCheckRecursionLimit recursion(this->fc_);
4038 if (!recursion.check(this->fc_)) {
4039 return errorResult();
4040 }
4041
4042 ListNodeType stmtList;
4043 MOZ_TRY_VAR(stmtList, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
4044
4045 bool canHaveDirectives = pc_->atBodyLevel();
4046 if (canHaveDirectives) {
4047 // Clear flags for deprecated content that might have been seen in an
4048 // enclosing context.
4049 anyChars.clearSawDeprecatedContent();
4050 }
4051
4052 bool canHaveHashbangComment = pc_->atTopLevel();
4053 if (canHaveHashbangComment) {
4054 tokenStream.consumeOptionalHashbangComment();
4055 }
4056
4057 bool afterReturn = false;
4058 bool warnedAboutStatementsAfterReturn = false;
4059 uint32_t statementBegin = 0;
4060 for (;;) {
4061 TokenKind tt = TokenKind::Eof;
4062 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
4063 if (anyChars.isEOF()) {
4064 isUnexpectedEOF_ = true;
4065 }
4066 return errorResult();
4067 }
4068 if (tt == TokenKind::Eof || tt == TokenKind::RightCurly) {
4069 TokenPos pos;
4070 if (!tokenStream.peekTokenPos(&pos, TokenStream::SlashIsRegExp)) {
4071 return errorResult();
4072 }
4073 handler_.setListEndPosition(stmtList, pos);
4074 break;
4075 }
4076 if (afterReturn) {
4077 if (!tokenStream.peekOffset(&statementBegin,
4078 TokenStream::SlashIsRegExp)) {
4079 return errorResult();
4080 }
4081 }
4082 auto nextResult = statementListItem(yieldHandling, canHaveDirectives);
4083 if (nextResult.isErr()) {
4084 if (anyChars.isEOF()) {
4085 isUnexpectedEOF_ = true;
4086 }
4087 return errorResult();
4088 }
4089 Node next = nextResult.unwrap();
4090 if (!warnedAboutStatementsAfterReturn) {
4091 if (afterReturn) {
4092 if (!handler_.isStatementPermittedAfterReturnStatement(next)) {
4093 if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
4094 return errorResult();
4095 }
4096
4097 warnedAboutStatementsAfterReturn = true;
4098 }
4099 } else if (handler_.isReturnStatement(next)) {
4100 afterReturn = true;
4101 }
4102 }
4103
4104 if (canHaveDirectives) {
4105 if (!maybeParseDirective(stmtList, next, &canHaveDirectives)) {
4106 return errorResult();
4107 }
4108 }
4109
4110 handler_.addStatementToList(stmtList, next);
4111 }
4112
4113 return stmtList;
4114}
4115
4116template <class ParseHandler, typename Unit>
4117typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::condition(
4118 InHandling inHandling, YieldHandling yieldHandling) {
4119 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_COND)) {
4120 return errorResult();
4121 }
4122
4123 Node pn;
4124 MOZ_TRY_VAR(pn, exprInParens(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (exprInParens(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (pn) = mozTryVarTempResult_.unwrap(); } while (0)
;
4125
4126 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_COND)) {
4127 return errorResult();
4128 }
4129
4130 return pn;
4131}
4132
4133template <class ParseHandler, typename Unit>
4134bool GeneralParser<ParseHandler, Unit>::matchLabel(
4135 YieldHandling yieldHandling, TaggedParserAtomIndex* labelOut) {
4136 MOZ_ASSERT(labelOut != nullptr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(labelOut != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(labelOut != nullptr))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("labelOut != nullptr"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4136); AnnotateMozCrashReason("MOZ_ASSERT" "(" "labelOut != nullptr"
")"); do { *((volatile int*)__null) = 4136; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4137 TokenKind tt = TokenKind::Eof;
4138 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
4139 return false;
4140 }
4141
4142 if (TokenKindIsPossibleIdentifier(tt)) {
4143 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
4144
4145 *labelOut = labelIdentifier(yieldHandling);
4146 if (!*labelOut) {
4147 return false;
4148 }
4149 } else {
4150 *labelOut = TaggedParserAtomIndex::null();
4151 }
4152 return true;
4153}
4154
4155template <class ParseHandler, typename Unit>
4156GeneralParser<ParseHandler, Unit>::PossibleError::PossibleError(
4157 GeneralParser<ParseHandler, Unit>& parser)
4158 : parser_(parser) {}
4159
4160template <class ParseHandler, typename Unit>
4161typename GeneralParser<ParseHandler, Unit>::PossibleError::Error&
4162GeneralParser<ParseHandler, Unit>::PossibleError::error(ErrorKind kind) {
4163 if (kind == ErrorKind::Expression) {
4164 return exprError_;
4165 }
4166 if (kind == ErrorKind::Destructuring) {
4167 return destructuringError_;
4168 }
4169 MOZ_ASSERT(kind == ErrorKind::DestructuringWarning)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ErrorKind::DestructuringWarning)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == ErrorKind::DestructuringWarning))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("kind == ErrorKind::DestructuringWarning"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4169); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ErrorKind::DestructuringWarning"
")"); do { *((volatile int*)__null) = 4169; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4170 return destructuringWarning_;
4171}
4172
4173template <class ParseHandler, typename Unit>
4174void GeneralParser<ParseHandler, Unit>::PossibleError::setResolved(
4175 ErrorKind kind) {
4176 error(kind).state_ = ErrorState::None;
4177}
4178
4179template <class ParseHandler, typename Unit>
4180bool GeneralParser<ParseHandler, Unit>::PossibleError::hasError(
4181 ErrorKind kind) {
4182 return error(kind).state_ == ErrorState::Pending;
4183}
4184
4185template <class ParseHandler, typename Unit>
4186bool GeneralParser<ParseHandler,
4187 Unit>::PossibleError::hasPendingDestructuringError() {
4188 return hasError(ErrorKind::Destructuring);
4189}
4190
4191template <class ParseHandler, typename Unit>
4192void GeneralParser<ParseHandler, Unit>::PossibleError::setPending(
4193 ErrorKind kind, const TokenPos& pos, unsigned errorNumber) {
4194 // Don't overwrite a previously recorded error.
4195 if (hasError(kind)) {
4196 return;
4197 }
4198
4199 // If we report an error later, we'll do it from the position where we set
4200 // the state to pending.
4201 Error& err = error(kind);
4202 err.offset_ = pos.begin;
4203 err.errorNumber_ = errorNumber;
4204 err.state_ = ErrorState::Pending;
4205}
4206
4207template <class ParseHandler, typename Unit>
4208void GeneralParser<ParseHandler, Unit>::PossibleError::
4209 setPendingDestructuringErrorAt(const TokenPos& pos, unsigned errorNumber) {
4210 setPending(ErrorKind::Destructuring, pos, errorNumber);
4211}
4212
4213template <class ParseHandler, typename Unit>
4214void GeneralParser<ParseHandler, Unit>::PossibleError::
4215 setPendingDestructuringWarningAt(const TokenPos& pos,
4216 unsigned errorNumber) {
4217 setPending(ErrorKind::DestructuringWarning, pos, errorNumber);
4218}
4219
4220template <class ParseHandler, typename Unit>
4221void GeneralParser<ParseHandler, Unit>::PossibleError::
4222 setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber) {
4223 setPending(ErrorKind::Expression, pos, errorNumber);
4224}
4225
4226template <class ParseHandler, typename Unit>
4227bool GeneralParser<ParseHandler, Unit>::PossibleError::checkForError(
4228 ErrorKind kind) {
4229 if (!hasError(kind)) {
4230 return true;
4231 }
4232
4233 Error& err = error(kind);
4234 parser_.errorAt(err.offset_, err.errorNumber_);
4235 return false;
4236}
4237
4238template <class ParseHandler, typename Unit>
4239bool GeneralParser<ParseHandler,
4240 Unit>::PossibleError::checkForDestructuringErrorOrWarning() {
4241 // Clear pending expression error, because we're definitely not in an
4242 // expression context.
4243 setResolved(ErrorKind::Expression);
4244
4245 // Report any pending destructuring error.
4246 return checkForError(ErrorKind::Destructuring);
4247}
4248
4249template <class ParseHandler, typename Unit>
4250bool GeneralParser<ParseHandler,
4251 Unit>::PossibleError::checkForExpressionError() {
4252 // Clear pending destructuring error, because we're definitely not
4253 // in a destructuring context.
4254 setResolved(ErrorKind::Destructuring);
4255 setResolved(ErrorKind::DestructuringWarning);
4256
4257 // Report any pending expression error.
4258 return checkForError(ErrorKind::Expression);
4259}
4260
4261template <class ParseHandler, typename Unit>
4262void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorTo(
4263 ErrorKind kind, PossibleError* other) {
4264 if (hasError(kind) && !other->hasError(kind)) {
4265 Error& err = error(kind);
4266 Error& otherErr = other->error(kind);
4267 otherErr.offset_ = err.offset_;
4268 otherErr.errorNumber_ = err.errorNumber_;
4269 otherErr.state_ = err.state_;
4270 }
4271}
4272
4273template <class ParseHandler, typename Unit>
4274void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorsTo(
4275 PossibleError* other) {
4276 MOZ_ASSERT(other)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(other)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(other))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("other", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "other" ")")
; do { *((volatile int*)__null) = 4276; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4277 MOZ_ASSERT(this != other)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this != other)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(this != other))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("this != other",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4277); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this != other"
")"); do { *((volatile int*)__null) = 4277; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4278 MOZ_ASSERT(&parser_ == &other->parser_,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(&parser_ == &other->parser_)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(&parser_ == &other->parser_))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("&parser_ == &other->parser_"
" (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4280); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4280
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
4279 "Can't transfer fields to an instance which belongs to a "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(&parser_ == &other->parser_)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(&parser_ == &other->parser_))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("&parser_ == &other->parser_"
" (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4280); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4280
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
4280 "different parser")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(&parser_ == &other->parser_)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(&parser_ == &other->parser_))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("&parser_ == &other->parser_"
" (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4280); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4280
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
4281
4282 transferErrorTo(ErrorKind::Destructuring, other);
4283 transferErrorTo(ErrorKind::Expression, other);
4284}
4285
4286template <class ParseHandler, typename Unit>
4287typename ParseHandler::BinaryNodeResult
4288GeneralParser<ParseHandler, Unit>::bindingInitializer(
4289 Node lhs, DeclarationKind kind, YieldHandling yieldHandling) {
4290 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assign))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Assign)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Assign)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4290); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assign)"
")"); do { *((volatile int*)__null) = 4290; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4291
4292 if (kind == DeclarationKind::FormalParameter) {
4293 pc_->functionBox()->hasParameterExprs = true;
4294 }
4295
4296 Node rhs;
4297 MOZ_TRY_VAR(rhs, assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
4298
4299 BinaryNodeType assign;
4300 MOZ_TRY_VAR(assign,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assign) = mozTryVarTempResult_.unwrap(); } while (0)
4301 handler_.newAssignment(ParseNodeKind::AssignExpr, lhs, rhs))do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assign) = mozTryVarTempResult_.unwrap(); } while (0)
;
4302
4303 return assign;
4304}
4305
4306template <class ParseHandler, typename Unit>
4307typename ParseHandler::NameNodeResult
4308GeneralParser<ParseHandler, Unit>::bindingIdentifier(
4309 DeclarationKind kind, YieldHandling yieldHandling) {
4310 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
4311 if (!name) {
4312 return errorResult();
4313 }
4314
4315 NameNodeType binding;
4316 MOZ_TRY_VAR(binding, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (binding) = mozTryVarTempResult_.unwrap();
} while (0)
;
4317 if (!noteDeclaredName(name, kind, pos())) {
4318 return errorResult();
4319 }
4320
4321 return binding;
4322}
4323
4324template <class ParseHandler, typename Unit>
4325typename ParseHandler::NodeResult
4326GeneralParser<ParseHandler, Unit>::bindingIdentifierOrPattern(
4327 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4328 if (tt == TokenKind::LeftBracket) {
4329 return arrayBindingPattern(kind, yieldHandling);
4330 }
4331
4332 if (tt == TokenKind::LeftCurly) {
4333 return objectBindingPattern(kind, yieldHandling);
4334 }
4335
4336 if (!TokenKindIsPossibleIdentifierName(tt)) {
4337 error(JSMSG_NO_VARIABLE_NAME);
4338 return errorResult();
4339 }
4340
4341 return bindingIdentifier(kind, yieldHandling);
4342}
4343
4344template <class ParseHandler, typename Unit>
4345typename ParseHandler::ListNodeResult
4346GeneralParser<ParseHandler, Unit>::objectBindingPattern(
4347 DeclarationKind kind, YieldHandling yieldHandling) {
4348 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4348); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4348; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4349
4350 AutoCheckRecursionLimit recursion(this->fc_);
4351 if (!recursion.check(this->fc_)) {
4352 return errorResult();
4353 }
4354
4355 uint32_t begin = pos().begin;
4356 ListNodeType literal;
4357 MOZ_TRY_VAR(literal, handler_.newObjectLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newObjectLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4358
4359 Maybe<DeclarationKind> declKind = Some(kind);
4360 TaggedParserAtomIndex propAtom;
4361 for (;;) {
4362 TokenKind tt;
4363 if (!tokenStream.peekToken(&tt)) {
4364 return errorResult();
4365 }
4366 if (tt == TokenKind::RightCurly) {
4367 break;
4368 }
4369
4370 if (tt == TokenKind::TripleDot) {
4371 tokenStream.consumeKnownToken(TokenKind::TripleDot);
4372 uint32_t begin = pos().begin;
4373
4374 TokenKind tt;
4375 if (!tokenStream.getToken(&tt)) {
4376 return errorResult();
4377 }
4378
4379 if (!TokenKindIsPossibleIdentifierName(tt)) {
4380 error(JSMSG_NO_VARIABLE_NAME);
4381 return errorResult();
4382 }
4383
4384 NameNodeType inner;
4385 MOZ_TRY_VAR(inner, bindingIdentifier(kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(kind, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (inner) =
mozTryVarTempResult_.unwrap(); } while (0)
;
4386
4387 if (!handler_.addSpreadProperty(literal, begin, inner)) {
4388 return errorResult();
4389 }
4390 } else {
4391 TokenPos namePos = anyChars.nextToken().pos;
4392
4393 PropertyType propType;
4394 Node propName;
4395 MOZ_TRY_VAR(propName, propertyOrMethodName(do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInPattern, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
4396 yieldHandling, PropertyNameInPattern, declKind,do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInPattern, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
4397 literal, &propType, &propAtom))do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInPattern, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
4398
4399 if (propType == PropertyType::Normal) {
4400 // Handle e.g., |var {p: x} = o| and |var {p: x=0} = o|.
4401
4402 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
4403 return errorResult();
4404 }
4405
4406 Node binding;
4407 MOZ_TRY_VAR(binding,do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (binding) = mozTryVarTempResult_.unwrap(); } while (0)
4408 bindingIdentifierOrPattern(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (binding) = mozTryVarTempResult_.unwrap(); } while (0)
;
4409
4410 bool hasInitializer;
4411 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
4412 TokenStream::SlashIsRegExp)) {
4413 return errorResult();
4414 }
4415
4416 Node bindingExpr;
4417 if (hasInitializer) {
4418 MOZ_TRY_VAR(bindingExpr,do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
4419 bindingInitializer(binding, kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
4420 } else {
4421 bindingExpr = binding;
4422 }
4423
4424 if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
4425 return errorResult();
4426 }
4427 } else if (propType == PropertyType::Shorthand) {
4428 // Handle e.g., |var {x, y} = o| as destructuring shorthand
4429 // for |var {x: x, y: y} = o|.
4430 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(tt))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(TokenKindIsPossibleIdentifierName(tt)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifierName(tt)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4430); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(tt)"
")"); do { *((volatile int*)__null) = 4430; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4431
4432 NameNodeType binding;
4433 MOZ_TRY_VAR(binding, bindingIdentifier(kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(kind, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4434
4435 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
4436 binding)) {
4437 return errorResult();
4438 }
4439 } else if (propType == PropertyType::CoverInitializedName) {
4440 // Handle e.g., |var {x=1, y=2} = o| as destructuring
4441 // shorthand with default values.
4442 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(tt))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(TokenKindIsPossibleIdentifierName(tt)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifierName(tt)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(tt)"
")"); do { *((volatile int*)__null) = 4442; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4443
4444 NameNodeType binding;
4445 MOZ_TRY_VAR(binding, bindingIdentifier(kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(kind, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4446
4447 tokenStream.consumeKnownToken(TokenKind::Assign);
4448
4449 BinaryNodeType bindingExpr;
4450 MOZ_TRY_VAR(bindingExpr,do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
4451 bindingInitializer(binding, kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
4452
4453 if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
4454 return errorResult();
4455 }
4456 } else {
4457 errorAt(namePos.begin, JSMSG_NO_VARIABLE_NAME);
4458 return errorResult();
4459 }
4460 }
4461
4462 bool matched;
4463 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
4464 TokenStream::SlashIsInvalid)) {
4465 return errorResult();
4466 }
4467 if (!matched) {
4468 break;
4469 }
4470 if (tt == TokenKind::TripleDot) {
4471 error(JSMSG_REST_WITH_COMMA);
4472 return errorResult();
4473 }
4474 }
4475
4476 if (!mustMatchToken(TokenKind::RightCurly, [this, begin](TokenKind actual) {
4477 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST, JSMSG_CURLY_OPENED,
4478 begin);
4479 })) {
4480 return errorResult();
4481 }
4482
4483 handler_.setEndPosition(literal, pos().end);
4484 return literal;
4485}
4486
4487template <class ParseHandler, typename Unit>
4488typename ParseHandler::ListNodeResult
4489GeneralParser<ParseHandler, Unit>::arrayBindingPattern(
4490 DeclarationKind kind, YieldHandling yieldHandling) {
4491 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 4491; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4492
4493 AutoCheckRecursionLimit recursion(this->fc_);
4494 if (!recursion.check(this->fc_)) {
4495 return errorResult();
4496 }
4497
4498 uint32_t begin = pos().begin;
4499 ListNodeType literal;
4500 MOZ_TRY_VAR(literal, handler_.newArrayLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newArrayLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4501
4502 uint32_t index = 0;
4503 for (;; index++) {
4504 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
4505 error(JSMSG_ARRAY_INIT_TOO_BIG);
4506 return errorResult();
4507 }
4508
4509 TokenKind tt;
4510 if (!tokenStream.getToken(&tt)) {
4511 return errorResult();
4512 }
4513
4514 if (tt == TokenKind::RightBracket) {
4515 anyChars.ungetToken();
4516 break;
4517 }
4518
4519 if (tt == TokenKind::Comma) {
4520 if (!handler_.addElision(literal, pos())) {
4521 return errorResult();
4522 }
4523 } else if (tt == TokenKind::TripleDot) {
4524 uint32_t begin = pos().begin;
4525
4526 TokenKind tt;
4527 if (!tokenStream.getToken(&tt)) {
4528 return errorResult();
4529 }
4530
4531 Node inner;
4532 MOZ_TRY_VAR(inner, bindingIdentifierOrPattern(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
;
4533
4534 if (!handler_.addSpreadElement(literal, begin, inner)) {
4535 return errorResult();
4536 }
4537 } else {
4538 Node binding;
4539 MOZ_TRY_VAR(binding, bindingIdentifierOrPattern(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (binding) = mozTryVarTempResult_.unwrap(); } while (0)
;
4540
4541 bool hasInitializer;
4542 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
4543 TokenStream::SlashIsRegExp)) {
4544 return errorResult();
4545 }
4546
4547 Node element;
4548 if (hasInitializer) {
4549 MOZ_TRY_VAR(element, bindingInitializer(binding, kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (element) = mozTryVarTempResult_.unwrap(); } while (0)
;
4550 } else {
4551 element = binding;
4552 }
4553
4554 handler_.addArrayElement(literal, element);
4555 }
4556
4557 if (tt != TokenKind::Comma) {
4558 // If we didn't already match TokenKind::Comma in above case.
4559 bool matched;
4560 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
4561 TokenStream::SlashIsRegExp)) {
4562 return errorResult();
4563 }
4564 if (!matched) {
4565 break;
4566 }
4567
4568 if (tt == TokenKind::TripleDot) {
4569 error(JSMSG_REST_WITH_COMMA);
4570 return errorResult();
4571 }
4572 }
4573 }
4574
4575 if (!mustMatchToken(TokenKind::RightBracket, [this, begin](TokenKind actual) {
4576 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
4577 JSMSG_BRACKET_OPENED, begin);
4578 })) {
4579 return errorResult();
4580 }
4581
4582 handler_.setEndPosition(literal, pos().end);
4583 return literal;
4584}
4585
4586template <class ParseHandler, typename Unit>
4587typename ParseHandler::NodeResult
4588GeneralParser<ParseHandler, Unit>::destructuringDeclaration(
4589 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4590 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4590); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 4590; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4591 MOZ_ASSERT(tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4591); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly"
")"); do { *((volatile int*)__null) = 4591; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4592
4593 if (tt == TokenKind::LeftBracket) {
4594 return arrayBindingPattern(kind, yieldHandling);
4595 }
4596 return objectBindingPattern(kind, yieldHandling);
4597}
4598
4599template <class ParseHandler, typename Unit>
4600typename ParseHandler::NodeResult
4601GeneralParser<ParseHandler, Unit>::destructuringDeclarationWithoutYieldOrAwait(
4602 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4603 uint32_t startYieldOffset = pc_->lastYieldOffset;
4604 uint32_t startAwaitOffset = pc_->lastAwaitOffset;
4605
4606 Node res;
4607 MOZ_TRY_VAR(res, destructuringDeclaration(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (destructuringDeclaration(kind
, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (res) = mozTryVarTempResult_.unwrap(); } while (0)
;
4608
4609 if (pc_->lastYieldOffset != startYieldOffset) {
4610 errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
4611 return errorResult();
4612 }
4613 if (pc_->lastAwaitOffset != startAwaitOffset) {
4614 errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
4615 return errorResult();
4616 }
4617 return res;
4618}
4619
4620template <class ParseHandler, typename Unit>
4621typename ParseHandler::LexicalScopeNodeResult
4622GeneralParser<ParseHandler, Unit>::blockStatement(YieldHandling yieldHandling,
4623 unsigned errorNumber) {
4624 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4624); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4624; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4625 uint32_t openedPos = pos().begin;
4626
4627 ParseContext::Statement stmt(pc_, StatementKind::Block);
4628 ParseContext::Scope scope(this);
4629 if (!scope.init(pc_)) {
4630 return errorResult();
4631 }
4632
4633 ListNodeType list;
4634 MOZ_TRY_VAR(list, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (list) = mozTryVarTempResult_
.unwrap(); } while (0)
;
4635
4636 if (!mustMatchToken(TokenKind::RightCurly, [this, errorNumber,
4637 openedPos](TokenKind actual) {
4638 this->reportMissingClosing(errorNumber, JSMSG_CURLY_OPENED, openedPos);
4639 })) {
4640 return errorResult();
4641 }
4642
4643 return finishLexicalScope(scope, list);
4644}
4645
4646template <class ParseHandler, typename Unit>
4647typename ParseHandler::NodeResult
4648GeneralParser<ParseHandler, Unit>::expressionAfterForInOrOf(
4649 ParseNodeKind forHeadKind, YieldHandling yieldHandling) {
4650 MOZ_ASSERT(forHeadKind == ParseNodeKind::ForIn ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(forHeadKind == ParseNodeKind::ForIn || forHeadKind ==
ParseNodeKind::ForOf)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(forHeadKind == ParseNodeKind
::ForIn || forHeadKind == ParseNodeKind::ForOf))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 4651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4651 forHeadKind == ParseNodeKind::ForOf)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(forHeadKind == ParseNodeKind::ForIn || forHeadKind ==
ParseNodeKind::ForOf)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(forHeadKind == ParseNodeKind
::ForIn || forHeadKind == ParseNodeKind::ForOf))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 4651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4652 if (forHeadKind == ParseNodeKind::ForOf) {
4653 return assignExpr(InAllowed, yieldHandling, TripledotProhibited);
4654 }
4655
4656 return expr(InAllowed, yieldHandling, TripledotProhibited);
4657}
4658
4659template <class ParseHandler, typename Unit>
4660typename ParseHandler::NodeResult
4661GeneralParser<ParseHandler, Unit>::declarationPattern(
4662 DeclarationKind declKind, TokenKind tt, bool initialDeclaration,
4663 YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
4664 Node* forInOrOfExpression) {
4665 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket) ||
anyChars.isCurrentTokenType(TokenKind::LeftCurly))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars
.isCurrentTokenType(TokenKind::LeftCurly)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4666); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4666; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4666 anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket) ||
anyChars.isCurrentTokenType(TokenKind::LeftCurly))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars
.isCurrentTokenType(TokenKind::LeftCurly)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4666); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4666; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4667
4668 Node pattern;
4669 MOZ_TRY_VAR(pattern, destructuringDeclaration(declKind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (destructuringDeclaration(declKind
, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (pattern) = mozTryVarTempResult_.unwrap(); } while (0)
;
4670
4671 if (initialDeclaration && forHeadKind) {
4672 bool isForIn, isForOf;
4673 if (!matchInOrOf(&isForIn, &isForOf)) {
4674 return errorResult();
4675 }
4676
4677 if (isForIn) {
4678 *forHeadKind = ParseNodeKind::ForIn;
4679 } else if (isForOf) {
4680 *forHeadKind = ParseNodeKind::ForOf;
4681 } else {
4682 *forHeadKind = ParseNodeKind::ForHead;
4683 }
4684
4685 if (*forHeadKind != ParseNodeKind::ForHead) {
4686 MOZ_TRY_VAR(*forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4687 expressionAfterForInOrOf(*forHeadKind, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4688
4689 return pattern;
4690 }
4691 }
4692
4693 if (!mustMatchToken(TokenKind::Assign, JSMSG_BAD_DESTRUCT_DECL)) {
4694 return errorResult();
4695 }
4696
4697 Node init;
4698 MOZ_TRY_VAR(init, assignExpr(forHeadKind ? InProhibited : InAllowed,do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (init) = mozTryVarTempResult_.unwrap(); } while
(0)
4699 yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (init) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4700
4701 return handler_.newAssignment(ParseNodeKind::AssignExpr, pattern, init);
4702}
4703
4704template <class ParseHandler, typename Unit>
4705typename ParseHandler::AssignmentNodeResult
4706GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
4707 NameNodeType binding, DeclarationKind declKind, bool initialDeclaration,
4708 YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
4709 Node* forInOrOfExpression) {
4710 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assign))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Assign)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Assign)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4710); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assign)"
")"); do { *((volatile int*)__null) = 4710; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4711
4712 uint32_t initializerOffset;
4713 if (!tokenStream.peekOffset(&initializerOffset, TokenStream::SlashIsRegExp)) {
4714 return errorResult();
4715 }
4716
4717 Node initializer;
4718 MOZ_TRY_VAR(initializer, assignExpr(forHeadKind ? InProhibited : InAllowed,do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializer) = mozTryVarTempResult_.unwrap
(); } while (0)
4719 yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializer) = mozTryVarTempResult_.unwrap
(); } while (0)
;
4720
4721 if (forHeadKind && initialDeclaration) {
4722 bool isForIn, isForOf;
4723 if (!matchInOrOf(&isForIn, &isForOf)) {
4724 return errorResult();
4725 }
4726
4727 // An initialized declaration can't appear in a for-of:
4728 //
4729 // for (var/let/const x = ... of ...); // BAD
4730 if (isForOf) {
4731 errorAt(initializerOffset, JSMSG_OF_AFTER_FOR_LOOP_DECL);
4732 return errorResult();
4733 }
4734
4735 if (isForIn) {
4736 // Lexical declarations in for-in loops can't be initialized:
4737 //
4738 // for (let/const x = ... in ...); // BAD
4739 if (DeclarationKindIsLexical(declKind)) {
4740 errorAt(initializerOffset, JSMSG_IN_AFTER_LEXICAL_FOR_DECL);
4741 return errorResult();
4742 }
4743
4744 // This leaves only initialized for-in |var| declarations. ES6
4745 // forbids these; later ES un-forbids in non-strict mode code.
4746 *forHeadKind = ParseNodeKind::ForIn;
4747 if (!strictModeErrorAt(initializerOffset,
4748 JSMSG_INVALID_FOR_IN_DECL_WITH_INIT)) {
4749 return errorResult();
4750 }
4751
4752 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4753 *forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4754 expressionAfterForInOrOf(ParseNodeKind::ForIn, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4755 } else {
4756 *forHeadKind = ParseNodeKind::ForHead;
4757 }
4758 }
4759
4760 return handler_.finishInitializerAssignment(binding, initializer);
4761}
4762
4763template <class ParseHandler, typename Unit>
4764typename ParseHandler::NodeResult
4765GeneralParser<ParseHandler, Unit>::declarationName(DeclarationKind declKind,
4766 TokenKind tt,
4767 bool initialDeclaration,
4768 YieldHandling yieldHandling,
4769 ParseNodeKind* forHeadKind,
4770 Node* forInOrOfExpression) {
4771 // Anything other than possible identifier is an error.
4772 if (!TokenKindIsPossibleIdentifier(tt)) {
4773 error(JSMSG_NO_VARIABLE_NAME);
4774 return errorResult();
4775 }
4776
4777 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
4778 if (!name) {
4779 return errorResult();
4780 }
4781
4782 NameNodeType binding;
4783 MOZ_TRY_VAR(binding, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (binding) = mozTryVarTempResult_.unwrap();
} while (0)
;
4784
4785 TokenPos namePos = pos();
4786
4787 // The '=' context after a variable name in a declaration is an opportunity
4788 // for ASI, and thus for the next token to start an ExpressionStatement:
4789 //
4790 // var foo // VariableDeclaration
4791 // /bar/g; // ExpressionStatement
4792 //
4793 // Therefore get the token here with SlashIsRegExp.
4794 bool matched;
4795 if (!tokenStream.matchToken(&matched, TokenKind::Assign,
4796 TokenStream::SlashIsRegExp)) {
4797 return errorResult();
4798 }
4799
4800 Node declaration;
4801 if (matched) {
4802 MOZ_TRY_VAR(declaration,do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
4803 initializerInNameDeclaration(binding, declKind,do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
4804 initialDeclaration, yieldHandling,do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
4805 forHeadKind, forInOrOfExpression))do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
;
4806 } else {
4807 declaration = binding;
4808
4809 if (initialDeclaration && forHeadKind) {
4810 bool isForIn, isForOf;
4811 if (!matchInOrOf(&isForIn, &isForOf)) {
4812 return errorResult();
4813 }
4814
4815 if (isForIn) {
4816 *forHeadKind = ParseNodeKind::ForIn;
4817#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
4818 if (declKind == DeclarationKind::Using ||
4819 declKind == DeclarationKind::AwaitUsing) {
4820 errorAt(namePos.begin, JSMSG_NO_IN_WITH_USING);
4821 return errorResult();
4822 }
4823#endif
4824 } else if (isForOf) {
4825 *forHeadKind = ParseNodeKind::ForOf;
4826 } else {
4827 *forHeadKind = ParseNodeKind::ForHead;
4828 }
4829 }
4830
4831 if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
4832 MOZ_TRY_VAR(*forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4833 expressionAfterForInOrOf(*forHeadKind, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4834 } else {
4835 // Normal const declarations, and const declarations in for(;;)
4836 // heads, must be initialized.
4837 if (declKind == DeclarationKind::Const) {
4838 errorAt(namePos.begin, JSMSG_BAD_CONST_DECL);
4839 return errorResult();
4840 }
4841 }
4842 }
4843
4844 // Note the declared name after knowing whether or not we are in a for-of
4845 // loop, due to special early error semantics in Annex B.3.5.
4846 if (!noteDeclaredName(name, declKind, namePos)) {
4847 return errorResult();
4848 }
4849
4850 return declaration;
4851}
4852
4853template <class ParseHandler, typename Unit>
4854typename ParseHandler::DeclarationListNodeResult
4855GeneralParser<ParseHandler, Unit>::declarationList(
4856 YieldHandling yieldHandling, ParseNodeKind kind,
4857 ParseNodeKind* forHeadKind /* = nullptr */,
4858 Node* forInOrOfExpression /* = nullptr */) {
4859 MOZ_ASSERT(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4860 kind == ParseNodeKind::ConstDecldo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4861#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENTdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4862 || kind == ParseNodeKind::UsingDecl ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4863 kind == ParseNodeKind::AwaitUsingDecldo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4864#endifdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4865 )do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
|| kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind
::AwaitUsingDecl endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind ==
ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4866
4867 DeclarationKind declKind;
4868 switch (kind) {
4869 case ParseNodeKind::VarStmt:
4870 declKind = DeclarationKind::Var;
4871 break;
4872 case ParseNodeKind::ConstDecl:
4873 declKind = DeclarationKind::Const;
4874 break;
4875 case ParseNodeKind::LetDecl:
4876 declKind = DeclarationKind::Let;
4877 break;
4878#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
4879 case ParseNodeKind::UsingDecl:
4880 declKind = DeclarationKind::Using;
4881 break;
4882 case ParseNodeKind::AwaitUsingDecl:
4883 declKind = DeclarationKind::AwaitUsing;
4884 break;
4885#endif
4886 default:
4887 MOZ_CRASH("Unknown declaration kind")do { do { } while (false); MOZ_ReportCrash("" "Unknown declaration kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4887); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown declaration kind"
")"); do { *((volatile int*)__null) = 4887; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4888 }
4889
4890 DeclarationListNodeType decl;
4891 MOZ_TRY_VAR(decl, handler_.newDeclarationList(kind, pos()))do { auto mozTryVarTempResult_ = (handler_.newDeclarationList
(kind, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decl) = mozTryVarTempResult_.unwrap(); } while (0)
;
4892
4893 bool moreDeclarations;
4894 bool initialDeclaration = true;
4895 do {
4896 MOZ_ASSERT_IF(!initialDeclaration && forHeadKind,do { if (!initialDeclaration && forHeadKind) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(*forHeadKind
== ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*forHeadKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("*forHeadKind == ParseNodeKind::ForHead", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4897); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*forHeadKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 4897; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
4897 *forHeadKind == ParseNodeKind::ForHead)do { if (!initialDeclaration && forHeadKind) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(*forHeadKind
== ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*forHeadKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("*forHeadKind == ParseNodeKind::ForHead", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4897); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*forHeadKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 4897; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4898
4899 TokenKind tt;
4900 if (!tokenStream.getToken(&tt)) {
4901 return errorResult();
4902 }
4903
4904 Node binding;
4905 if (tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly) {
4906 MOZ_TRY_VAR(binding, declarationPattern(declKind, tt, initialDeclaration,do { auto mozTryVarTempResult_ = (declarationPattern(declKind
, tt, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4907 yieldHandling, forHeadKind,do { auto mozTryVarTempResult_ = (declarationPattern(declKind
, tt, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4908 forInOrOfExpression))do { auto mozTryVarTempResult_ = (declarationPattern(declKind
, tt, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4909 } else {
4910 MOZ_TRY_VAR(binding, declarationName(declKind, tt, initialDeclaration,do { auto mozTryVarTempResult_ = (declarationName(declKind, tt
, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4911 yieldHandling, forHeadKind,do { auto mozTryVarTempResult_ = (declarationName(declKind, tt
, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4912 forInOrOfExpression))do { auto mozTryVarTempResult_ = (declarationName(declKind, tt
, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4913 }
4914
4915 handler_.addList(decl, binding);
4916
4917 // If we have a for-in/of loop, the above call matches the entirety
4918 // of the loop head (up to the closing parenthesis).
4919 if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
4920 break;
4921 }
4922
4923 initialDeclaration = false;
4924
4925 if (!tokenStream.matchToken(&moreDeclarations, TokenKind::Comma,
4926 TokenStream::SlashIsRegExp)) {
4927 return errorResult();
4928 }
4929 } while (moreDeclarations);
4930
4931 return decl;
4932}
4933
4934template <class ParseHandler, typename Unit>
4935typename ParseHandler::DeclarationListNodeResult
4936GeneralParser<ParseHandler, Unit>::lexicalDeclaration(
4937 YieldHandling yieldHandling, DeclarationKind kind) {
4938 MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Letdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4939#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENTdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4940 || kind == DeclarationKind::Using ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4941 kind == DeclarationKind::AwaitUsingdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4942#endifdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4943 )do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == DeclarationKind::Const || kind == DeclarationKind::
Let ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4944
4945 if (options().selfHostingMode) {
4946 error(JSMSG_SELFHOSTED_LEXICAL);
4947 return errorResult();
4948 }
4949
4950 /*
4951 * Parse body-level lets without a new block object. ES6 specs
4952 * that an execution environment's initial lexical environment
4953 * is the VariableEnvironment, i.e., body-level lets are in
4954 * the same environment record as vars.
4955 *
4956 * However, they cannot be parsed exactly as vars, as ES6
4957 * requires that uninitialized lets throw ReferenceError on use.
4958 *
4959 * See 8.1.1.1.6 and the note in 13.2.1.
4960 */
4961 DeclarationListNodeType decl;
4962 ParseNodeKind pnk;
4963 switch (kind) {
4964 case DeclarationKind::Const:
4965 pnk = ParseNodeKind::ConstDecl;
4966 break;
4967#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
4968 case DeclarationKind::Using:
4969 pnk = ParseNodeKind::UsingDecl;
4970 break;
4971 case DeclarationKind::AwaitUsing:
4972 pnk = ParseNodeKind::AwaitUsingDecl;
4973 break;
4974#endif
4975 case DeclarationKind::Let:
4976 pnk = ParseNodeKind::LetDecl;
4977 break;
4978 default:
4979 MOZ_CRASH("unexpected node kind")do { do { } while (false); MOZ_ReportCrash("" "unexpected node kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4979); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected node kind"
")"); do { *((volatile int*)__null) = 4979; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4980 }
4981 MOZ_TRY_VAR(decl, declarationList(yieldHandling, pnk))do { auto mozTryVarTempResult_ = (declarationList(yieldHandling
, pnk)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr(
)), 0))) { return mozTryVarTempResult_.propagateErr(); } (decl
) = mozTryVarTempResult_.unwrap(); } while (0)
;
4982 if (!matchOrInsertSemicolon()) {
4983 return errorResult();
4984 }
4985
4986 return decl;
4987}
4988
4989template <class ParseHandler, typename Unit>
4990typename ParseHandler::NameNodeResult
4991GeneralParser<ParseHandler, Unit>::moduleExportName() {
4992 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::String)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::String)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::String)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type == TokenKind::String"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4992); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::String"
")"); do { *((volatile int*)__null) = 4992; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4993 TaggedParserAtomIndex name = anyChars.currentToken().atom();
4994 if (!this->parserAtoms().isModuleExportName(name)) {
4995 error(JSMSG_UNPAIRED_SURROGATE_EXPORT);
4996 return errorResult();
4997 }
4998 return handler_.newStringLiteral(name, pos());
4999}
5000
5001template <class ParseHandler, typename Unit>
5002bool GeneralParser<ParseHandler, Unit>::withClause(ListNodeType attributesSet) {
5003 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assert) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars
.isCurrentTokenType(TokenKind::With))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::
With)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5004); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 5004; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5004 anyChars.isCurrentTokenType(TokenKind::With))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars
.isCurrentTokenType(TokenKind::With))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::
With)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5004); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 5004; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5005
5006 if (!options().importAttributes()) {
5007 error(JSMSG_IMPORT_ASSERTIONS_NOT_SUPPORTED);
5008 return false;
5009 }
5010
5011 if (!abortIfSyntaxParser()) {
5012 return false;
5013 }
5014
5015 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_AFTER_ASSERT)) {
5016 return false;
5017 }
5018
5019 // Handle the form |... assert {}|
5020 TokenKind token;
5021 if (!tokenStream.getToken(&token)) {
5022 return false;
5023 }
5024 if (token == TokenKind::RightCurly) {
5025 return true;
5026 }
5027
5028 js::HashSet<TaggedParserAtomIndex, TaggedParserAtomIndexHasher,
5029 js::SystemAllocPolicy>
5030 usedAssertionKeys;
5031
5032 for (;;) {
5033 TaggedParserAtomIndex keyName;
5034 if (TokenKindIsPossibleIdentifierName(token)) {
5035 keyName = anyChars.currentName();
5036 } else if (token == TokenKind::String) {
5037 keyName = anyChars.currentToken().atom();
5038 } else {
5039 error(JSMSG_ASSERT_KEY_EXPECTED);
5040 return false;
5041 }
5042
5043 auto p = usedAssertionKeys.lookupForAdd(keyName);
5044 if (p) {
5045 UniqueChars str = this->parserAtoms().toPrintableString(keyName);
5046 if (!str) {
5047 ReportOutOfMemory(this->fc_);
5048 return false;
5049 }
5050 error(JSMSG_DUPLICATE_ASSERT_KEY, str.get());
5051 return false;
5052 }
5053 if (!usedAssertionKeys.add(p, keyName)) {
5054 ReportOutOfMemory(this->fc_);
5055 return false;
5056 }
5057
5058 NameNodeType keyNode;
5059 MOZ_TRY_VAR_OR_RETURN(keyNode, newName(keyName), false)do { auto parserTryVarTempResult_ = (newName(keyName)); if ((
__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) { return
(false); } (keyNode) = parserTryVarTempResult_.unwrap(); } while
(0)
;
5060
5061 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_ASSERT_KEY)) {
5062 return false;
5063 }
5064 if (!mustMatchToken(TokenKind::String, JSMSG_ASSERT_STRING_LITERAL)) {
5065 return false;
5066 }
5067
5068 NameNodeType valueNode;
5069 MOZ_TRY_VAR_OR_RETURN(valueNode, stringLiteral(), false)do { auto parserTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(valueNode) = parserTryVarTempResult_.unwrap(); } while (0)
;
5070
5071 BinaryNodeType importAttributeNode;
5072 MOZ_TRY_VAR_OR_RETURN(importAttributeNode,do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
5073 handler_.newImportAttribute(keyNode, valueNode),do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
5074 false)do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5075
5076 handler_.addList(attributesSet, importAttributeNode);
5077
5078 if (!tokenStream.getToken(&token)) {
5079 return false;
5080 }
5081 if (token == TokenKind::Comma) {
5082 if (!tokenStream.getToken(&token)) {
5083 return false;
5084 }
5085 }
5086 if (token == TokenKind::RightCurly) {
5087 break;
5088 }
5089 }
5090
5091 return true;
5092}
5093
5094template <class ParseHandler, typename Unit>
5095bool GeneralParser<ParseHandler, Unit>::namedImports(
5096 ListNodeType importSpecSet) {
5097 if (!abortIfSyntaxParser()) {
5098 return false;
5099 }
5100
5101 while (true) {
5102 // Handle the forms |import {} from 'a'| and
5103 // |import { ..., } from 'a'| (where ... is non empty), by
5104 // escaping the loop early if the next token is }.
5105 TokenKind tt;
5106 if (!tokenStream.getToken(&tt)) {
5107 return false;
5108 }
5109
5110 if (tt == TokenKind::RightCurly) {
5111 break;
5112 }
5113
5114 TaggedParserAtomIndex importName;
5115 NameNodeType importNameNode = null();
5116 if (TokenKindIsPossibleIdentifierName(tt)) {
5117 importName = anyChars.currentName();
5118 MOZ_TRY_VAR_OR_RETURN(importNameNode, newName(importName), false)do { auto parserTryVarTempResult_ = (newName(importName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (importNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5119 } else if (tt == TokenKind::String) {
5120 MOZ_TRY_VAR_OR_RETURN(importNameNode, moduleExportName(), false)do { auto parserTryVarTempResult_ = (moduleExportName()); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (importNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5121 } else {
5122 error(JSMSG_NO_IMPORT_NAME);
5123 return false;
5124 }
5125
5126 bool matched;
5127 if (!tokenStream.matchToken(&matched, TokenKind::As)) {
5128 return false;
5129 }
5130
5131 if (matched) {
5132 TokenKind afterAs;
5133 if (!tokenStream.getToken(&afterAs)) {
5134 return false;
5135 }
5136
5137 if (!TokenKindIsPossibleIdentifierName(afterAs)) {
5138 error(JSMSG_NO_BINDING_NAME);
5139 return false;
5140 }
5141 } else {
5142 // String export names can't refer to local bindings.
5143 if (tt == TokenKind::String) {
5144 error(JSMSG_AS_AFTER_STRING);
5145 return false;
5146 }
5147
5148 // Keywords cannot be bound to themselves, so an import name
5149 // that is a keyword is a syntax error if it is not followed
5150 // by the keyword 'as'.
5151 // See the ImportSpecifier production in ES6 section 15.2.2.
5152 MOZ_ASSERT(importName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(importName)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(importName))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("importName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5152); AnnotateMozCrashReason("MOZ_ASSERT" "(" "importName"
")"); do { *((volatile int*)__null) = 5152; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5153 if (IsKeyword(importName)) {
5154 error(JSMSG_AS_AFTER_RESERVED_WORD, ReservedWordToCharZ(importName));
5155 return false;
5156 }
5157 }
5158
5159 TaggedParserAtomIndex bindingAtom = importedBinding();
5160 if (!bindingAtom) {
5161 return false;
5162 }
5163
5164 NameNodeType bindingName;
5165 MOZ_TRY_VAR_OR_RETURN(bindingName, newName(bindingAtom), false)do { auto parserTryVarTempResult_ = (newName(bindingAtom)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (bindingName) = parserTryVarTempResult_.
unwrap(); } while (0)
;
5166 if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
5167 return false;
5168 }
5169
5170 BinaryNodeType importSpec;
5171 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newImportSpec(importNameNode
, bindingName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5172 importSpec, handler_.newImportSpec(importNameNode, bindingName), false)do { auto parserTryVarTempResult_ = (handler_.newImportSpec(importNameNode
, bindingName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5173
5174 handler_.addList(importSpecSet, importSpec);
5175
5176 TokenKind next;
5177 if (!tokenStream.getToken(&next)) {
5178 return false;
5179 }
5180
5181 if (next == TokenKind::RightCurly) {
5182 break;
5183 }
5184
5185 if (next != TokenKind::Comma) {
5186 error(JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
5187 return false;
5188 }
5189 }
5190
5191 return true;
5192}
5193
5194template <class ParseHandler, typename Unit>
5195bool GeneralParser<ParseHandler, Unit>::namespaceImport(
5196 ListNodeType importSpecSet) {
5197 if (!abortIfSyntaxParser()) {
5198 return false;
5199 }
5200
5201 if (!mustMatchToken(TokenKind::As, JSMSG_AS_AFTER_IMPORT_STAR)) {
5202 return false;
5203 }
5204 uint32_t begin = pos().begin;
5205
5206 if (!mustMatchToken(TokenKindIsPossibleIdentifierName,
5207 JSMSG_NO_BINDING_NAME)) {
5208 return false;
5209 }
5210
5211 // Namespace imports are not indirect bindings but lexical
5212 // definitions that hold a module namespace object. They are treated
5213 // as const variables which are initialized during the
5214 // ModuleInstantiate step.
5215 TaggedParserAtomIndex bindingName = importedBinding();
5216 if (!bindingName) {
5217 return false;
5218 }
5219 NameNodeType bindingNameNode;
5220 MOZ_TRY_VAR_OR_RETURN(bindingNameNode, newName(bindingName), false)do { auto parserTryVarTempResult_ = (newName(bindingName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (bindingNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5221 if (!noteDeclaredName(bindingName, DeclarationKind::Const, pos())) {
5222 return false;
5223 }
5224
5225 // The namespace import name is currently required to live on the
5226 // environment.
5227 pc_->varScope().lookupDeclaredName(bindingName)->value()->setClosedOver();
5228
5229 UnaryNodeType importSpec;
5230 MOZ_TRY_VAR_OR_RETURN(importSpec,do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5231 handler_.newImportNamespaceSpec(begin, bindingNameNode),do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5232 false)do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5233
5234 handler_.addList(importSpecSet, importSpec);
5235
5236 return true;
5237}
5238
5239template <class ParseHandler, typename Unit>
5240typename ParseHandler::BinaryNodeResult
5241GeneralParser<ParseHandler, Unit>::importDeclaration() {
5242 if (!abortIfSyntaxParser()) {
5243 return errorResult();
5244 }
5245
5246 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Import))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Import)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Import)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5246); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 5246; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5247
5248 if (!pc_->atModuleLevel()) {
5249 error(JSMSG_IMPORT_DECL_AT_TOP_LEVEL);
5250 return errorResult();
5251 }
5252
5253 uint32_t begin = pos().begin;
5254 TokenKind tt;
5255 if (!tokenStream.getToken(&tt)) {
5256 return errorResult();
5257 }
5258
5259 ListNodeType importSpecSet;
5260 MOZ_TRY_VAR(importSpecSet,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importSpecSet) = mozTryVarTempResult_.unwrap(); } while (
0)
5261 handler_.newList(ParseNodeKind::ImportSpecList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importSpecSet) = mozTryVarTempResult_.unwrap(); } while (
0)
;
5262
5263 if (tt == TokenKind::String) {
5264 // Handle the form |import 'a'| by leaving the list empty. This is
5265 // equivalent to |import {} from 'a'|.
5266 handler_.setEndPosition(importSpecSet, pos().begin);
5267 } else {
5268 if (tt == TokenKind::LeftCurly) {
5269 if (!namedImports(importSpecSet)) {
5270 return errorResult();
5271 }
5272 } else if (tt == TokenKind::Mul) {
5273 if (!namespaceImport(importSpecSet)) {
5274 return errorResult();
5275 }
5276 } else if (TokenKindIsPossibleIdentifierName(tt)) {
5277 // Handle the form |import a from 'b'|, by adding a single import
5278 // specifier to the list, with 'default' as the import name and
5279 // 'a' as the binding name. This is equivalent to
5280 // |import { default as a } from 'b'|.
5281 NameNodeType importName;
5282 MOZ_TRY_VAR(importName,do { auto mozTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::default_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importName) = mozTryVarTempResult_.unwrap(); } while (0)
5283 newName(TaggedParserAtomIndex::WellKnown::default_()))do { auto mozTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::default_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importName) = mozTryVarTempResult_.unwrap(); } while (0)
;
5284
5285 TaggedParserAtomIndex bindingAtom = importedBinding();
5286 if (!bindingAtom) {
5287 return errorResult();
5288 }
5289
5290 NameNodeType bindingName;
5291 MOZ_TRY_VAR(bindingName, newName(bindingAtom))do { auto mozTryVarTempResult_ = (newName(bindingAtom)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (bindingName) = mozTryVarTempResult_
.unwrap(); } while (0)
;
5292
5293 if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
5294 return errorResult();
5295 }
5296
5297 BinaryNodeType importSpec;
5298 MOZ_TRY_VAR(importSpec, handler_.newImportSpec(importName, bindingName))do { auto mozTryVarTempResult_ = (handler_.newImportSpec(importName
, bindingName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importSpec) = mozTryVarTempResult_.unwrap(); } while (0)
;
5299
5300 handler_.addList(importSpecSet, importSpec);
5301
5302 if (!tokenStream.peekToken(&tt)) {
5303 return errorResult();
5304 }
5305
5306 if (tt == TokenKind::Comma) {
5307 tokenStream.consumeKnownToken(tt);
5308 if (!tokenStream.getToken(&tt)) {
5309 return errorResult();
5310 }
5311
5312 if (tt == TokenKind::LeftCurly) {
5313 if (!namedImports(importSpecSet)) {
5314 return errorResult();
5315 }
5316 } else if (tt == TokenKind::Mul) {
5317 if (!namespaceImport(importSpecSet)) {
5318 return errorResult();
5319 }
5320 } else {
5321 error(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT);
5322 return errorResult();
5323 }
5324 }
5325 } else {
5326 error(JSMSG_DECLARATION_AFTER_IMPORT);
5327 return errorResult();
5328 }
5329
5330 if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_IMPORT_CLAUSE)) {
5331 return errorResult();
5332 }
5333
5334 if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
5335 return errorResult();
5336 }
5337 }
5338
5339 NameNodeType moduleSpec;
5340 MOZ_TRY_VAR(moduleSpec, stringLiteral())do { auto mozTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleSpec) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5341
5342 // The `assert` keyword has a [no LineTerminator here] production before it in
5343 // the grammar -- `with` does not. We need to handle this distinction.
5344 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
5345 return errorResult();
5346 }
5347
5348 // `with` may have an EOL prior, so peek the next token and replace
5349 // EOL if the next token is `with`.
5350 if (tt == TokenKind::Eol) {
5351 // Doing a regular peek won't produce Eol, but the actual next token.
5352 TokenKind peekedToken;
5353 if (!tokenStream.peekToken(&peekedToken, TokenStream::SlashIsRegExp)) {
5354 return errorResult();
5355 }
5356
5357 if (peekedToken == TokenKind::With) {
5358 tt = TokenKind::With;
5359 }
5360 }
5361
5362 ListNodeType importAttributeList;
5363 MOZ_TRY_VAR(importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
5364 handler_.newList(ParseNodeKind::ImportAttributeList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
;
5365
5366 if (tt == TokenKind::With ||
5367 (tt == TokenKind::Assert && options().importAttributesAssertSyntax())) {
5368 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
5369
5370 if (!withClause(importAttributeList)) {
5371 return errorResult();
5372 }
5373 }
5374
5375 if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
5376 return errorResult();
5377 }
5378
5379 BinaryNodeType moduleRequest;
5380 MOZ_TRY_VAR(moduleRequest,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleRequest) = mozTryVarTempResult_.unwrap
(); } while (0)
5381 handler_.newModuleRequest(moduleSpec, importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleRequest) = mozTryVarTempResult_.unwrap
(); } while (0)
5382 TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleRequest) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5383
5384 BinaryNodeType node;
5385 MOZ_TRY_VAR(node, handler_.newImportDeclaration(importSpecSet, moduleRequest,do { auto mozTryVarTempResult_ = (handler_.newImportDeclaration
(importSpecSet, moduleRequest, TokenPos(begin, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (node) = mozTryVarTempResult_
.unwrap(); } while (0)
5386 TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newImportDeclaration
(importSpecSet, moduleRequest, TokenPos(begin, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (node) = mozTryVarTempResult_
.unwrap(); } while (0)
;
5387 if (!processImport(node)) {
5388 return errorResult();
5389 }
5390
5391 return node;
5392}
5393
5394template <class ParseHandler, typename Unit>
5395inline typename ParseHandler::NodeResult
5396GeneralParser<ParseHandler, Unit>::importDeclarationOrImportExpr(
5397 YieldHandling yieldHandling) {
5398 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Import))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Import)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Import)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5398); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 5398; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5399
5400 TokenKind tt;
5401 if (!tokenStream.peekToken(&tt)) {
5402 return errorResult();
5403 }
5404
5405 if (tt == TokenKind::Dot || tt == TokenKind::LeftParen) {
5406 return expressionStatement(yieldHandling);
5407 }
5408
5409 return importDeclaration();
5410}
5411
5412template <typename Unit>
5413bool Parser<FullParseHandler, Unit>::checkExportedName(
5414 TaggedParserAtomIndex exportName) {
5415 switch (pc_->sc()->asModuleContext()->builder.noteExportedName(exportName)) {
5416 case ModuleBuilder::NoteExportedNameResult::Success:
5417 return true;
5418 case ModuleBuilder::NoteExportedNameResult::OutOfMemory:
5419 return false;
5420 case ModuleBuilder::NoteExportedNameResult::AlreadyDeclared:
5421 break;
5422 }
5423
5424 UniqueChars str = this->parserAtoms().toPrintableString(exportName);
5425 if (!str) {
5426 ReportOutOfMemory(this->fc_);
5427 return false;
5428 }
5429
5430 error(JSMSG_DUPLICATE_EXPORT_NAME, str.get());
5431 return false;
5432}
5433
5434template <typename Unit>
5435inline bool Parser<SyntaxParseHandler, Unit>::checkExportedName(
5436 TaggedParserAtomIndex exportName) {
5437 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5437); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5437; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5438 return false;
5439}
5440
5441template <class ParseHandler, typename Unit>
5442inline bool GeneralParser<ParseHandler, Unit>::checkExportedName(
5443 TaggedParserAtomIndex exportName) {
5444 return asFinalParser()->checkExportedName(exportName);
5445}
5446
5447template <typename Unit>
5448bool Parser<FullParseHandler, Unit>::checkExportedNamesForArrayBinding(
5449 ListNode* array) {
5450 MOZ_ASSERT(array->isKind(ParseNodeKind::ArrayExpr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(array->isKind(ParseNodeKind::ArrayExpr))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(array->isKind(ParseNodeKind::ArrayExpr)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("array->isKind(ParseNodeKind::ArrayExpr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5450); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array->isKind(ParseNodeKind::ArrayExpr)"
")"); do { *((volatile int*)__null) = 5450; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5451
5452 for (ParseNode* node : array->contents()) {
5453 if (node->isKind(ParseNodeKind::Elision)) {
5454 continue;
5455 }
5456
5457 ParseNode* binding;
5458 if (node->isKind(ParseNodeKind::Spread)) {
5459 binding = node->as<UnaryNode>().kid();
5460 } else if (node->isKind(ParseNodeKind::AssignExpr)) {
5461 binding = node->as<AssignmentNode>().left();
5462 } else {
5463 binding = node;
5464 }
5465
5466 if (!checkExportedNamesForDeclaration(binding)) {
5467 return false;
5468 }
5469 }
5470
5471 return true;
5472}
5473
5474template <typename Unit>
5475inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForArrayBinding(
5476 ListNodeType array) {
5477 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5477); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5477; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5478 return false;
5479}
5480
5481template <class ParseHandler, typename Unit>
5482inline bool
5483GeneralParser<ParseHandler, Unit>::checkExportedNamesForArrayBinding(
5484 ListNodeType array) {
5485 return asFinalParser()->checkExportedNamesForArrayBinding(array);
5486}
5487
5488template <typename Unit>
5489bool Parser<FullParseHandler, Unit>::checkExportedNamesForObjectBinding(
5490 ListNode* obj) {
5491 MOZ_ASSERT(obj->isKind(ParseNodeKind::ObjectExpr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(obj->isKind(ParseNodeKind::ObjectExpr))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(obj->isKind(ParseNodeKind::ObjectExpr)))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("obj->isKind(ParseNodeKind::ObjectExpr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->isKind(ParseNodeKind::ObjectExpr)"
")"); do { *((volatile int*)__null) = 5491; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5492
5493 for (ParseNode* node : obj->contents()) {
5494 MOZ_ASSERT(node->isKind(ParseNodeKind::MutateProto) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5497; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5495 node->isKind(ParseNodeKind::PropertyDefinition) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5497; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5496 node->isKind(ParseNodeKind::Shorthand) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5497; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5497 node->isKind(ParseNodeKind::Spread))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5497; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5498
5499 ParseNode* target;
5500 if (node->isKind(ParseNodeKind::Spread)) {
5501 target = node->as<UnaryNode>().kid();
5502 } else {
5503 if (node->isKind(ParseNodeKind::MutateProto)) {
5504 target = node->as<UnaryNode>().kid();
5505 } else {
5506 target = node->as<BinaryNode>().right();
5507 }
5508
5509 if (target->isKind(ParseNodeKind::AssignExpr)) {
5510 target = target->as<AssignmentNode>().left();
5511 }
5512 }
5513
5514 if (!checkExportedNamesForDeclaration(target)) {
5515 return false;
5516 }
5517 }
5518
5519 return true;
5520}
5521
5522template <typename Unit>
5523inline bool Parser<SyntaxParseHandler,
5524 Unit>::checkExportedNamesForObjectBinding(ListNodeType obj) {
5525 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5525); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5525; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5526 return false;
5527}
5528
5529template <class ParseHandler, typename Unit>
5530inline bool
5531GeneralParser<ParseHandler, Unit>::checkExportedNamesForObjectBinding(
5532 ListNodeType obj) {
5533 return asFinalParser()->checkExportedNamesForObjectBinding(obj);
5534}
5535
5536template <typename Unit>
5537bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclaration(
5538 ParseNode* node) {
5539 if (node->isKind(ParseNodeKind::Name)) {
5540 if (!checkExportedName(node->as<NameNode>().atom())) {
5541 return false;
5542 }
5543 } else if (node->isKind(ParseNodeKind::ArrayExpr)) {
5544 if (!checkExportedNamesForArrayBinding(&node->as<ListNode>())) {
5545 return false;
5546 }
5547 } else {
5548 MOZ_ASSERT(node->isKind(ParseNodeKind::ObjectExpr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::ObjectExpr))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(node->isKind(ParseNodeKind::ObjectExpr)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("node->isKind(ParseNodeKind::ObjectExpr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5548); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::ObjectExpr)"
")"); do { *((volatile int*)__null) = 5548; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5549 if (!checkExportedNamesForObjectBinding(&node->as<ListNode>())) {
5550 return false;
5551 }
5552 }
5553
5554 return true;
5555}
5556
5557template <typename Unit>
5558inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForDeclaration(
5559 Node node) {
5560 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5560); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5560; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5561 return false;
5562}
5563
5564template <class ParseHandler, typename Unit>
5565inline bool GeneralParser<ParseHandler, Unit>::checkExportedNamesForDeclaration(
5566 Node node) {
5567 return asFinalParser()->checkExportedNamesForDeclaration(node);
5568}
5569
5570template <typename Unit>
5571bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclarationList(
5572 DeclarationListNodeType node) {
5573 for (ParseNode* binding : node->contents()) {
5574 if (binding->isKind(ParseNodeKind::AssignExpr)) {
5575 binding = binding->as<AssignmentNode>().left();
5576 } else {
5577 MOZ_ASSERT(binding->isKind(ParseNodeKind::Name))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(binding->isKind(ParseNodeKind::Name))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(binding->isKind(ParseNodeKind::Name)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("binding->isKind(ParseNodeKind::Name)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5577); AnnotateMozCrashReason("MOZ_ASSERT" "(" "binding->isKind(ParseNodeKind::Name)"
")"); do { *((volatile int*)__null) = 5577; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5578 }
5579
5580 if (!checkExportedNamesForDeclaration(binding)) {
5581 return false;
5582 }
5583 }
5584
5585 return true;
5586}
5587
5588template <typename Unit>
5589inline bool
5590Parser<SyntaxParseHandler, Unit>::checkExportedNamesForDeclarationList(
5591 DeclarationListNodeType node) {
5592 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5592); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5592; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5593 return false;
5594}
5595
5596template <class ParseHandler, typename Unit>
5597inline bool
5598GeneralParser<ParseHandler, Unit>::checkExportedNamesForDeclarationList(
5599 DeclarationListNodeType node) {
5600 return asFinalParser()->checkExportedNamesForDeclarationList(node);
5601}
5602
5603template <typename Unit>
5604inline bool Parser<FullParseHandler, Unit>::checkExportedNameForClause(
5605 NameNode* nameNode) {
5606 return checkExportedName(nameNode->atom());
5607}
5608
5609template <typename Unit>
5610inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForClause(
5611 NameNodeType nameNode) {
5612 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5612); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5612; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5613 return false;
5614}
5615
5616template <class ParseHandler, typename Unit>
5617inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForClause(
5618 NameNodeType nameNode) {
5619 return asFinalParser()->checkExportedNameForClause(nameNode);
5620}
5621
5622template <typename Unit>
5623bool Parser<FullParseHandler, Unit>::checkExportedNameForFunction(
5624 FunctionNode* funNode) {
5625 return checkExportedName(funNode->funbox()->explicitName());
5626}
5627
5628template <typename Unit>
5629inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForFunction(
5630 FunctionNodeType funNode) {
5631 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5631); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5631; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5632 return false;
5633}
5634
5635template <class ParseHandler, typename Unit>
5636inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForFunction(
5637 FunctionNodeType funNode) {
5638 return asFinalParser()->checkExportedNameForFunction(funNode);
5639}
5640
5641template <typename Unit>
5642bool Parser<FullParseHandler, Unit>::checkExportedNameForClass(
5643 ClassNode* classNode) {
5644 MOZ_ASSERT(classNode->names())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(classNode->names())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(classNode->names()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("classNode->names()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5644); AnnotateMozCrashReason("MOZ_ASSERT" "(" "classNode->names()"
")"); do { *((volatile int*)__null) = 5644; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5645 return checkExportedName(classNode->names()->innerBinding()->atom());
5646}
5647
5648template <typename Unit>
5649inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForClass(
5650 ClassNodeType classNode) {
5651 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5651); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5651; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5652 return false;
5653}
5654
5655template <class ParseHandler, typename Unit>
5656inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForClass(
5657 ClassNodeType classNode) {
5658 return asFinalParser()->checkExportedNameForClass(classNode);
5659}
5660
5661template <>
5662inline bool PerHandlerParser<FullParseHandler>::processExport(ParseNode* node) {
5663 return pc_->sc()->asModuleContext()->builder.processExport(node);
5664}
5665
5666template <>
5667inline bool PerHandlerParser<SyntaxParseHandler>::processExport(Node node) {
5668 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5668); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5668; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5669 return false;
5670}
5671
5672template <>
5673inline bool PerHandlerParser<FullParseHandler>::processExportFrom(
5674 BinaryNodeType node) {
5675 return pc_->sc()->asModuleContext()->builder.processExportFrom(node);
5676}
5677
5678template <>
5679inline bool PerHandlerParser<SyntaxParseHandler>::processExportFrom(
5680 BinaryNodeType node) {
5681 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5681); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5681; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5682 return false;
5683}
5684
5685template <>
5686inline bool PerHandlerParser<FullParseHandler>::processImport(
5687 BinaryNodeType node) {
5688 return pc_->sc()->asModuleContext()->builder.processImport(node);
5689}
5690
5691template <>
5692inline bool PerHandlerParser<SyntaxParseHandler>::processImport(
5693 BinaryNodeType node) {
5694 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5694); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5694; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5695 return false;
5696}
5697
5698template <class ParseHandler, typename Unit>
5699typename ParseHandler::BinaryNodeResult
5700GeneralParser<ParseHandler, Unit>::exportFrom(uint32_t begin, Node specList) {
5701 if (!abortIfSyntaxParser()) {
5702 return errorResult();
5703 }
5704
5705 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::From))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::From))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::From)))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::From)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5705); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::From)"
")"); do { *((volatile int*)__null) = 5705; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5706
5707 if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
5708 return errorResult();
5709 }
5710
5711 NameNodeType moduleSpec;
5712 MOZ_TRY_VAR(moduleSpec, stringLiteral())do { auto mozTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleSpec) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5713
5714 TokenKind tt;
5715
5716 // The `assert` keyword has a [no LineTerminator here] production before it in
5717 // the grammar -- `with` does not. We need to handle this distinction.
5718 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
5719 return errorResult();
5720 }
5721
5722 // `with` may have an EOL prior, so peek the next token and replace
5723 // EOL if the next token is `with`.
5724 if (tt == TokenKind::Eol) {
5725 // Doing a regular peek won't produce Eol, but the actual next token.
5726 TokenKind peekedToken;
5727 if (!tokenStream.peekToken(&peekedToken, TokenStream::SlashIsRegExp)) {
5728 return errorResult();
5729 }
5730
5731 if (peekedToken == TokenKind::With) {
5732 tt = TokenKind::With;
5733 }
5734 }
5735
5736 uint32_t moduleSpecPos = pos().begin;
5737
5738 ListNodeType importAttributeList;
5739 MOZ_TRY_VAR(importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
5740 handler_.newList(ParseNodeKind::ImportAttributeList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
;
5741 if (tt == TokenKind::With ||
5742 (tt == TokenKind::Assert && options().importAttributesAssertSyntax())) {
5743 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
5744
5745 if (!withClause(importAttributeList)) {
5746 return errorResult();
5747 }
5748 }
5749
5750 if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
5751 return errorResult();
5752 }
5753
5754 BinaryNodeType moduleRequest;
5755 MOZ_TRY_VAR(moduleRequest,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(moduleSpecPos, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (moduleRequest) = mozTryVarTempResult_
.unwrap(); } while (0)
5756 handler_.newModuleRequest(moduleSpec, importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(moduleSpecPos, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (moduleRequest) = mozTryVarTempResult_
.unwrap(); } while (0)
5757 TokenPos(moduleSpecPos, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(moduleSpecPos, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (moduleRequest) = mozTryVarTempResult_
.unwrap(); } while (0)
;
5758
5759 BinaryNodeType node;
5760 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (handler_.newExportFromDeclaration
(begin, specList, moduleRequest)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (node) = mozTryVarTempResult_.unwrap(); } while (0)
5761 node, handler_.newExportFromDeclaration(begin, specList, moduleRequest))do { auto mozTryVarTempResult_ = (handler_.newExportFromDeclaration
(begin, specList, moduleRequest)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (node) = mozTryVarTempResult_.unwrap(); } while (0)
;
5762
5763 if (!processExportFrom(node)) {
5764 return errorResult();
5765 }
5766
5767 return node;
5768}
5769
5770template <class ParseHandler, typename Unit>
5771typename ParseHandler::BinaryNodeResult
5772GeneralParser<ParseHandler, Unit>::exportBatch(uint32_t begin) {
5773 if (!abortIfSyntaxParser()) {
5774 return errorResult();
5775 }
5776
5777 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Mul))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Mul))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Mul)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Mul)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5777); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Mul)"
")"); do { *((volatile int*)__null) = 5777; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5778 uint32_t beginExportSpec = pos().begin;
5779
5780 ListNodeType kid;
5781 MOZ_TRY_VAR(kid, handler_.newList(ParseNodeKind::ExportSpecList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ExportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
5782
5783 bool foundAs;
5784 if (!tokenStream.matchToken(&foundAs, TokenKind::As)) {
5785 return errorResult();
5786 }
5787
5788 if (foundAs) {
5789 TokenKind tt;
5790 if (!tokenStream.getToken(&tt)) {
5791 return errorResult();
5792 }
5793
5794 NameNodeType exportName = null();
5795 if (TokenKindIsPossibleIdentifierName(tt)) {
5796 MOZ_TRY_VAR(exportName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (exportName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5797 } else if (tt == TokenKind::String) {
5798 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5799 } else {
5800 error(JSMSG_NO_EXPORT_NAME);
5801 return errorResult();
5802 }
5803
5804 if (!checkExportedNameForClause(exportName)) {
5805 return errorResult();
5806 }
5807
5808 UnaryNodeType exportSpec;
5809 MOZ_TRY_VAR(exportSpec,do { auto mozTryVarTempResult_ = (handler_.newExportNamespaceSpec
(beginExportSpec, exportName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exportSpec) = mozTryVarTempResult_.unwrap(); } while (0)
5810 handler_.newExportNamespaceSpec(beginExportSpec, exportName))do { auto mozTryVarTempResult_ = (handler_.newExportNamespaceSpec
(beginExportSpec, exportName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exportSpec) = mozTryVarTempResult_.unwrap(); } while (0)
;
5811
5812 handler_.addList(kid, exportSpec);
5813 } else {
5814 // Handle the form |export *| by adding a special export batch
5815 // specifier to the list.
5816 NullaryNodeType exportSpec;
5817 MOZ_TRY_VAR(exportSpec, handler_.newExportBatchSpec(pos()))do { auto mozTryVarTempResult_ = (handler_.newExportBatchSpec
(pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (exportSpec
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5818
5819 handler_.addList(kid, exportSpec);
5820 }
5821
5822 if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_EXPORT_STAR)) {
5823 return errorResult();
5824 }
5825
5826 return exportFrom(begin, kid);
5827}
5828
5829template <typename Unit>
5830bool Parser<FullParseHandler, Unit>::checkLocalExportNames(ListNode* node) {
5831 // ES 2017 draft 15.2.3.1.
5832 for (ParseNode* next : node->contents()) {
5833 ParseNode* name = next->as<BinaryNode>().left();
5834
5835 if (name->isKind(ParseNodeKind::StringExpr)) {
5836 errorAt(name->pn_pos.begin, JSMSG_BAD_LOCAL_STRING_EXPORT);
5837 return false;
5838 }
5839
5840 MOZ_ASSERT(name->isKind(ParseNodeKind::Name))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name->isKind(ParseNodeKind::Name))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(name->isKind(ParseNodeKind
::Name)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("name->isKind(ParseNodeKind::Name)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5840); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name->isKind(ParseNodeKind::Name)"
")"); do { *((volatile int*)__null) = 5840; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5841
5842 TaggedParserAtomIndex ident = name->as<NameNode>().atom();
5843 if (!checkLocalExportName(ident, name->pn_pos.begin)) {
5844 return false;
5845 }
5846 }
5847
5848 return true;
5849}
5850
5851template <typename Unit>
5852bool Parser<SyntaxParseHandler, Unit>::checkLocalExportNames(
5853 ListNodeType node) {
5854 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5854); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5854; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5855 return false;
5856}
5857
5858template <class ParseHandler, typename Unit>
5859inline bool GeneralParser<ParseHandler, Unit>::checkLocalExportNames(
5860 ListNodeType node) {
5861 return asFinalParser()->checkLocalExportNames(node);
5862}
5863
5864template <class ParseHandler, typename Unit>
5865typename ParseHandler::NodeResult
5866GeneralParser<ParseHandler, Unit>::exportClause(uint32_t begin) {
5867 if (!abortIfSyntaxParser()) {
5868 return errorResult();
5869 }
5870
5871 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5871); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 5871; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5872
5873 ListNodeType kid;
5874 MOZ_TRY_VAR(kid, handler_.newList(ParseNodeKind::ExportSpecList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ExportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
5875
5876 TokenKind tt;
5877 while (true) {
5878 // Handle the forms |export {}| and |export { ..., }| (where ... is non
5879 // empty), by escaping the loop early if the next token is }.
5880 if (!tokenStream.getToken(&tt)) {
5881 return errorResult();
5882 }
5883
5884 if (tt == TokenKind::RightCurly) {
5885 break;
5886 }
5887
5888 NameNodeType bindingName = null();
5889 if (TokenKindIsPossibleIdentifierName(tt)) {
5890 MOZ_TRY_VAR(bindingName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (bindingName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5891 } else if (tt == TokenKind::String) {
5892 MOZ_TRY_VAR(bindingName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (bindingName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5893 } else {
5894 error(JSMSG_NO_BINDING_NAME);
5895 return errorResult();
5896 }
5897
5898 bool foundAs;
5899 if (!tokenStream.matchToken(&foundAs, TokenKind::As)) {
5900 return errorResult();
5901 }
5902
5903 NameNodeType exportName = null();
5904 if (foundAs) {
5905 TokenKind tt;
5906 if (!tokenStream.getToken(&tt)) {
5907 return errorResult();
5908 }
5909
5910 if (TokenKindIsPossibleIdentifierName(tt)) {
5911 MOZ_TRY_VAR(exportName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (exportName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5912 } else if (tt == TokenKind::String) {
5913 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5914 } else {
5915 error(JSMSG_NO_EXPORT_NAME);
5916 return errorResult();
5917 }
5918 } else {
5919 if (tt != TokenKind::String) {
5920 MOZ_TRY_VAR(exportName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (exportName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5921 } else {
5922 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5923 }
5924 }
5925
5926 if (!checkExportedNameForClause(exportName)) {
5927 return errorResult();
5928 }
5929
5930 BinaryNodeType exportSpec;
5931 MOZ_TRY_VAR(exportSpec, handler_.newExportSpec(bindingName, exportName))do { auto mozTryVarTempResult_ = (handler_.newExportSpec(bindingName
, exportName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exportSpec) = mozTryVarTempResult_.unwrap(); } while (0)
;
5932
5933 handler_.addList(kid, exportSpec);
5934
5935 TokenKind next;
5936 if (!tokenStream.getToken(&next)) {
5937 return errorResult();
5938 }
5939
5940 if (next == TokenKind::RightCurly) {
5941 break;
5942 }
5943
5944 if (next != TokenKind::Comma) {
5945 error(JSMSG_RC_AFTER_EXPORT_SPEC_LIST);
5946 return errorResult();
5947 }
5948 }
5949
5950 // Careful! If |from| follows, even on a new line, it must start a
5951 // FromClause:
5952 //
5953 // export { x }
5954 // from "foo"; // a single ExportDeclaration
5955 //
5956 // But if it doesn't, we might have an ASI opportunity in SlashIsRegExp
5957 // context:
5958 //
5959 // export { x } // ExportDeclaration, terminated by ASI
5960 // fro\u006D // ExpressionStatement, the name "from"
5961 //
5962 // In that case let matchOrInsertSemicolon sort out ASI or any necessary
5963 // error.
5964 bool matched;
5965 if (!tokenStream.matchToken(&matched, TokenKind::From,
5966 TokenStream::SlashIsRegExp)) {
5967 return errorResult();
5968 }
5969
5970 if (matched) {
5971 return exportFrom(begin, kid);
5972 }
5973
5974 if (!matchOrInsertSemicolon()) {
5975 return errorResult();
5976 }
5977
5978 if (!checkLocalExportNames(kid)) {
5979 return errorResult();
5980 }
5981
5982 UnaryNodeType node;
5983 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
5984 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
5985
5986 if (!processExport(node)) {
5987 return errorResult();
5988 }
5989
5990 return node;
5991}
5992
5993template <class ParseHandler, typename Unit>
5994typename ParseHandler::UnaryNodeResult
5995GeneralParser<ParseHandler, Unit>::exportVariableStatement(uint32_t begin) {
5996 if (!abortIfSyntaxParser()) {
5997 return errorResult();
5998 }
5999
6000 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Var))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Var))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Var)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Var)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6000); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Var)"
")"); do { *((volatile int*)__null) = 6000; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6001
6002 DeclarationListNodeType kid;
6003 MOZ_TRY_VAR(kid, declarationList(YieldIsName, ParseNodeKind::VarStmt))do { auto mozTryVarTempResult_ = (declarationList(YieldIsName
, ParseNodeKind::VarStmt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
6004 if (!matchOrInsertSemicolon()) {
6005 return errorResult();
6006 }
6007 if (!checkExportedNamesForDeclarationList(kid)) {
6008 return errorResult();
6009 }
6010
6011 UnaryNodeType node;
6012 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6013 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6014
6015 if (!processExport(node)) {
6016 return errorResult();
6017 }
6018
6019 return node;
6020}
6021
6022template <class ParseHandler, typename Unit>
6023typename ParseHandler::UnaryNodeResult
6024GeneralParser<ParseHandler, Unit>::exportFunctionDeclaration(
6025 uint32_t begin, uint32_t toStringStart,
6026 FunctionAsyncKind asyncKind /* = SyncFunction */) {
6027 if (!abortIfSyntaxParser()) {
6028 return errorResult();
6029 }
6030
6031 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6031); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 6031; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6032
6033 Node kid;
6034 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, NameRequired, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
6035 kid, functionStmt(toStringStart, YieldIsName, NameRequired, asyncKind))do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, NameRequired, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6036
6037 if (!checkExportedNameForFunction(handler_.asFunctionNode(kid))) {
6038 return errorResult();
6039 }
6040
6041 UnaryNodeType node;
6042 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6043 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6044
6045 if (!processExport(node)) {
6046 return errorResult();
6047 }
6048
6049 return node;
6050}
6051
6052template <class ParseHandler, typename Unit>
6053typename ParseHandler::UnaryNodeResult
6054GeneralParser<ParseHandler, Unit>::exportClassDeclaration(uint32_t begin) {
6055 if (!abortIfSyntaxParser()) {
6056 return errorResult();
6057 }
6058
6059 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Class))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Class)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6059); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 6059; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6060
6061 ClassNodeType kid;
6062 MOZ_TRY_VAR(kid, classDefinition(YieldIsName, ClassStatement, NameRequired))do { auto mozTryVarTempResult_ = (classDefinition(YieldIsName
, ClassStatement, NameRequired)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
6063
6064 if (!checkExportedNameForClass(kid)) {
6065 return errorResult();
6066 }
6067
6068 UnaryNodeType node;
6069 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6070 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6071
6072 if (!processExport(node)) {
6073 return errorResult();
6074 }
6075
6076 return node;
6077}
6078
6079template <class ParseHandler, typename Unit>
6080typename ParseHandler::UnaryNodeResult
6081GeneralParser<ParseHandler, Unit>::exportLexicalDeclaration(
6082 uint32_t begin, DeclarationKind kind) {
6083 if (!abortIfSyntaxParser()) {
6084 return errorResult();
6085 }
6086
6087 MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Let)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == DeclarationKind::Const || kind == DeclarationKind
::Let))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == DeclarationKind::Const || kind == DeclarationKind::Let"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6087); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Let"
")"); do { *((volatile int*)__null) = 6087; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6088 MOZ_ASSERT_IF(kind == DeclarationKind::Const,do { if (kind == DeclarationKind::Const) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(anyChars
.isCurrentTokenType(TokenKind::Const))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Const)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Const)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6089); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Const)"
")"); do { *((volatile int*)__null) = 6089; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6089 anyChars.isCurrentTokenType(TokenKind::Const))do { if (kind == DeclarationKind::Const) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(anyChars
.isCurrentTokenType(TokenKind::Const))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Const)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Const)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6089); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Const)"
")"); do { *((volatile int*)__null) = 6089; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6090 MOZ_ASSERT_IF(kind == DeclarationKind::Let,do { if (kind == DeclarationKind::Let) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Let))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Let)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Let)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6091); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 6091; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6091 anyChars.isCurrentTokenType(TokenKind::Let))do { if (kind == DeclarationKind::Let) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Let))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Let)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Let)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6091); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 6091; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6092
6093 DeclarationListNodeType kid;
6094 MOZ_TRY_VAR(kid, lexicalDeclaration(YieldIsName, kind))do { auto mozTryVarTempResult_ = (lexicalDeclaration(YieldIsName
, kind)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (kid
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6095 if (!checkExportedNamesForDeclarationList(kid)) {
6096 return errorResult();
6097 }
6098
6099 UnaryNodeType node;
6100 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6101 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6102
6103 if (!processExport(node)) {
6104 return errorResult();
6105 }
6106
6107 return node;
6108}
6109
6110template <class ParseHandler, typename Unit>
6111typename ParseHandler::BinaryNodeResult
6112GeneralParser<ParseHandler, Unit>::exportDefaultFunctionDeclaration(
6113 uint32_t begin, uint32_t toStringStart,
6114 FunctionAsyncKind asyncKind /* = SyncFunction */) {
6115 if (!abortIfSyntaxParser()) {
6116 return errorResult();
6117 }
6118
6119 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6119); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 6119; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6120
6121 Node kid;
6122 MOZ_TRY_VAR(kid, functionStmt(toStringStart, YieldIsName, AllowDefaultName,do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, AllowDefaultName, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
6123 asyncKind))do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, AllowDefaultName, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6124
6125 BinaryNodeType node;
6126 MOZ_TRY_VAR(node, handler_.newExportDefaultDeclaration(do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6127 kid, null(), TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6128
6129 if (!processExport(node)) {
6130 return errorResult();
6131 }
6132
6133 return node;
6134}
6135
6136template <class ParseHandler, typename Unit>
6137typename ParseHandler::BinaryNodeResult
6138GeneralParser<ParseHandler, Unit>::exportDefaultClassDeclaration(
6139 uint32_t begin) {
6140 if (!abortIfSyntaxParser()) {
6141 return errorResult();
6142 }
6143
6144 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Class))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Class)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6144); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 6144; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6145
6146 ClassNodeType kid;
6147 MOZ_TRY_VAR(kid,do { auto mozTryVarTempResult_ = (classDefinition(YieldIsName
, ClassStatement, AllowDefaultName)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
6148 classDefinition(YieldIsName, ClassStatement, AllowDefaultName))do { auto mozTryVarTempResult_ = (classDefinition(YieldIsName
, ClassStatement, AllowDefaultName)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6149
6150 BinaryNodeType node;
6151 MOZ_TRY_VAR(node, handler_.newExportDefaultDeclaration(do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6152 kid, null(), TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6153
6154 if (!processExport(node)) {
6155 return errorResult();
6156 }
6157
6158 return node;
6159}
6160
6161template <class ParseHandler, typename Unit>
6162typename ParseHandler::BinaryNodeResult
6163GeneralParser<ParseHandler, Unit>::exportDefaultAssignExpr(uint32_t begin) {
6164 if (!abortIfSyntaxParser()) {
6165 return errorResult();
6166 }
6167
6168 TaggedParserAtomIndex name = TaggedParserAtomIndex::WellKnown::default_();
6169 NameNodeType nameNode;
6170 MOZ_TRY_VAR(nameNode, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nameNode) = mozTryVarTempResult_.unwrap()
; } while (0)
;
6171 if (!noteDeclaredName(name, DeclarationKind::Const, pos())) {
6172 return errorResult();
6173 }
6174
6175 Node kid;
6176 MOZ_TRY_VAR(kid, assignExpr(InAllowed, YieldIsName, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, YieldIsName
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
6177
6178 if (!matchOrInsertSemicolon()) {
6179 return errorResult();
6180 }
6181
6182 BinaryNodeType node;
6183 MOZ_TRY_VAR(node, handler_.newExportDefaultDeclaration(do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, nameNode, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6184 kid, nameNode, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, nameNode, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6185
6186 if (!processExport(node)) {
6187 return errorResult();
6188 }
6189
6190 return node;
6191}
6192
6193template <class ParseHandler, typename Unit>
6194typename ParseHandler::BinaryNodeResult
6195GeneralParser<ParseHandler, Unit>::exportDefault(uint32_t begin) {
6196 if (!abortIfSyntaxParser()) {
6197 return errorResult();
6198 }
6199
6200 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Default))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Default))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Default)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Default)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6200); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Default)"
")"); do { *((volatile int*)__null) = 6200; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6201
6202 TokenKind tt;
6203 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6204 return errorResult();
6205 }
6206
6207 if (!checkExportedName(TaggedParserAtomIndex::WellKnown::default_())) {
6208 return errorResult();
6209 }
6210
6211 switch (tt) {
6212 case TokenKind::Function:
6213 return exportDefaultFunctionDeclaration(begin, pos().begin);
6214
6215 case TokenKind::Async: {
6216 TokenKind nextSameLine = TokenKind::Eof;
6217 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
6218 return errorResult();
6219 }
6220
6221 if (nextSameLine == TokenKind::Function) {
6222 uint32_t toStringStart = pos().begin;
6223 tokenStream.consumeKnownToken(TokenKind::Function);
6224 return exportDefaultFunctionDeclaration(
6225 begin, toStringStart, FunctionAsyncKind::AsyncFunction);
6226 }
6227
6228 anyChars.ungetToken();
6229 return exportDefaultAssignExpr(begin);
6230 }
6231
6232 case TokenKind::Class:
6233 return exportDefaultClassDeclaration(begin);
6234
6235 default:
6236 anyChars.ungetToken();
6237 return exportDefaultAssignExpr(begin);
6238 }
6239}
6240
6241template <class ParseHandler, typename Unit>
6242typename ParseHandler::NodeResult
6243GeneralParser<ParseHandler, Unit>::exportDeclaration() {
6244 if (!abortIfSyntaxParser()) {
6245 return errorResult();
6246 }
6247
6248 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Export))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Export))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Export)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Export)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6248); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Export)"
")"); do { *((volatile int*)__null) = 6248; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6249
6250 if (!pc_->atModuleLevel()) {
6251 error(JSMSG_EXPORT_DECL_AT_TOP_LEVEL);
6252 return errorResult();
6253 }
6254
6255 uint32_t begin = pos().begin;
6256
6257 TokenKind tt;
6258 if (!tokenStream.getToken(&tt)) {
6259 return errorResult();
6260 }
6261 switch (tt) {
6262 case TokenKind::Mul:
6263 return exportBatch(begin);
6264
6265 case TokenKind::LeftCurly:
6266 return exportClause(begin);
6267
6268 case TokenKind::Var:
6269 return exportVariableStatement(begin);
6270
6271 case TokenKind::Function:
6272 return exportFunctionDeclaration(begin, pos().begin);
6273
6274 case TokenKind::Async: {
6275 TokenKind nextSameLine = TokenKind::Eof;
6276 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
6277 return errorResult();
6278 }
6279
6280 if (nextSameLine == TokenKind::Function) {
6281 uint32_t toStringStart = pos().begin;
6282 tokenStream.consumeKnownToken(TokenKind::Function);
6283 return exportFunctionDeclaration(begin, toStringStart,
6284 FunctionAsyncKind::AsyncFunction);
6285 }
6286
6287 error(JSMSG_DECLARATION_AFTER_EXPORT);
6288 return errorResult();
6289 }
6290
6291 case TokenKind::Class:
6292 return exportClassDeclaration(begin);
6293
6294 case TokenKind::Const:
6295 return exportLexicalDeclaration(begin, DeclarationKind::Const);
6296
6297 case TokenKind::Let:
6298 return exportLexicalDeclaration(begin, DeclarationKind::Let);
6299
6300 case TokenKind::Default:
6301 return exportDefault(begin);
6302
6303 default:
6304 error(JSMSG_DECLARATION_AFTER_EXPORT);
6305 return errorResult();
6306 }
6307}
6308
6309template <class ParseHandler, typename Unit>
6310typename ParseHandler::UnaryNodeResult
6311GeneralParser<ParseHandler, Unit>::expressionStatement(
6312 YieldHandling yieldHandling, InvokedPrediction invoked) {
6313 anyChars.ungetToken();
6314 Node pnexpr;
6315 MOZ_TRY_VAR(pnexpr, expr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited, nullptr, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pnexpr) = mozTryVarTempResult_.unwrap(); }
while (0)
6316 /* possibleError = */ nullptr, invoked))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited, nullptr, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pnexpr) = mozTryVarTempResult_.unwrap(); }
while (0)
;
6317 if (!matchOrInsertSemicolon()) {
6318 return errorResult();
6319 }
6320 return handler_.newExprStatement(pnexpr, pos().end);
6321}
6322
6323template <class ParseHandler, typename Unit>
6324typename ParseHandler::NodeResult
6325GeneralParser<ParseHandler, Unit>::consequentOrAlternative(
6326 YieldHandling yieldHandling) {
6327 TokenKind next;
6328 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
6329 return errorResult();
6330 }
6331
6332 // Annex B.3.4 says that unbraced FunctionDeclarations under if/else in
6333 // non-strict code act as if they were braced: |if (x) function f() {}|
6334 // parses as |if (x) { function f() {} }|.
6335 //
6336 // Careful! FunctionDeclaration doesn't include generators or async
6337 // functions.
6338 if (next == TokenKind::Function) {
6339 tokenStream.consumeKnownToken(next, TokenStream::SlashIsRegExp);
6340
6341 // Parser::statement would handle this, but as this function handles
6342 // every other error case, it seems best to handle this.
6343 if (pc_->sc()->strict()) {
6344 error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
6345 return errorResult();
6346 }
6347
6348 TokenKind maybeStar;
6349 if (!tokenStream.peekToken(&maybeStar)) {
6350 return errorResult();
6351 }
6352
6353 if (maybeStar == TokenKind::Mul) {
6354 error(JSMSG_FORBIDDEN_AS_STATEMENT, "generator declarations");
6355 return errorResult();
6356 }
6357
6358 ParseContext::Statement stmt(pc_, StatementKind::Block);
6359 ParseContext::Scope scope(this);
6360 if (!scope.init(pc_)) {
6361 return errorResult();
6362 }
6363
6364 TokenPos funcPos = pos();
6365 Node fun;
6366 MOZ_TRY_VAR(fun, functionStmt(pos().begin, yieldHandling, NameRequired))do { auto mozTryVarTempResult_ = (functionStmt(pos().begin, yieldHandling
, NameRequired)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fun) = mozTryVarTempResult_.unwrap(); } while (0)
;
6367
6368 ListNodeType block;
6369 MOZ_TRY_VAR(block, handler_.newStatementList(funcPos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(funcPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (block) =
mozTryVarTempResult_.unwrap(); } while (0)
;
6370
6371 handler_.addStatementToList(block, fun);
6372 return finishLexicalScope(scope, block);
6373 }
6374
6375 return statement(yieldHandling);
6376}
6377
6378template <class ParseHandler, typename Unit>
6379typename ParseHandler::TernaryNodeResult
6380GeneralParser<ParseHandler, Unit>::ifStatement(YieldHandling yieldHandling) {
6381 Vector<Node, 4> condList(fc_), thenList(fc_);
6382 Vector<uint32_t, 4> posList(fc_);
6383 Node elseBranch;
6384
6385 ParseContext::Statement stmt(pc_, StatementKind::If);
6386
6387 while (true) {
6388 uint32_t begin = pos().begin;
6389
6390 /* An IF node has three kids: condition, then, and optional else. */
6391 Node cond;
6392 MOZ_TRY_VAR(cond, condition(InAllowed, yieldHandling))do { auto mozTryVarTempResult_ = (condition(InAllowed, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (cond) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6393
6394 TokenKind tt;
6395 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6396 return errorResult();
6397 }
6398
6399 Node thenBranch;
6400 MOZ_TRY_VAR(thenBranch, consequentOrAlternative(yieldHandling))do { auto mozTryVarTempResult_ = (consequentOrAlternative(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (thenBranch
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6401
6402 if (!condList.append(cond) || !thenList.append(thenBranch) ||
6403 !posList.append(begin)) {
6404 return errorResult();
6405 }
6406
6407 bool matched;
6408 if (!tokenStream.matchToken(&matched, TokenKind::Else,
6409 TokenStream::SlashIsRegExp)) {
6410 return errorResult();
6411 }
6412 if (matched) {
6413 if (!tokenStream.matchToken(&matched, TokenKind::If,
6414 TokenStream::SlashIsRegExp)) {
6415 return errorResult();
6416 }
6417 if (matched) {
6418 continue;
6419 }
6420 MOZ_TRY_VAR(elseBranch, consequentOrAlternative(yieldHandling))do { auto mozTryVarTempResult_ = (consequentOrAlternative(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (elseBranch
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6421 } else {
6422 elseBranch = null();
6423 }
6424 break;
6425 }
6426
6427 TernaryNodeType ifNode;
6428 for (int i = condList.length() - 1; i >= 0; i--) {
6429 MOZ_TRY_VAR(ifNode, handler_.newIfStatement(posList[i], condList[i],do { auto mozTryVarTempResult_ = (handler_.newIfStatement(posList
[i], condList[i], thenList[i], elseBranch)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ifNode) = mozTryVarTempResult_.unwrap(); }
while (0)
6430 thenList[i], elseBranch))do { auto mozTryVarTempResult_ = (handler_.newIfStatement(posList
[i], condList[i], thenList[i], elseBranch)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ifNode) = mozTryVarTempResult_.unwrap(); }
while (0)
;
6431 elseBranch = ifNode;
6432 }
6433
6434 return ifNode;
6435}
6436
6437template <class ParseHandler, typename Unit>
6438typename ParseHandler::BinaryNodeResult
6439GeneralParser<ParseHandler, Unit>::doWhileStatement(
6440 YieldHandling yieldHandling) {
6441 uint32_t begin = pos().begin;
6442 ParseContext::Statement stmt(pc_, StatementKind::DoLoop);
6443 Node body;
6444 MOZ_TRY_VAR(body, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6445 if (!mustMatchToken(TokenKind::While, JSMSG_WHILE_AFTER_DO)) {
6446 return errorResult();
6447 }
6448 Node cond;
6449 MOZ_TRY_VAR(cond, condition(InAllowed, yieldHandling))do { auto mozTryVarTempResult_ = (condition(InAllowed, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (cond) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6450
6451 // The semicolon after do-while is even more optional than most
6452 // semicolons in JS. Web compat required this by 2004:
6453 // http://bugzilla.mozilla.org/show_bug.cgi?id=238945
6454 // ES3 and ES5 disagreed, but ES6 conforms to Web reality:
6455 // https://bugs.ecmascript.org/show_bug.cgi?id=157
6456 // To parse |do {} while (true) false| correctly, use SlashIsRegExp.
6457 bool ignored;
6458 if (!tokenStream.matchToken(&ignored, TokenKind::Semi,
6459 TokenStream::SlashIsRegExp)) {
6460 return errorResult();
6461 }
6462 return handler_.newDoWhileStatement(body, cond, TokenPos(begin, pos().end));
6463}
6464
6465template <class ParseHandler, typename Unit>
6466typename ParseHandler::BinaryNodeResult
6467GeneralParser<ParseHandler, Unit>::whileStatement(YieldHandling yieldHandling) {
6468 uint32_t begin = pos().begin;
6469 ParseContext::Statement stmt(pc_, StatementKind::WhileLoop);
6470 Node cond;
6471 MOZ_TRY_VAR(cond, condition(InAllowed, yieldHandling))do { auto mozTryVarTempResult_ = (condition(InAllowed, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (cond) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6472 Node body;
6473 MOZ_TRY_VAR(body, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6474 return handler_.newWhileStatement(begin, cond, body);
6475}
6476
6477template <class ParseHandler, typename Unit>
6478bool GeneralParser<ParseHandler, Unit>::matchInOrOf(bool* isForInp,
6479 bool* isForOfp) {
6480 TokenKind tt;
6481 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6482 return false;
6483 }
6484
6485 *isForInp = tt == TokenKind::In;
6486 *isForOfp = tt == TokenKind::Of;
6487 if (!*isForInp && !*isForOfp) {
6488 anyChars.ungetToken();
6489 }
6490
6491 MOZ_ASSERT_IF(*isForInp || *isForOfp, *isForInp != *isForOfp)do { if (*isForInp || *isForOfp) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(*isForInp != *isForOfp
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(*isForInp != *isForOfp))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("*isForInp != *isForOfp", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6491); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*isForInp != *isForOfp"
")"); do { *((volatile int*)__null) = 6491; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6492 return true;
6493}
6494
6495template <class ParseHandler, typename Unit>
6496bool GeneralParser<ParseHandler, Unit>::forHeadStart(
6497 YieldHandling yieldHandling, IteratorKind iterKind,
6498 ParseNodeKind* forHeadKind, Node* forInitialPart,
6499 Maybe<ParseContext::Scope>& forLoopLexicalScope,
6500 Node* forInOrOfExpression) {
6501 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftParen))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftParen))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftParen))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftParen)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6501); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftParen)"
")"); do { *((volatile int*)__null) = 6501; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6502
6503 TokenKind tt;
6504 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6505 return false;
6506 }
6507
6508 // Super-duper easy case: |for (;| is a C-style for-loop with no init
6509 // component.
6510 if (tt == TokenKind::Semi) {
6511 *forInitialPart = null();
6512 *forHeadKind = ParseNodeKind::ForHead;
6513 return true;
6514 }
6515
6516 // Parsing after |for (var| is also relatively simple (from this method's
6517 // point of view). No block-related work complicates matters, so delegate
6518 // to Parser::declaration.
6519 if (tt == TokenKind::Var) {
6520 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6521
6522 // Pass null for block object because |var| declarations don't use one.
6523 MOZ_TRY_VAR_OR_RETURN(*forInitialPart,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
6524 declarationList(yieldHandling, ParseNodeKind::VarStmt,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
6525 forHeadKind, forInOrOfExpression),do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
6526 false)do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
;
6527 return true;
6528 }
6529
6530 // Otherwise we have a lexical declaration or an expression.
6531
6532 // For-in loop backwards compatibility requires that |let| starting a
6533 // for-loop that's not a (new to ES6) for-of loop, in non-strict mode code,
6534 // parse as an identifier. (|let| in for-of is always a declaration.)
6535 //
6536 // For-of loops can't start with the token sequence "async of", because that
6537 // leads to a shift-reduce conflict when parsing |for (async of => {};;)| or
6538 // |for (async of [])|.
6539 bool parsingLexicalDeclaration = false;
6540 bool letIsIdentifier = false;
6541 bool startsWithForOf = false;
6542
6543 if (tt == TokenKind::Const) {
6544 parsingLexicalDeclaration = true;
6545 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6546 }
6547#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
6548 else if (tt == TokenKind::Await) {
6549 if (!pc_->isAsync()) {
6550 if (pc_->atModuleTopLevel()) {
6551 if (!options().topLevelAwait) {
6552 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
6553 return false;
6554 }
6555 pc_->sc()->asModuleContext()->setIsAsync();
6556 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6556); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 6556; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6557 }
6558 }
6559 if (pc_->isAsync()) {
6560 // Try finding evidence of a AwaitUsingDeclaration the syntax for which
6561 // would be:
6562 // await [no LineTerminator here] using [no LineTerminator here]
6563 // identifier
6564 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6565
6566 TokenKind nextTok = TokenKind::Eof;
6567 if (!tokenStream.peekTokenSameLine(&nextTok,
6568 TokenStream::SlashIsRegExp)) {
6569 return false;
6570 }
6571
6572 if (nextTok == TokenKind::Using) {
6573 tokenStream.consumeKnownToken(nextTok, TokenStream::SlashIsRegExp);
6574
6575 TokenKind nextTokIdent = TokenKind::Eof;
6576 if (!tokenStream.peekTokenSameLine(&nextTokIdent)) {
6577 return false;
6578 }
6579
6580 if (TokenKindIsPossibleIdentifier(nextTokIdent)) {
6581 parsingLexicalDeclaration = true;
6582 } else {
6583 anyChars.ungetToken(); // put back using token
6584 anyChars.ungetToken(); // put back await token
6585 }
6586 } else {
6587 anyChars.ungetToken(); // put back await token
6588 }
6589 }
6590 } else if (tt == TokenKind::Using) {
6591 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6592
6593 // Look ahead to find either a 'of' token or if not identifier
6594 TokenKind nextTok = TokenKind::Eof;
6595 if (!tokenStream.peekTokenSameLine(&nextTok)) {
6596 return false;
6597 }
6598
6599 if (nextTok == TokenKind::Of || !TokenKindIsPossibleIdentifier(nextTok)) {
6600 anyChars.ungetToken(); // we didnt find a valid case of using decl put
6601 // back the token
6602 } else {
6603 parsingLexicalDeclaration = true;
6604 }
6605 }
6606#endif
6607 else if (tt == TokenKind::Let) {
6608 // We could have a {For,Lexical}Declaration, or we could have a
6609 // LeftHandSideExpression with lookahead restrictions so it's not
6610 // ambiguous with the former. Check for a continuation of the former
6611 // to decide which we have.
6612 tokenStream.consumeKnownToken(TokenKind::Let, TokenStream::SlashIsRegExp);
6613
6614 TokenKind next;
6615 if (!tokenStream.peekToken(&next)) {
6616 return false;
6617 }
6618
6619 parsingLexicalDeclaration = nextTokenContinuesLetDeclaration(next);
6620 if (!parsingLexicalDeclaration) {
6621 // If we end up here, we may have `for (let <reserved word> of/in ...`,
6622 // which is not valid.
6623 if (next != TokenKind::In && next != TokenKind::Of &&
6624 TokenKindIsReservedWord(next)) {
6625 tokenStream.consumeKnownToken(next);
6626 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
6627 return false;
6628 }
6629
6630 anyChars.ungetToken();
6631 letIsIdentifier = true;
6632 }
6633 } else if (tt == TokenKind::Async && iterKind == IteratorKind::Sync) {
6634 tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::SlashIsRegExp);
6635
6636 TokenKind next;
6637 if (!tokenStream.peekToken(&next)) {
6638 return false;
6639 }
6640
6641 if (next == TokenKind::Of) {
6642 startsWithForOf = true;
6643 }
6644 anyChars.ungetToken();
6645 }
6646
6647 if (parsingLexicalDeclaration) {
6648 if (options().selfHostingMode) {
6649 error(JSMSG_SELFHOSTED_LEXICAL);
6650 return false;
6651 }
6652
6653 forLoopLexicalScope.emplace(this);
6654 if (!forLoopLexicalScope->init(pc_)) {
6655 return false;
6656 }
6657
6658 // Push a temporary ForLoopLexicalHead Statement that allows for
6659 // lexical declarations, as they are usually allowed only in braced
6660 // statements.
6661 ParseContext::Statement forHeadStmt(pc_, StatementKind::ForLoopLexicalHead);
6662
6663 ParseNodeKind declKind;
6664 switch (tt) {
6665 case TokenKind::Const:
6666 declKind = ParseNodeKind::ConstDecl;
6667 break;
6668#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
6669 case TokenKind::Using:
6670 declKind = ParseNodeKind::UsingDecl;
6671 break;
6672 case TokenKind::Await:
6673 declKind = ParseNodeKind::AwaitUsingDecl;
6674 break;
6675#endif
6676 case TokenKind::Let:
6677 declKind = ParseNodeKind::LetDecl;
6678 break;
6679 default:
6680 MOZ_CRASH("unexpected node kind")do { do { } while (false); MOZ_ReportCrash("" "unexpected node kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6680); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected node kind"
")"); do { *((volatile int*)__null) = 6680; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6681 }
6682
6683 MOZ_TRY_VAR_OR_RETURN(*forInitialPart,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6684 declarationList(yieldHandling, declKind, forHeadKind,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6685 forInOrOfExpression),do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6686 false)do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
;
6687 return true;
6688 }
6689
6690 uint32_t exprOffset;
6691 if (!tokenStream.peekOffset(&exprOffset, TokenStream::SlashIsRegExp)) {
6692 return false;
6693 }
6694
6695 // Finally, handle for-loops that start with expressions. Pass
6696 // |InProhibited| so that |in| isn't parsed in a RelationalExpression as a
6697 // binary operator. |in| makes it a for-in loop, *not* an |in| expression.
6698 PossibleError possibleError(*this);
6699 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6700 *forInitialPart,do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6701 expr(InProhibited, yieldHandling, TripledotProhibited, &possibleError),do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6702 false)do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
;
6703
6704 bool isForIn, isForOf;
6705 if (!matchInOrOf(&isForIn, &isForOf)) {
6706 return false;
6707 }
6708
6709 // If we don't encounter 'in'/'of', we have a for(;;) loop. We've handled
6710 // the init expression; the caller handles the rest.
6711 if (!isForIn && !isForOf) {
6712 if (!possibleError.checkForExpressionError()) {
6713 return false;
6714 }
6715
6716 *forHeadKind = ParseNodeKind::ForHead;
6717 return true;
6718 }
6719
6720 MOZ_ASSERT(isForIn != isForOf)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isForIn != isForOf)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isForIn != isForOf))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("isForIn != isForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6720); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isForIn != isForOf"
")"); do { *((volatile int*)__null) = 6720; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6721
6722 // In a for-of loop, 'let' that starts the loop head is a |let| keyword,
6723 // per the [lookahead ≠ let] restriction on the LeftHandSideExpression
6724 // variant of such loops. Expressions that start with |let| can't be used
6725 // here.
6726 //
6727 // var let = {};
6728 // for (let.prop of [1]) // BAD
6729 // break;
6730 //
6731 // See ES6 13.7.
6732 if (isForOf && letIsIdentifier) {
6733 errorAt(exprOffset, JSMSG_BAD_STARTING_FOROF_LHS, "let");
6734 return false;
6735 }
6736
6737 // In a for-of loop, the LeftHandSideExpression isn't allowed to be an
6738 // identifier named "async" per the [lookahead ≠ async of] restriction.
6739 if (isForOf && startsWithForOf) {
6740 errorAt(exprOffset, JSMSG_BAD_STARTING_FOROF_LHS, "async of");
6741 return false;
6742 }
6743
6744 *forHeadKind = isForIn ? ParseNodeKind::ForIn : ParseNodeKind::ForOf;
6745
6746 // Verify the left-hand side expression doesn't have a forbidden form.
6747 if (handler_.isUnparenthesizedDestructuringPattern(*forInitialPart)) {
6748 if (!possibleError.checkForDestructuringErrorOrWarning()) {
6749 return false;
6750 }
6751 } else if (handler_.isName(*forInitialPart)) {
6752 if (const char* chars = nameIsArgumentsOrEval(*forInitialPart)) {
6753 // |chars| is "arguments" or "eval" here.
6754 if (!strictModeErrorAt(exprOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) {
6755 return false;
6756 }
6757 }
6758 } else if (handler_.isArgumentsLength(*forInitialPart)) {
6759 pc_->sc()->setIneligibleForArgumentsLength();
6760 } else if (handler_.isPropertyOrPrivateMemberAccess(*forInitialPart)) {
6761 // Permitted: no additional testing/fixup needed.
6762 } else if (handler_.isFunctionCall(*forInitialPart)) {
6763 if (!strictModeErrorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE)) {
6764 return false;
6765 }
6766 } else {
6767 errorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE);
6768 return false;
6769 }
6770
6771 if (!possibleError.checkForExpressionError()) {
6772 return false;
6773 }
6774
6775 // Finally, parse the iterated expression, making the for-loop's closing
6776 // ')' the next token.
6777 MOZ_TRY_VAR_OR_RETURN(*forInOrOfExpression,do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
6778 expressionAfterForInOrOf(*forHeadKind, yieldHandling),do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
6779 false)do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
;
6780 return true;
6781}
6782
6783template <class ParseHandler, typename Unit>
6784typename ParseHandler::NodeResult
6785GeneralParser<ParseHandler, Unit>::forStatement(YieldHandling yieldHandling) {
6786 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::For))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::For))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::For)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::For)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6786); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::For)"
")"); do { *((volatile int*)__null) = 6786; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6787
6788 uint32_t begin = pos().begin;
6789
6790 ParseContext::Statement stmt(pc_, StatementKind::ForLoop);
6791
6792 IteratorKind iterKind = IteratorKind::Sync;
6793 unsigned iflags = 0;
6794
6795 if (pc_->isAsync() || pc_->sc()->isModuleContext()) {
6796 bool matched;
6797 if (!tokenStream.matchToken(&matched, TokenKind::Await)) {
6798 return errorResult();
6799 }
6800
6801 // If we come across a top level await here, mark the module as async.
6802 if (matched && pc_->sc()->isModuleContext() && !pc_->isAsync()) {
6803 if (!options().topLevelAwait) {
6804 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
6805 return errorResult();
6806 }
6807 pc_->sc()->asModuleContext()->setIsAsync();
6808 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6808); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 6808; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6809 }
6810
6811 if (matched) {
6812 iflags |= JSITER_FORAWAITOF0x80;
6813 iterKind = IteratorKind::Async;
6814 }
6815 }
6816
6817 if (!mustMatchToken(TokenKind::LeftParen, [this](TokenKind actual) {
6818 this->error((actual == TokenKind::Await && !this->pc_->isAsync())
6819 ? JSMSG_FOR_AWAIT_OUTSIDE_ASYNC
6820 : JSMSG_PAREN_AFTER_FOR);
6821 })) {
6822 return errorResult();
6823 }
6824
6825 // ParseNodeKind::ForHead, ParseNodeKind::ForIn, or
6826 // ParseNodeKind::ForOf depending on the loop type.
6827 ParseNodeKind headKind;
6828
6829 // |x| in either |for (x; ...; ...)| or |for (x in/of ...)|.
6830 Node startNode;
6831
6832 // The next two variables are used to implement `for (let/const ...)`.
6833 //
6834 // We generate an implicit block, wrapping the whole loop, to store loop
6835 // variables declared this way. Note that if the loop uses `for (var...)`
6836 // instead, those variables go on some existing enclosing scope, so no
6837 // implicit block scope is created.
6838 //
6839 // Both variables remain null/none if the loop is any other form.
6840
6841 // The static block scope for the implicit block scope.
6842 Maybe<ParseContext::Scope> forLoopLexicalScope;
6843
6844 // The expression being iterated over, for for-in/of loops only. Unused
6845 // for for(;;) loops.
6846 Node iteratedExpr;
6847
6848 // Parse the entirety of the loop-head for a for-in/of loop (so the next
6849 // token is the closing ')'):
6850 //
6851 // for (... in/of ...) ...
6852 // ^next token
6853 //
6854 // ...OR, parse up to the first ';' in a C-style for-loop:
6855 //
6856 // for (...; ...; ...) ...
6857 // ^next token
6858 //
6859 // In either case the subsequent token can be consistently accessed using
6860 // TokenStream::SlashIsDiv semantics.
6861 if (!forHeadStart(yieldHandling, iterKind, &headKind, &startNode,
6862 forLoopLexicalScope, &iteratedExpr)) {
6863 return errorResult();
6864 }
6865
6866 MOZ_ASSERT(headKind == ParseNodeKind::ForIn ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf || headKind == ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(headKind == ParseNodeKind::ForIn
|| headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6867 headKind == ParseNodeKind::ForOf ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf || headKind == ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(headKind == ParseNodeKind::ForIn
|| headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6868 headKind == ParseNodeKind::ForHead)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf || headKind == ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(headKind == ParseNodeKind::ForIn
|| headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6869
6870 if (iterKind == IteratorKind::Async && headKind != ParseNodeKind::ForOf) {
6871 errorAt(begin, JSMSG_FOR_AWAIT_NOT_OF);
6872 return errorResult();
6873 }
6874
6875 TernaryNodeType forHead;
6876 if (headKind == ParseNodeKind::ForHead) {
6877 Node init = startNode;
6878
6879 // Look for an operand: |for (;| means we might have already examined
6880 // this semicolon with that modifier.
6881 if (!mustMatchToken(TokenKind::Semi, JSMSG_SEMI_AFTER_FOR_INIT)) {
6882 return errorResult();
6883 }
6884
6885 TokenKind tt;
6886 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6887 return errorResult();
6888 }
6889
6890 Node test;
6891 if (tt == TokenKind::Semi) {
6892 test = null();
6893 } else {
6894 MOZ_TRY_VAR(test, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (test) = mozTryVarTempResult_.unwrap(); } while (0)
;
6895 }
6896
6897 if (!mustMatchToken(TokenKind::Semi, JSMSG_SEMI_AFTER_FOR_COND)) {
6898 return errorResult();
6899 }
6900
6901 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6902 return errorResult();
6903 }
6904
6905 Node update;
6906 if (tt == TokenKind::RightParen) {
6907 update = null();
6908 } else {
6909 MOZ_TRY_VAR(update, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (update) = mozTryVarTempResult_.unwrap(); } while (0)
;
6910 }
6911
6912 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_FOR_CTRL)) {
6913 return errorResult();
6914 }
6915
6916 TokenPos headPos(begin, pos().end);
6917 MOZ_TRY_VAR(forHead, handler_.newForHead(init, test, update, headPos))do { auto mozTryVarTempResult_ = (handler_.newForHead(init, test
, update, headPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forHead) = mozTryVarTempResult_.unwrap(); } while (0)
;
6918 } else {
6919 MOZ_ASSERT(headKind == ParseNodeKind::ForIn ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6920); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 6920; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6920 headKind == ParseNodeKind::ForOf)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6920); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 6920; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6921
6922 // |target| is the LeftHandSideExpression or declaration to which the
6923 // per-iteration value (an arbitrary value exposed by the iteration
6924 // protocol, or a string naming a property) is assigned.
6925 Node target = startNode;
6926
6927 // Parse the rest of the for-in/of head.
6928 if (headKind == ParseNodeKind::ForIn) {
6929 stmt.refineForKind(StatementKind::ForInLoop);
6930 } else {
6931 stmt.refineForKind(StatementKind::ForOfLoop);
6932 }
6933
6934 // Parser::declaration consumed everything up to the closing ')'. That
6935 // token follows an {Assignment,}Expression and so must be interpreted
6936 // as an operand to be consistent with normal expression tokenizing.
6937 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_FOR_CTRL)) {
6938 return errorResult();
6939 }
6940
6941 TokenPos headPos(begin, pos().end);
6942 MOZ_TRY_VAR(forHead, handler_.newForInOrOfHead(headKind, target,do { auto mozTryVarTempResult_ = (handler_.newForInOrOfHead(headKind
, target, iteratedExpr, headPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forHead) = mozTryVarTempResult_.unwrap(); } while (0)
6943 iteratedExpr, headPos))do { auto mozTryVarTempResult_ = (handler_.newForInOrOfHead(headKind
, target, iteratedExpr, headPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forHead) = mozTryVarTempResult_.unwrap(); } while (0)
;
6944 }
6945
6946 Node body;
6947 MOZ_TRY_VAR(body, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6948
6949 ForNodeType forLoop;
6950 MOZ_TRY_VAR(forLoop, handler_.newForStatement(begin, forHead, body, iflags))do { auto mozTryVarTempResult_ = (handler_.newForStatement(begin
, forHead, body, iflags)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forLoop) = mozTryVarTempResult_.unwrap(); } while (0)
;
6951
6952 if (forLoopLexicalScope) {
6953 return finishLexicalScope(*forLoopLexicalScope, forLoop);
6954 }
6955
6956 return forLoop;
6957}
6958
6959template <class ParseHandler, typename Unit>
6960typename ParseHandler::SwitchStatementResult
6961GeneralParser<ParseHandler, Unit>::switchStatement(
6962 YieldHandling yieldHandling) {
6963 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Switch))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Switch))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Switch)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Switch)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Switch)"
")"); do { *((volatile int*)__null) = 6963; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6964 uint32_t begin = pos().begin;
6965
6966 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_SWITCH)) {
6967 return errorResult();
6968 }
6969
6970 Node discriminant;
6971 MOZ_TRY_VAR(discriminant,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (discriminant) = mozTryVarTempResult_.unwrap(); } while (0
)
6972 exprInParens(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (discriminant) = mozTryVarTempResult_.unwrap(); } while (0
)
;
6973
6974 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_SWITCH)) {
6975 return errorResult();
6976 }
6977 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_SWITCH)) {
6978 return errorResult();
6979 }
6980
6981 ParseContext::Statement stmt(pc_, StatementKind::Switch);
6982 ParseContext::Scope scope(this);
6983 if (!scope.init(pc_)) {
6984 return errorResult();
6985 }
6986
6987 ListNodeType caseList;
6988 MOZ_TRY_VAR(caseList, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (caseList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6989
6990 bool seenDefault = false;
6991 TokenKind tt;
6992 while (true) {
6993 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6994 return errorResult();
6995 }
6996 if (tt == TokenKind::RightCurly) {
6997 break;
6998 }
6999 uint32_t caseBegin = pos().begin;
7000
7001 Node caseExpr;
7002 switch (tt) {
7003 case TokenKind::Default:
7004 if (seenDefault) {
7005 error(JSMSG_TOO_MANY_DEFAULTS);
7006 return errorResult();
7007 }
7008 seenDefault = true;
7009 caseExpr = null(); // The default case has pn_left == nullptr.
7010 break;
7011
7012 case TokenKind::Case:
7013 MOZ_TRY_VAR(caseExpr,do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
7014 expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
7015 break;
7016
7017 default:
7018 error(JSMSG_BAD_SWITCH);
7019 return errorResult();
7020 }
7021
7022 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_CASE)) {
7023 return errorResult();
7024 }
7025
7026 ListNodeType body;
7027 MOZ_TRY_VAR(body, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (body) =
mozTryVarTempResult_.unwrap(); } while (0)
;
7028
7029 bool afterReturn = false;
7030 bool warnedAboutStatementsAfterReturn = false;
7031 uint32_t statementBegin = 0;
7032 while (true) {
7033 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
7034 return errorResult();
7035 }
7036 if (tt == TokenKind::RightCurly || tt == TokenKind::Case ||
7037 tt == TokenKind::Default) {
7038 break;
7039 }
7040 if (afterReturn) {
7041 if (!tokenStream.peekOffset(&statementBegin,
7042 TokenStream::SlashIsRegExp)) {
7043 return errorResult();
7044 }
7045 }
7046 Node stmt;
7047 MOZ_TRY_VAR(stmt, statementListItem(yieldHandling))do { auto mozTryVarTempResult_ = (statementListItem(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (stmt) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7048 if (!warnedAboutStatementsAfterReturn) {
7049 if (afterReturn) {
7050 if (!handler_.isStatementPermittedAfterReturnStatement(stmt)) {
7051 if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
7052 return errorResult();
7053 }
7054
7055 warnedAboutStatementsAfterReturn = true;
7056 }
7057 } else if (handler_.isReturnStatement(stmt)) {
7058 afterReturn = true;
7059 }
7060 }
7061 handler_.addStatementToList(body, stmt);
7062 }
7063
7064 CaseClauseType caseClause;
7065 MOZ_TRY_VAR(caseClause,do { auto mozTryVarTempResult_ = (handler_.newCaseOrDefault(caseBegin
, caseExpr, body)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseClause) = mozTryVarTempResult_.unwrap(); } while (0)
7066 handler_.newCaseOrDefault(caseBegin, caseExpr, body))do { auto mozTryVarTempResult_ = (handler_.newCaseOrDefault(caseBegin
, caseExpr, body)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseClause) = mozTryVarTempResult_.unwrap(); } while (0)
;
7067 handler_.addCaseStatementToList(caseList, caseClause);
7068 }
7069
7070 LexicalScopeNodeType lexicalForCaseList;
7071 MOZ_TRY_VAR(lexicalForCaseList, finishLexicalScope(scope, caseList))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, caseList
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (lexicalForCaseList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7072
7073 handler_.setEndPosition(lexicalForCaseList, pos().end);
7074
7075 return handler_.newSwitchStatement(begin, discriminant, lexicalForCaseList,
7076 seenDefault);
7077}
7078
7079template <class ParseHandler, typename Unit>
7080typename ParseHandler::ContinueStatementResult
7081GeneralParser<ParseHandler, Unit>::continueStatement(
7082 YieldHandling yieldHandling) {
7083 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Continue))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Continue))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Continue)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Continue)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7083); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Continue)"
")"); do { *((volatile int*)__null) = 7083; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7084 uint32_t begin = pos().begin;
7085
7086 TaggedParserAtomIndex label;
7087 if (!matchLabel(yieldHandling, &label)) {
7088 return errorResult();
7089 }
7090
7091 auto validity = pc_->checkContinueStatement(label);
7092 if (validity.isErr()) {
7093 switch (validity.unwrapErr()) {
7094 case ParseContext::ContinueStatementError::NotInALoop:
7095 errorAt(begin, JSMSG_BAD_CONTINUE);
7096 break;
7097 case ParseContext::ContinueStatementError::LabelNotFound:
7098 error(JSMSG_LABEL_NOT_FOUND);
7099 break;
7100 }
7101 return errorResult();
7102 }
7103
7104 if (!matchOrInsertSemicolon()) {
7105 return errorResult();
7106 }
7107
7108 return handler_.newContinueStatement(label, TokenPos(begin, pos().end));
7109}
7110
7111template <class ParseHandler, typename Unit>
7112typename ParseHandler::BreakStatementResult
7113GeneralParser<ParseHandler, Unit>::breakStatement(YieldHandling yieldHandling) {
7114 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Break))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Break))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Break)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Break)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7114); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Break)"
")"); do { *((volatile int*)__null) = 7114; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7115 uint32_t begin = pos().begin;
7116
7117 TaggedParserAtomIndex label;
7118 if (!matchLabel(yieldHandling, &label)) {
7119 return errorResult();
7120 }
7121
7122 auto validity = pc_->checkBreakStatement(label);
7123 if (validity.isErr()) {
7124 switch (validity.unwrapErr()) {
7125 case ParseContext::BreakStatementError::ToughBreak:
7126 errorAt(begin, JSMSG_TOUGH_BREAK);
7127 return errorResult();
7128 case ParseContext::BreakStatementError::LabelNotFound:
7129 error(JSMSG_LABEL_NOT_FOUND);
7130 return errorResult();
7131 }
7132 }
7133
7134 if (!matchOrInsertSemicolon()) {
7135 return errorResult();
7136 }
7137
7138 return handler_.newBreakStatement(label, TokenPos(begin, pos().end));
7139}
7140
7141template <class ParseHandler, typename Unit>
7142typename ParseHandler::UnaryNodeResult
7143GeneralParser<ParseHandler, Unit>::returnStatement(
7144 YieldHandling yieldHandling) {
7145 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Return))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Return))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Return)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Return)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7145); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Return)"
")"); do { *((volatile int*)__null) = 7145; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7146 uint32_t begin = pos().begin;
7147
7148 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7148); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 7148; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7149
7150 // Parse an optional operand.
7151 //
7152 // This is ugly, but we don't want to require a semicolon.
7153 Node exprNode;
7154 TokenKind tt = TokenKind::Eof;
7155 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7156 return errorResult();
7157 }
7158 switch (tt) {
7159 case TokenKind::Eol:
7160 case TokenKind::Eof:
7161 case TokenKind::Semi:
7162 case TokenKind::RightCurly:
7163 exprNode = null();
7164 break;
7165 default: {
7166 MOZ_TRY_VAR(exprNode,do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
7167 expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
7168 }
7169 }
7170
7171 if (!matchOrInsertSemicolon()) {
7172 return errorResult();
7173 }
7174
7175 return handler_.newReturnStatement(exprNode, TokenPos(begin, pos().end));
7176}
7177
7178template <class ParseHandler, typename Unit>
7179typename ParseHandler::UnaryNodeResult
7180GeneralParser<ParseHandler, Unit>::yieldExpression(InHandling inHandling) {
7181 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Yield))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Yield))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Yield)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Yield)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7181); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Yield)"
")"); do { *((volatile int*)__null) = 7181; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7182 uint32_t begin = pos().begin;
7183
7184 MOZ_ASSERT(pc_->isGenerator())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isGenerator())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isGenerator()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isGenerator()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7184); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isGenerator()"
")"); do { *((volatile int*)__null) = 7184; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7185 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7185); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 7185; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7186
7187 pc_->lastYieldOffset = begin;
7188
7189 Node exprNode;
7190 ParseNodeKind kind = ParseNodeKind::YieldExpr;
7191 TokenKind tt = TokenKind::Eof;
7192 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7193 return errorResult();
7194 }
7195 switch (tt) {
7196 // TokenKind::Eol is special; it implements the [no LineTerminator here]
7197 // quirk in the grammar.
7198 case TokenKind::Eol:
7199 // The rest of these make up the complete set of tokens that can
7200 // appear after any of the places where AssignmentExpression is used
7201 // throughout the grammar. Conveniently, none of them can also be the
7202 // start an expression.
7203 case TokenKind::Eof:
7204 case TokenKind::Semi:
7205 case TokenKind::RightCurly:
7206 case TokenKind::RightBracket:
7207 case TokenKind::RightParen:
7208 case TokenKind::Colon:
7209 case TokenKind::Comma:
7210 case TokenKind::In: // Annex B.3.6 `for (x = yield in y) ;`
7211 // No value.
7212 exprNode = null();
7213 break;
7214 case TokenKind::Mul:
7215 kind = ParseNodeKind::YieldStarExpr;
7216 tokenStream.consumeKnownToken(TokenKind::Mul, TokenStream::SlashIsRegExp);
7217 [[fallthrough]];
7218 default:
7219 MOZ_TRY_VAR(exprNode,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, YieldIsKeyword
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
7220 assignExpr(inHandling, YieldIsKeyword, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, YieldIsKeyword
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
7221 }
7222 if (kind == ParseNodeKind::YieldStarExpr) {
7223 return handler_.newYieldStarExpression(begin, exprNode);
7224 }
7225 return handler_.newYieldExpression(begin, exprNode);
7226}
7227
7228template <class ParseHandler, typename Unit>
7229typename ParseHandler::BinaryNodeResult
7230GeneralParser<ParseHandler, Unit>::withStatement(YieldHandling yieldHandling) {
7231 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::With))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::With))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::With)))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::With)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7231); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 7231; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7232 uint32_t begin = pos().begin;
7233
7234 if (pc_->sc()->strict()) {
7235 if (!strictModeError(JSMSG_STRICT_CODE_WITH)) {
7236 return errorResult();
7237 }
7238 }
7239
7240 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_WITH)) {
7241 return errorResult();
7242 }
7243
7244 Node objectExpr;
7245 MOZ_TRY_VAR(objectExpr,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (objectExpr) = mozTryVarTempResult_.unwrap(); } while (0)
7246 exprInParens(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (objectExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
7247
7248 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_WITH)) {
7249 return errorResult();
7250 }
7251
7252 Node innerBlock;
7253 {
7254 ParseContext::Statement stmt(pc_, StatementKind::With);
7255 MOZ_TRY_VAR(innerBlock, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (innerBlock) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7256 }
7257
7258 pc_->sc()->setBindingsAccessedDynamically();
7259
7260 return handler_.newWithStatement(begin, objectExpr, innerBlock);
7261}
7262
7263template <class ParseHandler, typename Unit>
7264typename ParseHandler::NodeResult
7265GeneralParser<ParseHandler, Unit>::labeledItem(YieldHandling yieldHandling) {
7266 TokenKind tt;
7267 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
7268 return errorResult();
7269 }
7270
7271 if (tt == TokenKind::Function) {
7272 TokenKind next;
7273 if (!tokenStream.peekToken(&next)) {
7274 return errorResult();
7275 }
7276
7277 // GeneratorDeclaration is only matched by HoistableDeclaration in
7278 // StatementListItem, so generators can't be inside labels.
7279 if (next == TokenKind::Mul) {
7280 error(JSMSG_GENERATOR_LABEL);
7281 return errorResult();
7282 }
7283
7284 // Per 13.13.1 it's a syntax error if LabelledItem: FunctionDeclaration
7285 // is ever matched. Per Annex B.3.2 that modifies this text, this
7286 // applies only to strict mode code.
7287 if (pc_->sc()->strict()) {
7288 error(JSMSG_FUNCTION_LABEL);
7289 return errorResult();
7290 }
7291
7292 return functionStmt(pos().begin, yieldHandling, NameRequired);
7293 }
7294
7295 anyChars.ungetToken();
7296 return statement(yieldHandling);
7297}
7298
7299template <class ParseHandler, typename Unit>
7300typename ParseHandler::LabeledStatementResult
7301GeneralParser<ParseHandler, Unit>::labeledStatement(
7302 YieldHandling yieldHandling) {
7303 TaggedParserAtomIndex label = labelIdentifier(yieldHandling);
7304 if (!label) {
7305 return errorResult();
7306 }
7307
7308 auto hasSameLabel = [&label](ParseContext::LabelStatement* stmt) {
7309 return stmt->label() == label;
7310 };
7311
7312 uint32_t begin = pos().begin;
7313
7314 if (pc_->template findInnermostStatement<ParseContext::LabelStatement>(
7315 hasSameLabel)) {
7316 errorAt(begin, JSMSG_DUPLICATE_LABEL);
7317 return errorResult();
7318 }
7319
7320 tokenStream.consumeKnownToken(TokenKind::Colon);
7321
7322 /* Push a label struct and parse the statement. */
7323 ParseContext::LabelStatement stmt(pc_, label);
7324 Node pn;
7325 MOZ_TRY_VAR(pn, labeledItem(yieldHandling))do { auto mozTryVarTempResult_ = (labeledItem(yieldHandling))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7326
7327 return handler_.newLabeledStatement(label, pn, begin);
7328}
7329
7330template <class ParseHandler, typename Unit>
7331typename ParseHandler::UnaryNodeResult
7332GeneralParser<ParseHandler, Unit>::throwStatement(YieldHandling yieldHandling) {
7333 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Throw))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Throw))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Throw)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Throw)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7333); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Throw)"
")"); do { *((volatile int*)__null) = 7333; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7334 uint32_t begin = pos().begin;
7335
7336 /* ECMA-262 Edition 3 says 'throw [no LineTerminator here] Expr'. */
7337 TokenKind tt = TokenKind::Eof;
7338 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7339 return errorResult();
7340 }
7341 if (tt == TokenKind::Eof || tt == TokenKind::Semi ||
7342 tt == TokenKind::RightCurly) {
7343 error(JSMSG_MISSING_EXPR_AFTER_THROW);
7344 return errorResult();
7345 }
7346 if (tt == TokenKind::Eol) {
7347 error(JSMSG_LINE_BREAK_AFTER_THROW);
7348 return errorResult();
7349 }
7350
7351 Node throwExpr;
7352 MOZ_TRY_VAR(throwExpr, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (throwExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
7353
7354 if (!matchOrInsertSemicolon()) {
7355 return errorResult();
7356 }
7357
7358 return handler_.newThrowStatement(throwExpr, TokenPos(begin, pos().end));
7359}
7360
7361template <class ParseHandler, typename Unit>
7362typename ParseHandler::TernaryNodeResult
7363GeneralParser<ParseHandler, Unit>::tryStatement(YieldHandling yieldHandling) {
7364 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Try))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Try))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Try)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Try)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7364); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Try)"
")"); do { *((volatile int*)__null) = 7364; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7365 uint32_t begin = pos().begin;
7366
7367 /*
7368 * try nodes are ternary.
7369 * kid1 is the try statement
7370 * kid2 is the catch node list or null
7371 * kid3 is the finally statement
7372 *
7373 * catch nodes are binary.
7374 * left is the catch-name/pattern or null
7375 * right is the catch block
7376 *
7377 * catch lvalue nodes are either:
7378 * a single identifier
7379 * TokenKind::RightBracket for a destructuring left-hand side
7380 * TokenKind::RightCurly for a destructuring left-hand side
7381 *
7382 * finally nodes are TokenKind::LeftCurly statement lists.
7383 */
7384
7385 Node innerBlock;
7386 {
7387 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_TRY)) {
7388 return errorResult();
7389 }
7390
7391 uint32_t openedPos = pos().begin;
7392
7393 ParseContext::Statement stmt(pc_, StatementKind::Try);
7394 ParseContext::Scope scope(this);
7395 if (!scope.init(pc_)) {
7396 return errorResult();
7397 }
7398
7399 MOZ_TRY_VAR(innerBlock, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7400
7401 MOZ_TRY_VAR(innerBlock, finishLexicalScope(scope, innerBlock))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, innerBlock
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7402
7403 if (!mustMatchToken(
7404 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7405 this->reportMissingClosing(JSMSG_CURLY_AFTER_TRY,
7406 JSMSG_CURLY_OPENED, openedPos);
7407 })) {
7408 return errorResult();
7409 }
7410 }
7411
7412 LexicalScopeNodeType catchScope = null();
7413 TokenKind tt;
7414 if (!tokenStream.getToken(&tt)) {
7415 return errorResult();
7416 }
7417 if (tt == TokenKind::Catch) {
7418 /*
7419 * Create a lexical scope node around the whole catch clause,
7420 * including the head.
7421 */
7422 ParseContext::Statement stmt(pc_, StatementKind::Catch);
7423 ParseContext::Scope scope(this);
7424 if (!scope.init(pc_)) {
7425 return errorResult();
7426 }
7427
7428 /*
7429 * Legal catch forms are:
7430 * catch (lhs) {
7431 * catch {
7432 * where lhs is a name or a destructuring left-hand side.
7433 */
7434 bool omittedBinding;
7435 if (!tokenStream.matchToken(&omittedBinding, TokenKind::LeftCurly)) {
7436 return errorResult();
7437 }
7438
7439 Node catchName;
7440 if (omittedBinding) {
7441 catchName = null();
7442 } else {
7443 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_CATCH)) {
7444 return errorResult();
7445 }
7446
7447 if (!tokenStream.getToken(&tt)) {
7448 return errorResult();
7449 }
7450 switch (tt) {
7451 case TokenKind::LeftBracket:
7452 case TokenKind::LeftCurly:
7453 MOZ_TRY_VAR(catchName,do { auto mozTryVarTempResult_ = (destructuringDeclaration(DeclarationKind
::CatchParameter, yieldHandling, tt)); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7454 destructuringDeclaration(DeclarationKind::CatchParameter,do { auto mozTryVarTempResult_ = (destructuringDeclaration(DeclarationKind
::CatchParameter, yieldHandling, tt)); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7455 yieldHandling, tt))do { auto mozTryVarTempResult_ = (destructuringDeclaration(DeclarationKind
::CatchParameter, yieldHandling, tt)); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
;
7456 break;
7457
7458 default: {
7459 if (!TokenKindIsPossibleIdentifierName(tt)) {
7460 error(JSMSG_CATCH_IDENTIFIER);
7461 return errorResult();
7462 }
7463
7464 MOZ_TRY_VAR(catchName,do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7465 bindingIdentifier(DeclarationKind::SimpleCatchParameter,do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7466 yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
;
7467 break;
7468 }
7469 }
7470
7471 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_CATCH)) {
7472 return errorResult();
7473 }
7474
7475 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_CATCH)) {
7476 return errorResult();
7477 }
7478 }
7479
7480 LexicalScopeNodeType catchBody;
7481 MOZ_TRY_VAR(catchBody, catchBlockStatement(yieldHandling, scope))do { auto mozTryVarTempResult_ = (catchBlockStatement(yieldHandling
, scope)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (catchBody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7482
7483 MOZ_TRY_VAR(catchScope, finishLexicalScope(scope, catchBody))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, catchBody
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (catchScope
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7484
7485 if (!handler_.setupCatchScope(catchScope, catchName, catchBody)) {
7486 return errorResult();
7487 }
7488 handler_.setEndPosition(catchScope, pos().end);
7489
7490 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
7491 return errorResult();
7492 }
7493 }
7494
7495 Node finallyBlock = null();
7496
7497 if (tt == TokenKind::Finally) {
7498 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_FINALLY)) {
7499 return errorResult();
7500 }
7501
7502 uint32_t openedPos = pos().begin;
7503
7504 ParseContext::Statement stmt(pc_, StatementKind::Finally);
7505 ParseContext::Scope scope(this);
7506 if (!scope.init(pc_)) {
7507 return errorResult();
7508 }
7509
7510 MOZ_TRY_VAR(finallyBlock, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (finallyBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7511
7512 MOZ_TRY_VAR(finallyBlock, finishLexicalScope(scope, finallyBlock))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, finallyBlock
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (finallyBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7513
7514 if (!mustMatchToken(
7515 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7516 this->reportMissingClosing(JSMSG_CURLY_AFTER_FINALLY,
7517 JSMSG_CURLY_OPENED, openedPos);
7518 })) {
7519 return errorResult();
7520 }
7521 } else {
7522 anyChars.ungetToken();
7523 }
7524 if (!catchScope && !finallyBlock) {
7525 error(JSMSG_CATCH_OR_FINALLY);
7526 return errorResult();
7527 }
7528
7529 return handler_.newTryStatement(begin, innerBlock, catchScope, finallyBlock);
7530}
7531
7532template <class ParseHandler, typename Unit>
7533typename ParseHandler::LexicalScopeNodeResult
7534GeneralParser<ParseHandler, Unit>::catchBlockStatement(
7535 YieldHandling yieldHandling, ParseContext::Scope& catchParamScope) {
7536 uint32_t openedPos = pos().begin;
7537
7538 ParseContext::Statement stmt(pc_, StatementKind::Block);
7539
7540 // ES 13.15.7 CatchClauseEvaluation
7541 //
7542 // Step 8 means that the body of a catch block always has an additional
7543 // lexical scope.
7544 ParseContext::Scope scope(this);
7545 if (!scope.init(pc_)) {
7546 return errorResult();
7547 }
7548
7549 // The catch parameter names cannot be redeclared inside the catch
7550 // block, so declare the name in the inner scope.
7551 if (!scope.addCatchParameters(pc_, catchParamScope)) {
7552 return errorResult();
7553 }
7554
7555 ListNodeType list;
7556 MOZ_TRY_VAR(list, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (list) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7557
7558 if (!mustMatchToken(
7559 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7560 this->reportMissingClosing(JSMSG_CURLY_AFTER_CATCH,
7561 JSMSG_CURLY_OPENED, openedPos);
7562 })) {
7563 return errorResult();
7564 }
7565
7566 // The catch parameter names are not bound in the body scope, so remove
7567 // them before generating bindings.
7568 scope.removeCatchParameters(pc_, catchParamScope);
7569 return finishLexicalScope(scope, list);
7570}
7571
7572template <class ParseHandler, typename Unit>
7573typename ParseHandler::DebuggerStatementResult
7574GeneralParser<ParseHandler, Unit>::debuggerStatement() {
7575 TokenPos p;
7576 p.begin = pos().begin;
7577 if (!matchOrInsertSemicolon()) {
7578 return errorResult();
7579 }
7580 p.end = pos().end;
7581
7582 return handler_.newDebuggerStatement(p);
7583}
7584
7585static AccessorType ToAccessorType(PropertyType propType) {
7586 switch (propType) {
7587 case PropertyType::Getter:
7588 return AccessorType::Getter;
7589 case PropertyType::Setter:
7590 return AccessorType::Setter;
7591 case PropertyType::Normal:
7592 case PropertyType::Method:
7593 case PropertyType::GeneratorMethod:
7594 case PropertyType::AsyncMethod:
7595 case PropertyType::AsyncGeneratorMethod:
7596 case PropertyType::Constructor:
7597 case PropertyType::DerivedConstructor:
7598 return AccessorType::None;
7599 default:
7600 MOZ_CRASH("unexpected property type")do { do { } while (false); MOZ_ReportCrash("" "unexpected property type"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7600); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected property type"
")"); do { *((volatile int*)__null) = 7600; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
7601 }
7602}
7603
7604#ifdef ENABLE_DECORATORS
7605template <class ParseHandler, typename Unit>
7606typename ParseHandler::ListNodeResult
7607GeneralParser<ParseHandler, Unit>::decoratorList(YieldHandling yieldHandling) {
7608 ListNodeType decorators;
7609 MOZ_TRY_VAR(decorators,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::DecoratorList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decorators) = mozTryVarTempResult_.unwrap(); } while (0)
7610 handler_.newList(ParseNodeKind::DecoratorList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::DecoratorList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decorators) = mozTryVarTempResult_.unwrap(); } while (0)
;
7611
7612 // Build a decorator list element. At each entry point to this loop we have
7613 // already consumed the |@| token
7614 TokenKind tt;
7615 for (;;) {
7616 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
7617 return errorResult();
7618 }
7619
7620 Node decorator;
7621 MOZ_TRY_VAR(decorator, decoratorExpr(yieldHandling, tt))do { auto mozTryVarTempResult_ = (decoratorExpr(yieldHandling
, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()
), 0))) { return mozTryVarTempResult_.propagateErr(); } (decorator
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7622
7623 handler_.addList(decorators, decorator);
7624
7625 if (!tokenStream.getToken(&tt)) {
7626 return errorResult();
7627 }
7628 if (tt != TokenKind::At) {
7629 anyChars.ungetToken();
7630 break;
7631 }
7632 }
7633 return decorators;
7634}
7635#endif
7636
7637template <class ParseHandler, typename Unit>
7638bool GeneralParser<ParseHandler, Unit>::classMember(
7639 YieldHandling yieldHandling, const ParseContext::ClassStatement& classStmt,
7640 TaggedParserAtomIndex className, uint32_t classStartOffset,
7641 HasHeritage hasHeritage, ClassInitializedMembers& classInitializedMembers,
7642 ListNodeType& classMembers, bool* done) {
7643 *done = false;
7644
7645 TokenKind tt;
7646 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
1
Assuming the condition is false
2
Taking false branch
7647 return false;
7648 }
7649 if (tt == TokenKind::RightCurly) {
3
Assuming 'tt' is not equal to RightCurly
4
Taking false branch
7650 *done = true;
7651 return true;
7652 }
7653
7654 if (tt == TokenKind::Semi) {
5
Assuming 'tt' is not equal to Semi
6
Taking false branch
7655 return true;
7656 }
7657
7658#ifdef ENABLE_DECORATORS
7659 ListNodeType decorators = null();
7660 if (tt == TokenKind::At) {
7661 MOZ_TRY_VAR_OR_RETURN(decorators, decoratorList(yieldHandling), false)do { auto parserTryVarTempResult_ = (decoratorList(yieldHandling
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (decorators) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7662
7663 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
7664 return false;
7665 }
7666 }
7667#endif
7668
7669 bool isStatic = false;
7670 if (tt == TokenKind::Static) {
7
Assuming 'tt' is not equal to Static
8
Taking false branch
7671 if (!tokenStream.peekToken(&tt)) {
7672 return false;
7673 }
7674
7675 if (tt == TokenKind::LeftCurly) {
7676 /* Parsing static class block: static { ... } */
7677 FunctionNodeType staticBlockBody;
7678 MOZ_TRY_VAR_OR_RETURN(staticBlockBody,do { auto parserTryVarTempResult_ = (staticClassBlock(classInitializedMembers
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (staticBlockBody) = parserTryVarTempResult_
.unwrap(); } while (0)
7679 staticClassBlock(classInitializedMembers), false)do { auto parserTryVarTempResult_ = (staticClassBlock(classInitializedMembers
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (staticBlockBody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7680
7681 StaticClassBlockType classBlock;
7682 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newStaticClassBlock
(staticBlockBody)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (classBlock) = parserTryVarTempResult_
.unwrap(); } while (0)
7683 classBlock, handler_.newStaticClassBlock(staticBlockBody), false)do { auto parserTryVarTempResult_ = (handler_.newStaticClassBlock
(staticBlockBody)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (classBlock) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7684
7685 return handler_.addClassMemberDefinition(classMembers, classBlock);
7686 }
7687
7688 if (tt != TokenKind::LeftParen && tt != TokenKind::Assign &&
7689 tt != TokenKind::Semi && tt != TokenKind::RightCurly) {
7690 isStatic = true;
7691 } else {
7692 anyChars.ungetToken();
7693 }
7694 } else {
7695 anyChars.ungetToken();
7696 }
7697
7698 uint32_t propNameOffset;
7699 if (!tokenStream.peekOffset(&propNameOffset, TokenStream::SlashIsInvalid)) {
9
Taking false branch
7700 return false;
7701 }
7702
7703 TaggedParserAtomIndex propAtom;
7704 PropertyType propType;
7705 Node propName;
7706 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
10
Taking false branch
7707 propName,do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7708 propertyOrMethodName(yieldHandling, PropertyNameInClass,do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7709 /* maybeDecl = */ Nothing(), classMembers, &propType,do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7710 &propAtom),do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7711 false)do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7712
7713 if (propType
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 ||
7714 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) {
7715 if (isStatic) {
7716 if (propAtom == TaggedParserAtomIndex::WellKnown::prototype()) {
7717 errorAt(propNameOffset, JSMSG_CLASS_STATIC_PROTO);
7718 return false;
7719 }
7720 }
7721
7722 if (propAtom == TaggedParserAtomIndex::WellKnown::constructor()) {
7723 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7724 return false;
7725 }
7726
7727 if (handler_.isPrivateName(propName)) {
7728 if (propAtom == TaggedParserAtomIndex::WellKnown::hash_constructor_()) {
7729 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7730 return false;
7731 }
7732
7733 auto privateName = propAtom;
7734 if (!noteDeclaredPrivateName(
7735 propName, privateName, propType,
7736 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7737 pos())) {
7738 return false;
7739 }
7740 }
7741
7742#ifdef ENABLE_DECORATORS
7743 ClassMethodType accessorGetterNode = null();
7744 ClassMethodType accessorSetterNode = null();
7745 if (propType == PropertyType::FieldWithAccessor) {
7746 // Decorators Proposal
7747 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-runtime-semantics-classfielddefinitionevaluation
7748 //
7749 // FieldDefinition : accessor ClassElementName Initializeropt
7750 //
7751 // Step 1. Let name be the result of evaluating ClassElementName.
7752 // ...
7753 // Step 3. Let privateStateDesc be the string-concatenation of name
7754 // and " accessor storage".
7755 StringBuffer privateStateDesc(fc_);
7756 if (!privateStateDesc.append(this->parserAtoms(), propAtom)) {
7757 return false;
7758 }
7759 if (!privateStateDesc.append(" accessor storage")) {
7760 return false;
7761 }
7762 // Step 4. Let privateStateName be a new Private Name whose
7763 // [[Description]] value is privateStateDesc.
7764 TokenPos propNamePos(propNameOffset, pos().end);
7765 auto privateStateName =
7766 privateStateDesc.finishParserAtom(this->parserAtoms(), fc_);
7767 if (!noteDeclaredPrivateName(
7768 propName, privateStateName, propType,
7769 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7770 propNamePos)) {
7771 return false;
7772 }
7773
7774 // Step 5. Let getter be MakeAutoAccessorGetter(homeObject, name,
7775 // privateStateName).
7776 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7777 accessorGetterNode,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7778 synthesizeAccessor(propName, propNamePos, propAtom, privateStateName,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7779 isStatic, FunctionSyntaxKind::Getter,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7780 classInitializedMembers),do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7781 false)do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
;
7782
7783 // If the accessor is not decorated or is a non-static private field,
7784 // add it to the class here. Otherwise, we'll handle this when the
7785 // decorators are called. We don't need to keep a reference to the node
7786 // after this except for non-static private accessors. Please see the
7787 // comment in the definition of ClassField for details.
7788 bool addAccessorImmediately =
7789 !decorators || (!isStatic && handler_.isPrivateName(propName));
7790 if (addAccessorImmediately) {
7791 if (!handler_.addClassMemberDefinition(classMembers,
7792 accessorGetterNode)) {
7793 return false;
7794 }
7795 if (!handler_.isPrivateName(propName)) {
7796 accessorGetterNode = null();
7797 }
7798 }
7799
7800 // Step 6. Let setter be MakeAutoAccessorSetter(homeObject, name,
7801 // privateStateName).
7802 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7803 accessorSetterNode,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7804 synthesizeAccessor(propName, propNamePos, propAtom, privateStateName,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7805 isStatic, FunctionSyntaxKind::Setter,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7806 classInitializedMembers),do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7807 false)do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
;
7808
7809 if (addAccessorImmediately) {
7810 if (!handler_.addClassMemberDefinition(classMembers,
7811 accessorSetterNode)) {
7812 return false;
7813 }
7814 if (!handler_.isPrivateName(propName)) {
7815 accessorSetterNode = null();
7816 }
7817 }
7818
7819 // Step 10. Return ClassElementDefinition Record { [[Key]]: name,
7820 // [[Kind]]: accessor, [[Get]]: getter, [[Set]]: setter,
7821 // [[BackingStorageKey]]: privateStateName, [[Initializers]]:
7822 // initializers, [[Decorators]]: empty }.
7823 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newPrivateName(
privateStateName, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7824 propName, handler_.newPrivateName(privateStateName, pos()), false)do { auto parserTryVarTempResult_ = (handler_.newPrivateName(
privateStateName, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7825 propAtom = privateStateName;
7826 // We maintain `decorators` here to perform this step at the same time:
7827 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-static-semantics-classelementevaluation
7828 // 4. Set fieldDefinition.[[Decorators]] to decorators.
7829 }
7830#endif
7831 if (isStatic) {
7832 classInitializedMembers.staticFields++;
7833 } else {
7834 classInitializedMembers.instanceFields++;
7835#ifdef ENABLE_DECORATORS
7836 if (decorators) {
7837 classInitializedMembers.hasInstanceDecorators = true;
7838 }
7839#endif
7840 }
7841
7842 TokenPos propNamePos(propNameOffset, pos().end);
7843 FunctionNodeType initializer;
7844 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7845 initializer,do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7846 fieldInitializerOpt(propNamePos, propName, propAtom,do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7847 classInitializedMembers, isStatic, hasHeritage),do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7848 false)do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7849
7850 if (!matchOrInsertSemicolon(TokenStream::SlashIsInvalid)) {
7851 return false;
7852 }
7853
7854 ClassFieldType field;
7855 MOZ_TRY_VAR_OR_RETURN(field,do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7856 handler_.newClassFieldDefinition(do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7857 propName, initializer, isStaticdo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7858#ifdef ENABLE_DECORATORSdo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7859 ,do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7860 decorators, accessorGetterNode, accessorSetterNodedo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7861#endifdo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7862 ),do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7863 false)do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
;
7864
7865 return handler_.addClassMemberDefinition(classMembers, field);
7866 }
7867
7868 if (propType
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 &&
7869 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 &&
7870 propType != PropertyType::GeneratorMethod &&
7871 propType != PropertyType::AsyncMethod &&
7872 propType != PropertyType::AsyncGeneratorMethod) {
7873 errorAt(propNameOffset, JSMSG_BAD_CLASS_MEMBER_DEF);
7874 return false;
7875 }
7876
7877 bool isConstructor =
7878 !isStatic
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();
7879 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
) {
7880 if (propType != PropertyType::Method) {
7881 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7882 return false;
7883 }
7884 if (classStmt.constructorBox) {
7885 errorAt(propNameOffset, JSMSG_DUPLICATE_CONSTRUCTOR);
7886 return false;
7887 }
7888 propType = hasHeritage == HasHeritage::Yes
7889 ? PropertyType::DerivedConstructor
7890 : PropertyType::Constructor;
7891 } else if (isStatic
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
7892 propAtom == TaggedParserAtomIndex::WellKnown::prototype()) {
7893 errorAt(propNameOffset, JSMSG_CLASS_STATIC_PROTO);
7894 return false;
7895 }
7896
7897 TaggedParserAtomIndex funName;
7898 switch (propType) {
12
Control jumps to the 'default' case at line 7915
7899 case PropertyType::Getter:
7900 case PropertyType::Setter: {
7901 bool hasStaticName =
7902 !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom;
7903 if (hasStaticName) {
7904 funName = prefixAccessorName(propType, propAtom);
7905 if (!funName) {
7906 return false;
7907 }
7908 }
7909 break;
7910 }
7911 case PropertyType::Constructor:
7912 case PropertyType::DerivedConstructor:
7913 funName = className;
7914 break;
7915 default:
7916 if (!anyChars.isCurrentTokenType(TokenKind::RightBracket)) {
13
Taking false branch
7917 funName = propAtom;
7918 }
7919 }
7920
7921 // When |super()| is invoked, we search for the nearest scope containing
7922 // |.initializers| to initialize the class fields. This set-up precludes
7923 // declaring |.initializers| in the class scope, because in some syntactic
7924 // contexts |super()| can appear nested in a class, while actually belonging
7925 // to an outer class definition.
7926 //
7927 // Example:
7928 // class Outer extends Base {
7929 // field = 1;
7930 // constructor() {
7931 // class Inner {
7932 // field = 2;
7933 //
7934 // // The super() call in the computed property name mustn't access
7935 // // Inner's |.initializers| array, but instead Outer's.
7936 // [super()]() {}
7937 // }
7938 // }
7939 // }
7940 Maybe<ParseContext::Scope> dotInitializersScope;
7941 if (isConstructor
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) {
7942 dotInitializersScope.emplace(this);
7943 if (!dotInitializersScope->init(pc_)) {
7944 return false;
7945 }
7946
7947 if (!noteDeclaredName(TaggedParserAtomIndex::WellKnown::dot_initializers_(),
7948 DeclarationKind::Let, pos())) {
7949 return false;
7950 }
7951
7952#ifdef ENABLE_DECORATORS
7953 if (!noteDeclaredName(
7954 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
7955 DeclarationKind::Let, pos())) {
7956 return false;
7957 }
7958#endif
7959 }
7960
7961 // Calling toString on constructors need to return the source text for
7962 // the entire class. The end offset is unknown at this point in
7963 // parsing and will be amended when class parsing finishes below.
7964 FunctionNodeType funNode;
7965 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
14
'?' condition is false
15
Taking true branch
16
Calling implicit destructor for 'Maybe<js::frontend::ParseContext::Scope>'
17
Calling '~MaybeStorage'
7966 funNode,do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7967 methodDefinition(isConstructor ? classStartOffset : propNameOffset,do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7968 propType, funName),do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7969 false)do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
;
7970
7971 AccessorType atype = ToAccessorType(propType);
7972
7973 Maybe<FunctionNodeType> initializerIfPrivate = Nothing();
7974 if (handler_.isPrivateName(propName)) {
7975 if (propAtom == TaggedParserAtomIndex::WellKnown::hash_constructor_()) {
7976 // #constructor is an invalid private name.
7977 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7978 return false;
7979 }
7980
7981 TaggedParserAtomIndex privateName = propAtom;
7982 if (!noteDeclaredPrivateName(
7983 propName, privateName, propType,
7984 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7985 pos())) {
7986 return false;
7987 }
7988
7989 // Private non-static methods are stored in the class body environment.
7990 // Private non-static accessors are stamped onto every instance using
7991 // initializers. Private static methods are stamped onto the constructor
7992 // during class evaluation; see BytecodeEmitter::emitPropertyList.
7993 if (!isStatic) {
7994 if (atype == AccessorType::Getter || atype == AccessorType::Setter) {
7995 classInitializedMembers.privateAccessors++;
7996 TokenPos propNamePos(propNameOffset, pos().end);
7997 FunctionNodeType initializerNode;
7998 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
7999 initializerNode,do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8000 synthesizePrivateMethodInitializer(propAtom, atype, propNamePos),do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8001 false)do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8002 initializerIfPrivate = Some(initializerNode);
8003 } else {
8004 MOZ_ASSERT(atype == AccessorType::None)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(atype == AccessorType::None)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(atype == AccessorType::None)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("atype == AccessorType::None"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8004); AnnotateMozCrashReason("MOZ_ASSERT" "(" "atype == AccessorType::None"
")"); do { *((volatile int*)__null) = 8004; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8005 classInitializedMembers.privateMethods++;
8006 }
8007 }
8008 }
8009
8010#ifdef ENABLE_DECORATORS
8011 if (decorators) {
8012 classInitializedMembers.hasInstanceDecorators = true;
8013 }
8014#endif
8015
8016 Node method;
8017 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8018 method,do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8019 handler_.newClassMethodDefinition(propName, funNode, atype, isStatic,do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8020 initializerIfPrivatedo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8021#ifdef ENABLE_DECORATORSdo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8022 ,do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8023 decoratorsdo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8024#endifdo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8025 ),do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8026 false)do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
;
8027
8028 if (dotInitializersScope.isSome()) {
8029 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(*dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (method) = parserTryVarTempResult_
.unwrap(); } while (0)
8030 method, finishLexicalScope(*dotInitializersScope, method), false)do { auto parserTryVarTempResult_ = (finishLexicalScope(*dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (method) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8031 dotInitializersScope.reset();
8032 }
8033
8034 return handler_.addClassMemberDefinition(classMembers, method);
8035}
8036
8037template <class ParseHandler, typename Unit>
8038bool GeneralParser<ParseHandler, Unit>::finishClassConstructor(
8039 const ParseContext::ClassStatement& classStmt,
8040 TaggedParserAtomIndex className, HasHeritage hasHeritage,
8041 uint32_t classStartOffset, uint32_t classEndOffset,
8042 const ClassInitializedMembers& classInitializedMembers,
8043 ListNodeType& classMembers) {
8044 if (classStmt.constructorBox == nullptr) {
8045 MOZ_ASSERT(!options().selfHostingMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!options().selfHostingMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!options().selfHostingMode))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!options().selfHostingMode"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8045); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 8045; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8046 // Unconditionally create the scope here, because it's always the
8047 // constructor.
8048 ParseContext::Scope dotInitializersScope(this);
8049 if (!dotInitializersScope.init(pc_)) {
8050 return false;
8051 }
8052
8053 if (!noteDeclaredName(TaggedParserAtomIndex::WellKnown::dot_initializers_(),
8054 DeclarationKind::Let, pos())) {
8055 return false;
8056 }
8057
8058#ifdef ENABLE_DECORATORS
8059 if (!noteDeclaredName(
8060 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
8061 DeclarationKind::Let, pos(), ClosedOver::Yes)) {
8062 return false;
8063 }
8064#endif
8065
8066 // synthesizeConstructor assigns to classStmt.constructorBox
8067 TokenPos synthesizedBodyPos(classStartOffset, classEndOffset);
8068 FunctionNodeType synthesizedCtor;
8069 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8070 synthesizedCtor,do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8071 synthesizeConstructor(className, synthesizedBodyPos, hasHeritage),do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8072 false)do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
;
8073
8074 // Note: the *function* has the name of the class, but the *property*
8075 // containing the function has the name "constructor"
8076 Node constructorNameNode;
8077 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8078 constructorNameNode,do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8079 handler_.newObjectLiteralPropertyName(do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8080 TaggedParserAtomIndex::WellKnown::constructor(), pos()),do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8081 false)do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8082 ClassMethodType method;
8083 MOZ_TRY_VAR_OR_RETURN(method,do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8084 handler_.newDefaultClassConstructor(do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8085 constructorNameNode, synthesizedCtor),do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8086 false)do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
;
8087 LexicalScopeNodeType scope;
8088 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (scope) = parserTryVarTempResult_
.unwrap(); } while (0)
8089 scope, finishLexicalScope(dotInitializersScope, method), false)do { auto parserTryVarTempResult_ = (finishLexicalScope(dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (scope) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8090 if (!handler_.addClassMemberDefinition(classMembers, scope)) {
8091 return false;
8092 }
8093 }
8094
8095 MOZ_ASSERT(classStmt.constructorBox)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(classStmt.constructorBox)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(classStmt.constructorBox))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("classStmt.constructorBox"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8095); AnnotateMozCrashReason("MOZ_ASSERT" "(" "classStmt.constructorBox"
")"); do { *((volatile int*)__null) = 8095; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8096 FunctionBox* ctorbox = classStmt.constructorBox;
8097
8098 // Amend the toStringEnd offset for the constructor now that we've
8099 // finished parsing the class.
8100 ctorbox->setCtorToStringEnd(classEndOffset);
8101
8102 size_t numMemberInitializers = classInitializedMembers.privateAccessors +
8103 classInitializedMembers.instanceFields;
8104 bool hasPrivateBrand = classInitializedMembers.hasPrivateBrand();
8105 if (hasPrivateBrand || numMemberInitializers > 0) {
8106 // Now that we have full set of initializers, update the constructor.
8107 MemberInitializers initializers(
8108 hasPrivateBrand,
8109#ifdef ENABLE_DECORATORS
8110 classInitializedMembers.hasInstanceDecorators,
8111#endif
8112 numMemberInitializers);
8113 ctorbox->setMemberInitializers(initializers);
8114
8115 // Field initialization need access to `this`.
8116 ctorbox->setCtorFunctionHasThisBinding();
8117 }
8118
8119 return true;
8120}
8121
8122template <class ParseHandler, typename Unit>
8123typename ParseHandler::ClassNodeResult
8124GeneralParser<ParseHandler, Unit>::classDefinition(
8125 YieldHandling yieldHandling, ClassContext classContext,
8126 DefaultHandling defaultHandling) {
8127#ifdef ENABLE_DECORATORS
8128 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::At) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::At) || anyChars
.isCurrentTokenType(TokenKind::Class))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
8129 anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::At) || anyChars
.isCurrentTokenType(TokenKind::Class))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8130
8131 ListNodeType decorators = null();
8132 FunctionNodeType addInitializerFunction = null();
8133 if (anyChars.isCurrentTokenType(TokenKind::At)) {
8134 MOZ_TRY_VAR(decorators, decoratorList(yieldHandling))do { auto mozTryVarTempResult_ = (decoratorList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (decorators
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8135 TokenKind next;
8136 if (!tokenStream.getToken(&next)) {
8137 return errorResult();
8138 }
8139 if (next != TokenKind::Class) {
8140 error(JSMSG_CLASS_EXPECTED);
8141 return errorResult();
8142 }
8143 }
8144#else
8145 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Class))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Class)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8145); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8145; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8146#endif
8147
8148 uint32_t classStartOffset = pos().begin;
8149 bool savedStrictness = setLocalStrictMode(true);
8150
8151 // Classes are quite broken in self-hosted code.
8152 if (options().selfHostingMode) {
8153 error(JSMSG_SELFHOSTED_CLASS);
8154 return errorResult();
8155 }
8156
8157 TokenKind tt;
8158 if (!tokenStream.getToken(&tt)) {
8159 return errorResult();
8160 }
8161
8162 TaggedParserAtomIndex className;
8163 if (TokenKindIsPossibleIdentifier(tt)) {
8164 className = bindingIdentifier(yieldHandling);
8165 if (!className) {
8166 return errorResult();
8167 }
8168 } else if (classContext == ClassStatement) {
8169 if (defaultHandling == AllowDefaultName) {
8170 className = TaggedParserAtomIndex::WellKnown::default_();
8171 anyChars.ungetToken();
8172 } else {
8173 // Class statements must have a bound name
8174 error(JSMSG_UNNAMED_CLASS_STMT);
8175 return errorResult();
8176 }
8177 } else {
8178 // Make sure to put it back, whatever it was
8179 anyChars.ungetToken();
8180 }
8181
8182 // Because the binding definitions keep track of their blockId, we need to
8183 // create at least the inner binding later. Keep track of the name's
8184 // position in order to provide it for the nodes created later.
8185 TokenPos namePos = pos();
8186
8187 auto isClass = [](ParseContext::Statement* stmt) {
8188 return stmt->kind() == StatementKind::Class;
8189 };
8190
8191 bool isInClass = pc_->sc()->inClass() || pc_->findInnermostStatement(isClass);
8192
8193 // Push a ParseContext::ClassStatement to keep track of the constructor
8194 // funbox.
8195 ParseContext::ClassStatement classStmt(pc_);
8196
8197 NameNodeType innerName;
8198 Node nameNode = null();
8199 Node classHeritage = null();
8200 LexicalScopeNodeType classBlock = null();
8201 ClassBodyScopeNodeType classBodyBlock = null();
8202 uint32_t classEndOffset;
8203 {
8204 // A named class creates a new lexical scope with a const binding of the
8205 // class name for the "inner name".
8206 ParseContext::Statement innerScopeStmt(pc_, StatementKind::Block);
8207 ParseContext::Scope innerScope(this);
8208 if (!innerScope.init(pc_)) {
8209 return errorResult();
8210 }
8211
8212 bool hasHeritageBool;
8213 if (!tokenStream.matchToken(&hasHeritageBool, TokenKind::Extends)) {
8214 return errorResult();
8215 }
8216 HasHeritage hasHeritage =
8217 hasHeritageBool ? HasHeritage::Yes : HasHeritage::No;
8218 if (hasHeritage == HasHeritage::Yes) {
8219 if (!tokenStream.getToken(&tt)) {
8220 return errorResult();
8221 }
8222 MOZ_TRY_VAR(classHeritage,do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classHeritage) = mozTryVarTempResult_.unwrap(); } while (
0)
8223 optionalExpr(yieldHandling, TripledotProhibited, tt))do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classHeritage) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8224 }
8225
8226 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_CLASS)) {
8227 return errorResult();
8228 }
8229
8230 {
8231 ParseContext::Statement bodyScopeStmt(pc_, StatementKind::Block);
8232 ParseContext::Scope bodyScope(this);
8233 if (!bodyScope.init(pc_)) {
8234 return errorResult();
8235 }
8236
8237 ListNodeType classMembers;
8238 MOZ_TRY_VAR(classMembers, handler_.newClassMemberList(pos().begin))do { auto mozTryVarTempResult_ = (handler_.newClassMemberList
(pos().begin)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classMembers) = mozTryVarTempResult_.unwrap(); } while (0
)
;
8239
8240 ClassInitializedMembers classInitializedMembers{};
8241 for (;;) {
8242 bool done;
8243 if (!classMember(yieldHandling, classStmt, className, classStartOffset,
8244 hasHeritage, classInitializedMembers, classMembers,
8245 &done)) {
8246 return errorResult();
8247 }
8248 if (done) {
8249 break;
8250 }
8251 }
8252#ifdef ENABLE_DECORATORS
8253 if (classInitializedMembers.hasInstanceDecorators) {
8254 MOZ_TRY_VAR(addInitializerFunction,do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8255 synthesizeAddInitializerFunction(do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8256 TaggedParserAtomIndex::WellKnown::do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8257 dot_instanceExtraInitializers_(),do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8258 yieldHandling))do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
;
8259 }
8260#endif
8261
8262 if (classInitializedMembers.privateMethods +
8263 classInitializedMembers.privateAccessors >
8264 0) {
8265 // We declare `.privateBrand` as ClosedOver because the constructor
8266 // always uses it, even a default constructor. We could equivalently
8267 // `noteUsedName` when parsing the constructor, except that at that
8268 // time, we don't necessarily know if the class has a private brand.
8269 if (!noteDeclaredName(
8270 TaggedParserAtomIndex::WellKnown::dot_privateBrand_(),
8271 DeclarationKind::Synthetic, namePos, ClosedOver::Yes)) {
8272 return errorResult();
8273 }
8274 }
8275
8276 if (classInitializedMembers.instanceFieldKeys > 0) {
8277 if (!noteDeclaredName(
8278 TaggedParserAtomIndex::WellKnown::dot_fieldKeys_(),
8279 DeclarationKind::Synthetic, namePos)) {
8280 return errorResult();
8281 }
8282 }
8283
8284 if (classInitializedMembers.staticFields > 0) {
8285 if (!noteDeclaredName(
8286 TaggedParserAtomIndex::WellKnown::dot_staticInitializers_(),
8287 DeclarationKind::Synthetic, namePos)) {
8288 return errorResult();
8289 }
8290 }
8291
8292 if (classInitializedMembers.staticFieldKeys > 0) {
8293 if (!noteDeclaredName(
8294 TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_(),
8295 DeclarationKind::Synthetic, namePos)) {
8296 return errorResult();
8297 }
8298 }
8299
8300 classEndOffset = pos().end;
8301 if (!finishClassConstructor(classStmt, className, hasHeritage,
8302 classStartOffset, classEndOffset,
8303 classInitializedMembers, classMembers)) {
8304 return errorResult();
8305 }
8306
8307 MOZ_TRY_VAR(classBodyBlock,do { auto mozTryVarTempResult_ = (finishClassBodyScope(bodyScope
, classMembers)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBodyBlock) = mozTryVarTempResult_.unwrap(); } while (
0)
8308 finishClassBodyScope(bodyScope, classMembers))do { auto mozTryVarTempResult_ = (finishClassBodyScope(bodyScope
, classMembers)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBodyBlock) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8309
8310 // Pop the class body scope
8311 }
8312
8313 if (className) {
8314 // The inner name is immutable.
8315 if (!noteDeclaredName(className, DeclarationKind::Const, namePos)) {
8316 return errorResult();
8317 }
8318
8319 MOZ_TRY_VAR(innerName, newName(className, namePos))do { auto mozTryVarTempResult_ = (newName(className, namePos)
); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)
)) { return mozTryVarTempResult_.propagateErr(); } (innerName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8320 }
8321
8322 MOZ_TRY_VAR(classBlock, finishLexicalScope(innerScope, classBodyBlock))do { auto mozTryVarTempResult_ = (finishLexicalScope(innerScope
, classBodyBlock)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBlock) = mozTryVarTempResult_.unwrap(); } while (0)
;
8323
8324 // Pop the inner scope.
8325 }
8326
8327 if (className) {
8328 NameNodeType outerName = null();
8329 if (classContext == ClassStatement) {
8330 // The outer name is mutable.
8331 if (!noteDeclaredName(className, DeclarationKind::Class, namePos)) {
8332 return errorResult();
8333 }
8334
8335 MOZ_TRY_VAR(outerName, newName(className, namePos))do { auto mozTryVarTempResult_ = (newName(className, namePos)
); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)
)) { return mozTryVarTempResult_.propagateErr(); } (outerName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8336 }
8337
8338 MOZ_TRY_VAR(nameNode,do { auto mozTryVarTempResult_ = (handler_.newClassNames(outerName
, innerName, namePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nameNode) = mozTryVarTempResult_.unwrap(); } while (0)
8339 handler_.newClassNames(outerName, innerName, namePos))do { auto mozTryVarTempResult_ = (handler_.newClassNames(outerName
, innerName, namePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nameNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8340 }
8341 MOZ_ALWAYS_TRUE(setLocalStrictMode(savedStrictness))do { if ((__builtin_expect(!!(setLocalStrictMode(savedStrictness
)), 1))) { } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "setLocalStrictMode(savedStrictness)"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8341); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "setLocalStrictMode(savedStrictness)" ")"); do { *((volatile
int*)__null) = 8341; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false); } } while (false)
;
8342 // We're leaving a class definition that was not itself nested within a class
8343 if (!isInClass) {
8344 mozilla::Maybe<UnboundPrivateName> maybeUnboundName;
8345 if (!usedNames_.hasUnboundPrivateNames(fc_, maybeUnboundName)) {
8346 return errorResult();
8347 }
8348 if (maybeUnboundName) {
8349 UniqueChars str =
8350 this->parserAtoms().toPrintableString(maybeUnboundName->atom);
8351 if (!str) {
8352 ReportOutOfMemory(this->fc_);
8353 return errorResult();
8354 }
8355
8356 errorAt(maybeUnboundName->position.begin, JSMSG_MISSING_PRIVATE_DECL,
8357 str.get());
8358 return errorResult();
8359 }
8360 }
8361
8362 return handler_.newClass(nameNode, classHeritage, classBlock,
8363#ifdef ENABLE_DECORATORS
8364 decorators, addInitializerFunction,
8365#endif
8366 TokenPos(classStartOffset, classEndOffset));
8367}
8368
8369template <class ParseHandler, typename Unit>
8370typename ParseHandler::FunctionNodeResult
8371GeneralParser<ParseHandler, Unit>::synthesizeConstructor(
8372 TaggedParserAtomIndex className, TokenPos synthesizedBodyPos,
8373 HasHeritage hasHeritage) {
8374 FunctionSyntaxKind functionSyntaxKind =
8375 hasHeritage == HasHeritage::Yes
8376 ? FunctionSyntaxKind::DerivedClassConstructor
8377 : FunctionSyntaxKind::ClassConstructor;
8378
8379 bool isSelfHosting = options().selfHostingMode;
8380 FunctionFlags flags =
8381 InitialFunctionFlags(functionSyntaxKind, GeneratorKind::NotGenerator,
8382 FunctionAsyncKind::SyncFunction, isSelfHosting);
8383
8384 // Create the top-level field initializer node.
8385 FunctionNodeType funNode;
8386 MOZ_TRY_VAR(funNode,do { auto mozTryVarTempResult_ = (handler_.newFunction(functionSyntaxKind
, synthesizedBodyPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
8387 handler_.newFunction(functionSyntaxKind, synthesizedBodyPos))do { auto mozTryVarTempResult_ = (handler_.newFunction(functionSyntaxKind
, synthesizedBodyPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8388
8389 // If we see any inner function, note it on our current context. The bytecode
8390 // emitter may eliminate the function later, but we use a conservative
8391 // definition for consistency between lazy and full parsing.
8392 pc_->sc()->setHasInnerFunctions();
8393
8394 // When fully parsing a lazy script, we do not fully reparse its inner
8395 // functions, which are also lazy. Instead, their free variables and source
8396 // extents are recorded and may be skipped.
8397 if (handler_.reuseLazyInnerFunctions()) {
8398 if (!skipLazyInnerFunction(funNode, synthesizedBodyPos.begin,
8399 /* tryAnnexB = */ false)) {
8400 return errorResult();
8401 }
8402
8403 return funNode;
8404 }
8405
8406 // Create the FunctionBox and link it to the function object.
8407 Directives directives(true);
8408 FunctionBox* funbox = newFunctionBox(
8409 funNode, className, flags, synthesizedBodyPos.begin, directives,
8410 GeneratorKind::NotGenerator, FunctionAsyncKind::SyncFunction);
8411 if (!funbox) {
8412 return errorResult();
8413 }
8414 funbox->initWithEnclosingParseContext(pc_, functionSyntaxKind);
8415 setFunctionEndFromCurrentToken(funbox);
8416
8417 // Mark this function as being synthesized by the parser. This means special
8418 // handling in delazification will be used since we don't have typical
8419 // function syntax.
8420 funbox->setSyntheticFunction();
8421
8422 // Push a SourceParseContext on to the stack.
8423 ParseContext* outerpc = pc_;
8424 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8425 if (!funpc.init()) {
8426 return errorResult();
8427 }
8428
8429 if (!synthesizeConstructorBody(synthesizedBodyPos, hasHeritage, funNode,
8430 funbox)) {
8431 return errorResult();
8432 }
8433
8434 if (!leaveInnerFunction(outerpc)) {
8435 return errorResult();
8436 }
8437
8438 return funNode;
8439}
8440
8441template <class ParseHandler, typename Unit>
8442bool GeneralParser<ParseHandler, Unit>::synthesizeConstructorBody(
8443 TokenPos synthesizedBodyPos, HasHeritage hasHeritage,
8444 FunctionNodeType funNode, FunctionBox* funbox) {
8445 MOZ_ASSERT(funbox->isClassConstructor())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isClassConstructor())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isClassConstructor
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isClassConstructor()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8445); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isClassConstructor()"
")"); do { *((volatile int*)__null) = 8445; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8446
8447 // Create a ParamsBodyNode for the parameters + body (there are no
8448 // parameters).
8449 ParamsBodyNodeType argsbody;
8450 MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(synthesizedBodyPos),do { auto parserTryVarTempResult_ = (handler_.newParamsBody(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
8451 false)do { auto parserTryVarTempResult_ = (handler_.newParamsBody(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8452 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8453 setFunctionStartAtPosition(funbox, synthesizedBodyPos);
8454
8455 if (hasHeritage == HasHeritage::Yes) {
8456 // Synthesize the equivalent to `function f(...args)`
8457 funbox->setHasRest();
8458 if (!notePositionalFormalParameter(
8459 funNode, TaggedParserAtomIndex::WellKnown::dot_args_(),
8460 synthesizedBodyPos.begin,
8461 /* disallowDuplicateParams = */ false,
8462 /* duplicatedParam = */ nullptr)) {
8463 return false;
8464 }
8465 funbox->setArgCount(1);
8466 } else {
8467 funbox->setArgCount(0);
8468 }
8469
8470 pc_->functionScope().useAsVarScope(pc_);
8471
8472 ListNodeType stmtList;
8473 MOZ_TRY_VAR_OR_RETURN(stmtList, handler_.newStatementList(synthesizedBodyPos),do { auto parserTryVarTempResult_ = (handler_.newStatementList
(synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (stmtList) = parserTryVarTempResult_
.unwrap(); } while (0)
8474 false)do { auto parserTryVarTempResult_ = (handler_.newStatementList
(synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (stmtList) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8475
8476 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_this_())) {
8477 return false;
8478 }
8479
8480 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
8481 return false;
8482 }
8483
8484#ifdef ENABLE_DECORATORS
8485 if (!noteUsedName(
8486 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_())) {
8487 return false;
8488 }
8489#endif
8490
8491 if (hasHeritage == HasHeritage::Yes) {
8492 // |super()| implicitly reads |new.target|.
8493 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
8494 return false;
8495 }
8496
8497 NameNodeType thisName;
8498 MOZ_TRY_VAR_OR_RETURN(thisName, newThisName(), false)do { auto parserTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(thisName) = parserTryVarTempResult_.unwrap(); } while (0)
;
8499
8500 UnaryNodeType superBase;
8501 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newSuperBase(thisName
, synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superBase) = parserTryVarTempResult_
.unwrap(); } while (0)
8502 superBase, handler_.newSuperBase(thisName, synthesizedBodyPos), false)do { auto parserTryVarTempResult_ = (handler_.newSuperBase(thisName
, synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superBase) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8503
8504 ListNodeType arguments;
8505 MOZ_TRY_VAR_OR_RETURN(arguments, handler_.newArguments(synthesizedBodyPos),do { auto parserTryVarTempResult_ = (handler_.newArguments(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (arguments) = parserTryVarTempResult_
.unwrap(); } while (0)
8506 false)do { auto parserTryVarTempResult_ = (handler_.newArguments(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (arguments) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8507
8508 NameNodeType argsNameNode;
8509 MOZ_TRY_VAR_OR_RETURN(argsNameNode,do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
8510 newName(TaggedParserAtomIndex::WellKnown::dot_args_(),do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
8511 synthesizedBodyPos),do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
8512 false)do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
;
8513 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_args_())) {
8514 return false;
8515 }
8516
8517 UnaryNodeType spreadArgs;
8518 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newSpread(synthesizedBodyPos
.begin, argsNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (spreadArgs) = parserTryVarTempResult_
.unwrap(); } while (0)
8519 spreadArgs, handler_.newSpread(synthesizedBodyPos.begin, argsNameNode),do { auto parserTryVarTempResult_ = (handler_.newSpread(synthesizedBodyPos
.begin, argsNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (spreadArgs) = parserTryVarTempResult_
.unwrap(); } while (0)
8520 false)do { auto parserTryVarTempResult_ = (handler_.newSpread(synthesizedBodyPos
.begin, argsNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (spreadArgs) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8521 handler_.addList(arguments, spreadArgs);
8522
8523 CallNodeType superCall;
8524 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
8525 superCall,do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
8526 handler_.newSuperCall(superBase, arguments, /* isSpread = */ true),do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
8527 false)do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8528
8529 BinaryNodeType setThis;
8530 MOZ_TRY_VAR_OR_RETURN(setThis, handler_.newSetThis(thisName, superCall),do { auto parserTryVarTempResult_ = (handler_.newSetThis(thisName
, superCall)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (setThis) = parserTryVarTempResult_
.unwrap(); } while (0)
8531 false)do { auto parserTryVarTempResult_ = (handler_.newSetThis(thisName
, superCall)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (setThis) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8532
8533 UnaryNodeType exprStatement;
8534 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newExprStatement
(setThis, synthesizedBodyPos.end)); if ((__builtin_expect(!!(
parserTryVarTempResult_.isErr()), 0))) { return (false); } (exprStatement
) = parserTryVarTempResult_.unwrap(); } while (0)
8535 exprStatement,do { auto parserTryVarTempResult_ = (handler_.newExprStatement
(setThis, synthesizedBodyPos.end)); if ((__builtin_expect(!!(
parserTryVarTempResult_.isErr()), 0))) { return (false); } (exprStatement
) = parserTryVarTempResult_.unwrap(); } while (0)
8536 handler_.newExprStatement(setThis, synthesizedBodyPos.end), false)do { auto parserTryVarTempResult_ = (handler_.newExprStatement
(setThis, synthesizedBodyPos.end)); if ((__builtin_expect(!!(
parserTryVarTempResult_.isErr()), 0))) { return (false); } (exprStatement
) = parserTryVarTempResult_.unwrap(); } while (0)
;
8537
8538 handler_.addStatementToList(stmtList, exprStatement);
8539 }
8540
8541 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8542 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8543 return false;
8544 }
8545 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8546 return false;
8547 }
8548
8549 LexicalScopeNodeType initializerBody;
8550 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
8551 initializerBody,do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
8552 finishLexicalScope(pc_->varScope(), stmtList, ScopeKind::FunctionLexical),do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
8553 false)do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
;
8554 handler_.setBeginPosition(initializerBody, stmtList);
8555 handler_.setEndPosition(initializerBody, stmtList);
8556
8557 handler_.setFunctionBody(funNode, initializerBody);
8558
8559 return finishFunction();
8560}
8561
8562template <class ParseHandler, typename Unit>
8563typename ParseHandler::FunctionNodeResult
8564GeneralParser<ParseHandler, Unit>::privateMethodInitializer(
8565 TokenPos propNamePos, TaggedParserAtomIndex propAtom,
8566 TaggedParserAtomIndex storedMethodAtom) {
8567 if (!abortIfSyntaxParser()) {
8568 return errorResult();
8569 }
8570
8571 // Synthesize an initializer function that the constructor can use to stamp a
8572 // private method onto an instance object.
8573 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer;
8574 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8575 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8576 bool isSelfHosting = options().selfHostingMode;
8577 FunctionFlags flags =
8578 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8579
8580 FunctionNodeType funNode;
8581 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8582
8583 Directives directives(true);
8584 FunctionBox* funbox =
8585 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
8586 propNamePos.begin, directives, generatorKind, asyncKind);
8587 if (!funbox) {
8588 return errorResult();
8589 }
8590 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8591
8592 // Push a SourceParseContext on to the stack.
8593 ParseContext* outerpc = pc_;
8594 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8595 if (!funpc.init()) {
8596 return errorResult();
8597 }
8598 pc_->functionScope().useAsVarScope(pc_);
8599
8600 // Add empty parameter list.
8601 ParamsBodyNodeType argsbody;
8602 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8603 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8604 setFunctionStartAtCurrentToken(funbox);
8605 funbox->setArgCount(0);
8606
8607 // Note both the stored private method body and it's private name as being
8608 // used in the initializer. They will be emitted into the method body in the
8609 // BCE.
8610 if (!noteUsedName(storedMethodAtom)) {
8611 return errorResult();
8612 }
8613 MOZ_TRY(privateNameReference(propAtom))do { auto mozTryTempResult_ = ::mozilla::ToResult(privateNameReference
(propAtom)); if ((__builtin_expect(!!(mozTryTempResult_.isErr
()), 0))) { return mozTryTempResult_.propagateErr(); } } while
(0)
;
8614
8615 // Unlike field initializers, private method initializers are not created with
8616 // a body of synthesized AST nodes. Instead, the body is left empty and the
8617 // initializer is synthesized at the bytecode level.
8618 // See BytecodeEmitter::emitPrivateMethodInitializer.
8619 ListNodeType stmtList;
8620 MOZ_TRY_VAR(stmtList, handler_.newStatementList(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8621
8622 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8623 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8624 return errorResult();
8625 }
8626 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8627 return errorResult();
8628 }
8629
8630 LexicalScopeNodeType initializerBody;
8631 MOZ_TRY_VAR(initializerBody, finishLexicalScope(pc_->varScope(), stmtList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerBody) = mozTryVarTempResult_.unwrap
(); } while (0)
8632 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerBody) = mozTryVarTempResult_.unwrap
(); } while (0)
;
8633 handler_.setBeginPosition(initializerBody, stmtList);
8634 handler_.setEndPosition(initializerBody, stmtList);
8635 handler_.setFunctionBody(funNode, initializerBody);
8636
8637 // Set field-initializer lambda boundary to start at property name and end
8638 // after method body.
8639 setFunctionStartAtPosition(funbox, propNamePos);
8640 setFunctionEndFromCurrentToken(funbox);
8641
8642 if (!finishFunction()) {
8643 return errorResult();
8644 }
8645
8646 if (!leaveInnerFunction(outerpc)) {
8647 return errorResult();
8648 }
8649
8650 return funNode;
8651}
8652
8653template <class ParseHandler, typename Unit>
8654typename ParseHandler::FunctionNodeResult
8655GeneralParser<ParseHandler, Unit>::staticClassBlock(
8656 ClassInitializedMembers& classInitializedMembers) {
8657 // Both for getting-this-done, and because this will invariably be executed,
8658 // syntax parsing should be aborted.
8659 if (!abortIfSyntaxParser()) {
8660 return errorResult();
8661 }
8662
8663 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::StaticClassBlock;
8664 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8665 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8666 bool isSelfHosting = options().selfHostingMode;
8667 FunctionFlags flags =
8668 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8669
8670 AutoAwaitIsKeyword awaitIsKeyword(this, AwaitHandling::AwaitIsDisallowed);
8671
8672 // Create the function node for the static class body.
8673 FunctionNodeType funNode;
8674 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8675
8676 // Create the FunctionBox and link it to the function object.
8677 Directives directives(true);
8678 FunctionBox* funbox =
8679 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags, pos().begin,
8680 directives, generatorKind, asyncKind);
8681 if (!funbox) {
8682 return errorResult();
8683 }
8684 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8685 MOZ_ASSERT(funbox->isSyntheticFunction())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isSyntheticFunction())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isSyntheticFunction
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isSyntheticFunction()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8685); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isSyntheticFunction()"
")"); do { *((volatile int*)__null) = 8685; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8686 MOZ_ASSERT(!funbox->allowSuperCall())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!funbox->allowSuperCall())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!funbox->allowSuperCall()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!funbox->allowSuperCall()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8686); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowSuperCall()"
")"); do { *((volatile int*)__null) = 8686; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8687 MOZ_ASSERT(!funbox->allowArguments())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!funbox->allowArguments())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!funbox->allowArguments()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!funbox->allowArguments()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8687); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowArguments()"
")"); do { *((volatile int*)__null) = 8687; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8688 MOZ_ASSERT(!funbox->allowReturn())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!funbox->allowReturn())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!funbox->allowReturn())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("!funbox->allowReturn()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8688); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowReturn()"
")"); do { *((volatile int*)__null) = 8688; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8689
8690 // Set start at `static` token.
8691 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Static))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Static))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Static)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Static)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8691); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Static)"
")"); do { *((volatile int*)__null) = 8691; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8692 setFunctionStartAtCurrentToken(funbox);
8693
8694 // Push a SourceParseContext on to the stack.
8695 ParseContext* outerpc = pc_;
8696 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8697 if (!funpc.init()) {
8698 return errorResult();
8699 }
8700
8701 pc_->functionScope().useAsVarScope(pc_);
8702
8703 uint32_t start = pos().begin;
8704
8705 tokenStream.consumeKnownToken(TokenKind::LeftCurly);
8706
8707 // Static class blocks are code-generated as if they were static field
8708 // initializers, so we bump the staticFields count here, which ensures
8709 // .staticInitializers is noted as used.
8710 classInitializedMembers.staticFields++;
8711
8712 LexicalScopeNodeType body;
8713 MOZ_TRY_VAR(body,do { auto mozTryVarTempResult_ = (functionBody(InHandling::InAllowed
, YieldHandling::YieldIsKeyword, syntaxKind, FunctionBodyType
::StatementListBody)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (body) = mozTryVarTempResult_.unwrap(); } while (0)
8714 functionBody(InHandling::InAllowed, YieldHandling::YieldIsKeyword,do { auto mozTryVarTempResult_ = (functionBody(InHandling::InAllowed
, YieldHandling::YieldIsKeyword, syntaxKind, FunctionBodyType
::StatementListBody)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (body) = mozTryVarTempResult_.unwrap(); } while (0)
8715 syntaxKind, FunctionBodyType::StatementListBody))do { auto mozTryVarTempResult_ = (functionBody(InHandling::InAllowed
, YieldHandling::YieldIsKeyword, syntaxKind, FunctionBodyType
::StatementListBody)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (body) = mozTryVarTempResult_.unwrap(); } while (0)
;
8716
8717 if (anyChars.isEOF()) {
8718 error(JSMSG_UNTERMINATED_STATIC_CLASS_BLOCK);
8719 return errorResult();
8720 }
8721
8722 tokenStream.consumeKnownToken(TokenKind::RightCurly,
8723 TokenStream::Modifier::SlashIsRegExp);
8724
8725 TokenPos wholeBodyPos(start, pos().end);
8726
8727 handler_.setEndPosition(funNode, wholeBodyPos.end);
8728 setFunctionEndFromCurrentToken(funbox);
8729
8730 // Create a ParamsBodyNode for the parameters + body (there are no
8731 // parameters).
8732 ParamsBodyNodeType argsbody;
8733 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(wholeBodyPos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(wholeBodyPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8734
8735 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8736 funbox->setArgCount(0);
8737
8738 if (pc_->superScopeNeedsHomeObject()) {
8739 funbox->setNeedsHomeObject();
8740 }
8741
8742 handler_.setEndPosition(body, pos().begin);
8743 handler_.setEndPosition(funNode, pos().end);
8744 handler_.setFunctionBody(funNode, body);
8745
8746 if (!finishFunction()) {
8747 return errorResult();
8748 }
8749
8750 if (!leaveInnerFunction(outerpc)) {
8751 return errorResult();
8752 }
8753
8754 return funNode;
8755}
8756
8757template <class ParseHandler, typename Unit>
8758typename ParseHandler::FunctionNodeResult
8759GeneralParser<ParseHandler, Unit>::fieldInitializerOpt(
8760 TokenPos propNamePos, Node propName, TaggedParserAtomIndex propAtom,
8761 ClassInitializedMembers& classInitializedMembers, bool isStatic,
8762 HasHeritage hasHeritage) {
8763 if (!abortIfSyntaxParser()) {
8764 return errorResult();
8765 }
8766
8767 bool hasInitializer = false;
8768 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
8769 TokenStream::SlashIsDiv)) {
8770 return errorResult();
8771 }
8772
8773 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer;
8774 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8775 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8776 bool isSelfHosting = options().selfHostingMode;
8777 FunctionFlags flags =
8778 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8779
8780 // Create the top-level field initializer node.
8781 FunctionNodeType funNode;
8782 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8783
8784 // Create the FunctionBox and link it to the function object.
8785 Directives directives(true);
8786 FunctionBox* funbox =
8787 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
8788 propNamePos.begin, directives, generatorKind, asyncKind);
8789 if (!funbox) {
8790 return errorResult();
8791 }
8792 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8793 MOZ_ASSERT(funbox->isSyntheticFunction())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isSyntheticFunction())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isSyntheticFunction
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isSyntheticFunction()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8793); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isSyntheticFunction()"
")"); do { *((volatile int*)__null) = 8793; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8794
8795 // We can't use setFunctionStartAtCurrentToken because that uses pos().begin,
8796 // which is incorrect for fields without initializers (pos() points to the
8797 // field identifier)
8798 setFunctionStartAtPosition(funbox, propNamePos);
8799
8800 // Push a SourceParseContext on to the stack.
8801 ParseContext* outerpc = pc_;
8802 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8803 if (!funpc.init()) {
8804 return errorResult();
8805 }
8806
8807 pc_->functionScope().useAsVarScope(pc_);
8808
8809 Node initializerExpr;
8810 if (hasInitializer) {
8811 // Parse the expression for the field initializer.
8812 {
8813 AutoAwaitIsKeyword awaitHandling(this, AwaitIsName);
8814 MOZ_TRY_VAR(initializerExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, YieldIsName
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerExpr) = mozTryVarTempResult_.unwrap(); } while
(0)
8815 assignExpr(InAllowed, YieldIsName, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, YieldIsName
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerExpr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
8816 }
8817
8818 handler_.checkAndSetIsDirectRHSAnonFunction(initializerExpr);
8819 } else {
8820 MOZ_TRY_VAR(initializerExpr, handler_.newRawUndefinedLiteral(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newRawUndefinedLiteral
(propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerExpr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
8821 }
8822
8823 TokenPos wholeInitializerPos(propNamePos.begin, pos().end);
8824
8825 // Update the end position of the parse node.
8826 handler_.setEndPosition(funNode, wholeInitializerPos.end);
8827 setFunctionEndFromCurrentToken(funbox);
8828
8829 // Create a ParamsBodyNode for the parameters + body (there are no
8830 // parameters).
8831 ParamsBodyNodeType argsbody;
8832 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(wholeInitializerPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8833 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8834 funbox->setArgCount(0);
8835
8836 NameNodeType thisName;
8837 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
8838
8839 // Build `this.field` expression.
8840 ThisLiteralType propAssignThis;
8841 MOZ_TRY_VAR(propAssignThis,do { auto mozTryVarTempResult_ = (handler_.newThisLiteral(wholeInitializerPos
, thisName)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propAssignThis
) = mozTryVarTempResult_.unwrap(); } while (0)
8842 handler_.newThisLiteral(wholeInitializerPos, thisName))do { auto mozTryVarTempResult_ = (handler_.newThisLiteral(wholeInitializerPos
, thisName)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propAssignThis
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8843
8844 Node propAssignFieldAccess;
8845 uint32_t indexValue;
8846 if (!propAtom) {
8847 // See BytecodeEmitter::emitCreateFieldKeys for an explanation of what
8848 // .fieldKeys means and its purpose.
8849 NameNodeType fieldKeysName;
8850 if (isStatic) {
8851 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8852 fieldKeysName,do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8853 newInternalDotName(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8854 TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_()))do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
8855 } else {
8856 MOZ_TRY_VAR(fieldKeysName,do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_fieldKeys_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fieldKeysName) = mozTryVarTempResult_.unwrap(); } while (
0)
8857 newInternalDotName(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_fieldKeys_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fieldKeysName) = mozTryVarTempResult_.unwrap(); } while (
0)
8858 TaggedParserAtomIndex::WellKnown::dot_fieldKeys_()))do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_fieldKeys_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fieldKeysName) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8859 }
8860 if (!fieldKeysName) {
8861 return errorResult();
8862 }
8863
8864 double fieldKeyIndex;
8865 if (isStatic) {
8866 fieldKeyIndex = classInitializedMembers.staticFieldKeys++;
8867 } else {
8868 fieldKeyIndex = classInitializedMembers.instanceFieldKeys++;
8869 }
8870 Node fieldKeyIndexNode;
8871 MOZ_TRY_VAR(fieldKeyIndexNode,do { auto mozTryVarTempResult_ = (handler_.newNumber(fieldKeyIndex
, DecimalPoint::NoDecimal, wholeInitializerPos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeyIndexNode) = mozTryVarTempResult_
.unwrap(); } while (0)
8872 handler_.newNumber(fieldKeyIndex, DecimalPoint::NoDecimal,do { auto mozTryVarTempResult_ = (handler_.newNumber(fieldKeyIndex
, DecimalPoint::NoDecimal, wholeInitializerPos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeyIndexNode) = mozTryVarTempResult_
.unwrap(); } while (0)
8873 wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newNumber(fieldKeyIndex
, DecimalPoint::NoDecimal, wholeInitializerPos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeyIndexNode) = mozTryVarTempResult_
.unwrap(); } while (0)
;
8874
8875 Node fieldKeyValue;
8876 MOZ_TRY_VAR(fieldKeyValue,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(fieldKeysName, fieldKeyIndexNode, wholeInitializerPos.end));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (fieldKeyValue
) = mozTryVarTempResult_.unwrap(); } while (0)
8877 handler_.newPropertyByValue(fieldKeysName, fieldKeyIndexNode,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(fieldKeysName, fieldKeyIndexNode, wholeInitializerPos.end));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (fieldKeyValue
) = mozTryVarTempResult_.unwrap(); } while (0)
8878 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(fieldKeysName, fieldKeyIndexNode, wholeInitializerPos.end));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (fieldKeyValue
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8879
8880 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, fieldKeyValue, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8881 handler_.newPropertyByValue(propAssignThis, fieldKeyValue,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, fieldKeyValue, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8882 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, fieldKeyValue, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8883 } else if (handler_.isPrivateName(propName)) {
8884 // It would be nice if we could tweak this here such that only if
8885 // HasHeritage::Yes we end up emitting CheckPrivateField, but otherwise we
8886 // emit InitElem -- this is an optimization to minimize HasOwn checks
8887 // in InitElem for classes without heritage.
8888 //
8889 // Further tweaking would be to ultimately only do CheckPrivateField for the
8890 // -first- field in a derived class, which would suffice to match the
8891 // semantic check.
8892
8893 NameNodeType privateNameNode;
8894 MOZ_TRY_VAR(privateNameNode, privateNameReference(propAtom))do { auto mozTryVarTempResult_ = (privateNameReference(propAtom
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (privateNameNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8895
8896 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
(propAssignThis, privateNameNode, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8897 handler_.newPrivateMemberAccess(propAssignThis, privateNameNode,do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
(propAssignThis, privateNameNode, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8898 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
(propAssignThis, privateNameNode, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8899 } else if (this->parserAtoms().isIndex(propAtom, &indexValue)) {
8900 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, propName, wholeInitializerPos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propAssignFieldAccess) = mozTryVarTempResult_
.unwrap(); } while (0)
8901 handler_.newPropertyByValue(propAssignThis, propName,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, propName, wholeInitializerPos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propAssignFieldAccess) = mozTryVarTempResult_
.unwrap(); } while (0)
8902 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, propName, wholeInitializerPos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propAssignFieldAccess) = mozTryVarTempResult_
.unwrap(); } while (0)
;
8903 } else {
8904 NameNodeType propAssignName;
8905 MOZ_TRY_VAR(propAssignName,do { auto mozTryVarTempResult_ = (handler_.newPropertyName(propAtom
, wholeInitializerPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignName) = mozTryVarTempResult_.unwrap(); } while (
0)
8906 handler_.newPropertyName(propAtom, wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newPropertyName(propAtom
, wholeInitializerPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignName) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8907
8908 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPropertyAccess(
propAssignThis, propAssignName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignFieldAccess) = mozTryVarTempResult_.unwrap(); }
while (0)
8909 handler_.newPropertyAccess(propAssignThis, propAssignName))do { auto mozTryVarTempResult_ = (handler_.newPropertyAccess(
propAssignThis, propAssignName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignFieldAccess) = mozTryVarTempResult_.unwrap(); }
while (0)
;
8910 }
8911
8912 // Synthesize an property init.
8913 BinaryNodeType initializerPropInit;
8914 MOZ_TRY_VAR(initializerPropInit,do { auto mozTryVarTempResult_ = (handler_.newInitExpr(propAssignFieldAccess
, initializerExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerPropInit) = mozTryVarTempResult_.unwrap(); } while
(0)
8915 handler_.newInitExpr(propAssignFieldAccess, initializerExpr))do { auto mozTryVarTempResult_ = (handler_.newInitExpr(propAssignFieldAccess
, initializerExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerPropInit) = mozTryVarTempResult_.unwrap(); } while
(0)
;
8916
8917 UnaryNodeType exprStatement;
8918 MOZ_TRY_VAR(exprStatement, handler_.newExprStatement(do { auto mozTryVarTempResult_ = (handler_.newExprStatement( initializerPropInit
, wholeInitializerPos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprStatement) = mozTryVarTempResult_.unwrap(); } while (
0)
8919 initializerPropInit, wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newExprStatement( initializerPropInit
, wholeInitializerPos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprStatement) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8920
8921 ListNodeType statementList;
8922 MOZ_TRY_VAR(statementList, handler_.newStatementList(wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(wholeInitializerPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (statementList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8923 handler_.addStatementToList(statementList, exprStatement);
8924
8925 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8926 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8927 return errorResult();
8928 }
8929 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8930 return errorResult();
8931 }
8932
8933 // Set the function's body to the field assignment.
8934 LexicalScopeNodeType initializerBody;
8935 MOZ_TRY_VAR(initializerBody,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
8936 finishLexicalScope(pc_->varScope(), statementList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
8937 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
;
8938
8939 handler_.setFunctionBody(funNode, initializerBody);
8940
8941 if (pc_->superScopeNeedsHomeObject()) {
8942 funbox->setNeedsHomeObject();
8943 }
8944
8945 if (!finishFunction()) {
8946 return errorResult();
8947 }
8948
8949 if (!leaveInnerFunction(outerpc)) {
8950 return errorResult();
8951 }
8952
8953 return funNode;
8954}
8955
8956template <class ParseHandler, typename Unit>
8957typename ParseHandler::FunctionNodeResult
8958GeneralParser<ParseHandler, Unit>::synthesizePrivateMethodInitializer(
8959 TaggedParserAtomIndex propAtom, AccessorType accessorType,
8960 TokenPos propNamePos) {
8961 if (!abortIfSyntaxParser()) {
8962 return errorResult();
8963 }
8964
8965 // Synthesize a name for the lexical variable that will store the
8966 // accessor body.
8967 StringBuffer storedMethodName(fc_);
8968 if (!storedMethodName.append(this->parserAtoms(), propAtom)) {
8969 return errorResult();
8970 }
8971 if (!storedMethodName.append(
8972 accessorType == AccessorType::Getter ? ".getter" : ".setter")) {
8973 return errorResult();
8974 }
8975 auto storedMethodProp =
8976 storedMethodName.finishParserAtom(this->parserAtoms(), fc_);
8977 if (!storedMethodProp) {
8978 return errorResult();
8979 }
8980 if (!noteDeclaredName(storedMethodProp, DeclarationKind::Synthetic, pos())) {
8981 return errorResult();
8982 }
8983
8984 return privateMethodInitializer(propNamePos, propAtom, storedMethodProp);
8985}
8986
8987#ifdef ENABLE_DECORATORS
8988template <class ParseHandler, typename Unit>
8989typename ParseHandler::FunctionNodeResult
8990GeneralParser<ParseHandler, Unit>::synthesizeAddInitializerFunction(
8991 TaggedParserAtomIndex initializers, YieldHandling yieldHandling) {
8992 if (!abortIfSyntaxParser()) {
8993 return errorResult();
8994 }
8995
8996 // TODO: Add support for static and class extra initializers, see bug 1868220
8997 // and bug 1868221.
8998 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9000); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9000; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
8999 initializers ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9000); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9000; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9000 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9000); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9000; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9001
9002 TokenPos propNamePos = pos();
9003
9004 // Synthesize an addInitializer function that can be used to append to
9005 // .initializers
9006 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
9007 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
9008 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
9009 bool isSelfHosting = options().selfHostingMode;
9010 FunctionFlags flags =
9011 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
9012
9013 FunctionNodeType funNode;
9014 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
9015
9016 Directives directives(true);
9017 FunctionBox* funbox =
9018 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
9019 propNamePos.begin, directives, generatorKind, asyncKind);
9020 if (!funbox) {
9021 return errorResult();
9022 }
9023 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
9024
9025 ParseContext* outerpc = pc_;
9026 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
9027 if (!funpc.init()) {
9028 return errorResult();
9029 }
9030 pc_->functionScope().useAsVarScope(pc_);
9031
9032 // Takes a single parameter, `initializer`.
9033 ParamsBodyNodeType params;
9034 MOZ_TRY_VAR(params, handler_.newParamsBody(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (params) =
mozTryVarTempResult_.unwrap(); } while (0)
;
9035
9036 handler_.setFunctionFormalParametersAndBody(funNode, params);
9037
9038 constexpr bool disallowDuplicateParams = true;
9039 bool duplicatedParam = false;
9040 if (!notePositionalFormalParameter(
9041 funNode, TaggedParserAtomIndex::WellKnown::initializer(), pos().begin,
9042 disallowDuplicateParams, &duplicatedParam)) {
9043 return null();
9044 }
9045 MOZ_ASSERT(!duplicatedParam)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!duplicatedParam)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!duplicatedParam))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!duplicatedParam"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9045); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!duplicatedParam"
")"); do { *((volatile int*)__null) = 9045; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9046 MOZ_ASSERT(pc_->positionalFormalParameterNames().length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->positionalFormalParameterNames().length() ==
1)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->positionalFormalParameterNames().length() ==
1))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->positionalFormalParameterNames().length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9046); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->positionalFormalParameterNames().length() == 1"
")"); do { *((volatile int*)__null) = 9046; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9047
9048 funbox->setLength(1);
9049 funbox->setArgCount(1);
9050 setFunctionStartAtCurrentToken(funbox);
9051
9052 // Like private method initializers, the addInitializer method is not created
9053 // with a body of synthesized AST nodes. Instead, the body is left empty and
9054 // the initializer is synthesized at the bytecode level. See
9055 // DecoratorEmitter::emitCreateAddInitializerFunction.
9056 ListNodeType stmtList;
9057 MOZ_TRY_VAR(stmtList, handler_.newStatementList(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9058
9059 if (!noteUsedName(initializers)) {
9060 return null();
9061 }
9062
9063 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
9064 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
9065 return null();
9066 }
9067 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
9068 return null();
9069 }
9070
9071 LexicalScopeNodeType addInitializerBody;
9072 MOZ_TRY_VAR(addInitializerBody,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (addInitializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9073 finishLexicalScope(pc_->varScope(), stmtList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (addInitializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9074 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (addInitializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
;
9075 handler_.setBeginPosition(addInitializerBody, stmtList);
9076 handler_.setEndPosition(addInitializerBody, stmtList);
9077 handler_.setFunctionBody(funNode, addInitializerBody);
9078
9079 // Set field-initializer lambda boundary to start at property name and end
9080 // after method body.
9081 setFunctionStartAtPosition(funbox, propNamePos);
9082 setFunctionEndFromCurrentToken(funbox);
9083
9084 if (!finishFunction()) {
9085 return errorResult();
9086 }
9087
9088 if (!leaveInnerFunction(outerpc)) {
9089 return errorResult();
9090 }
9091
9092 return funNode;
9093}
9094
9095template <class ParseHandler, typename Unit>
9096typename ParseHandler::ClassMethodResult
9097GeneralParser<ParseHandler, Unit>::synthesizeAccessor(
9098 Node propName, TokenPos propNamePos, TaggedParserAtomIndex propAtom,
9099 TaggedParserAtomIndex privateStateNameAtom, bool isStatic,
9100 FunctionSyntaxKind syntaxKind,
9101 ClassInitializedMembers& classInitializedMembers) {
9102 // Decorators Proposal
9103 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9104 // The abstract operation MakeAutoAccessorGetter takes arguments homeObject
9105 // (an Object), name (a property key or Private Name), and privateStateName (a
9106 // Private Name) and returns a function object.
9107 //
9108 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9109 // The abstract operation MakeAutoAccessorSetter takes arguments homeObject
9110 // (an Object), name (a property key or Private Name), and privateStateName (a
9111 // Private Name) and returns a function object.
9112 if (!abortIfSyntaxParser()) {
9113 return errorResult();
9114 }
9115
9116 AccessorType accessorType = syntaxKind == FunctionSyntaxKind::Getter
9117 ? AccessorType::Getter
9118 : AccessorType::Setter;
9119
9120 mozilla::Maybe<FunctionNodeType> initializerIfPrivate = Nothing();
9121 if (!isStatic && handler_.isPrivateName(propName)) {
9122 classInitializedMembers.privateAccessors++;
9123 FunctionNodeType initializerNode;
9124 MOZ_TRY_VAR(initializerNode, synthesizePrivateMethodInitializer(do { auto mozTryVarTempResult_ = (synthesizePrivateMethodInitializer
( propAtom, accessorType, propNamePos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerNode) = mozTryVarTempResult_.unwrap
(); } while (0)
9125 propAtom, accessorType, propNamePos))do { auto mozTryVarTempResult_ = (synthesizePrivateMethodInitializer
( propAtom, accessorType, propNamePos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerNode) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9126 initializerIfPrivate = Some(initializerNode);
9127 handler_.setPrivateNameKind(propName, PrivateNameKind::GetterSetter);
9128 }
9129
9130 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9131 // 2. Let getter be CreateBuiltinFunction(getterClosure, 0, "get", « »).
9132 //
9133 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9134 // 2. Let setter be CreateBuiltinFunction(setterClosure, 1, "set", « »).
9135 StringBuffer storedMethodName(fc_);
9136 if (!storedMethodName.append(accessorType == AccessorType::Getter ? "get"
9137 : "set")) {
9138 return errorResult();
9139 }
9140 TaggedParserAtomIndex funNameAtom =
9141 storedMethodName.finishParserAtom(this->parserAtoms(), fc_);
9142
9143 FunctionNodeType funNode;
9144 MOZ_TRY_VAR(funNode,do { auto mozTryVarTempResult_ = (synthesizeAccessorBody(funNameAtom
, propNamePos, privateStateNameAtom, syntaxKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (funNode) = mozTryVarTempResult_.unwrap();
} while (0)
9145 synthesizeAccessorBody(funNameAtom, propNamePos,do { auto mozTryVarTempResult_ = (synthesizeAccessorBody(funNameAtom
, propNamePos, privateStateNameAtom, syntaxKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (funNode) = mozTryVarTempResult_.unwrap();
} while (0)
9146 privateStateNameAtom, syntaxKind))do { auto mozTryVarTempResult_ = (synthesizeAccessorBody(funNameAtom
, propNamePos, privateStateNameAtom, syntaxKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (funNode) = mozTryVarTempResult_.unwrap();
} while (0)
;
9147
9148 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9149 // 3. Perform MakeMethod(getter, homeObject).
9150 // 4. Return getter.
9151 //
9152 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9153 // 3. Perform MakeMethod(setter, homeObject).
9154 // 4. Return setter.
9155 return handler_.newClassMethodDefinition(
9156 propName, funNode, accessorType, isStatic, initializerIfPrivate, null());
9157}
9158
9159template <class ParseHandler, typename Unit>
9160typename ParseHandler::FunctionNodeResult
9161GeneralParser<ParseHandler, Unit>::synthesizeAccessorBody(
9162 TaggedParserAtomIndex funNameAtom, TokenPos propNamePos,
9163 TaggedParserAtomIndex propNameAtom, FunctionSyntaxKind syntaxKind) {
9164 if (!abortIfSyntaxParser()) {
9165 return errorResult();
9166 }
9167
9168 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
9169 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
9170 bool isSelfHosting = options().selfHostingMode;
9171 FunctionFlags flags =
9172 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
9173
9174 // Create the top-level function node.
9175 FunctionNodeType funNode;
9176 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
9177
9178 // Create the FunctionBox and link it to the function object.
9179 Directives directives(true);
9180 FunctionBox* funbox =
9181 newFunctionBox(funNode, funNameAtom, flags, propNamePos.begin, directives,
9182 generatorKind, asyncKind);
9183 if (!funbox) {
9184 return errorResult();
9185 }
9186 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
9187 funbox->setSyntheticFunction();
9188
9189 // Push a SourceParseContext on to the stack.
9190 ParseContext* outerpc = pc_;
9191 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
9192 if (!funpc.init()) {
9193 return errorResult();
9194 }
9195
9196 pc_->functionScope().useAsVarScope(pc_);
9197
9198 // The function we synthesize is located at the field with the
9199 // accessor.
9200 setFunctionStartAtCurrentToken(funbox);
9201 setFunctionEndFromCurrentToken(funbox);
9202
9203 // Create a ListNode for the parameters + body
9204 ParamsBodyNodeType paramsbody;
9205 MOZ_TRY_VAR(paramsbody, handler_.newParamsBody(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (paramsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9206 handler_.setFunctionFormalParametersAndBody(funNode, paramsbody);
9207
9208 if (syntaxKind == FunctionSyntaxKind::Getter) {
9209 funbox->setArgCount(0);
9210 } else {
9211 funbox->setArgCount(1);
9212 }
9213
9214 // Build `this` expression to access the privateStateName for use in the
9215 // operations to create the getter and setter below.
9216 NameNodeType thisName;
9217 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
9218
9219 ThisLiteralType propThis;
9220 MOZ_TRY_VAR(propThis, handler_.newThisLiteral(propNamePos, thisName))do { auto mozTryVarTempResult_ = (handler_.newThisLiteral(propNamePos
, thisName)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propThis
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9221
9222 NameNodeType privateNameNode;
9223 MOZ_TRY_VAR(privateNameNode, privateNameReference(propNameAtom))do { auto mozTryVarTempResult_ = (privateNameReference(propNameAtom
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (privateNameNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9224
9225 Node propFieldAccess;
9226 MOZ_TRY_VAR(propFieldAccess, handler_.newPrivateMemberAccess(do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
( propThis, privateNameNode, propNamePos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propFieldAccess) = mozTryVarTempResult_.unwrap
(); } while (0)
9227 propThis, privateNameNode, propNamePos.end))do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
( propThis, privateNameNode, propNamePos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propFieldAccess) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9228
9229 Node accessorBody;
9230 if (syntaxKind == FunctionSyntaxKind::Getter) {
9231 // Decorators Proposal
9232 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9233 // 1. Let getterClosure be a new Abstract Closure with no parameters that
9234 // captures privateStateName and performs the following steps when called:
9235 // 1.a. Let o be the this value.
9236 // 1.b. Return ? PrivateGet(privateStateName, o).
9237 MOZ_TRY_VAR(accessorBody,do { auto mozTryVarTempResult_ = (handler_.newReturnStatement
(propFieldAccess, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
9238 handler_.newReturnStatement(propFieldAccess, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newReturnStatement
(propFieldAccess, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
;
9239 } else {
9240 // Decorators Proposal
9241 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9242 // The abstract operation MakeAutoAccessorSetter takes arguments homeObject
9243 // (an Object), name (a property key or Private Name), and privateStateName
9244 // (a Private Name) and returns a function object.
9245 // 1. Let setterClosure be a new Abstract Closure with parameters (value)
9246 // that captures privateStateName and performs the following steps when
9247 // called:
9248 // 1.a. Let o be the this value.
9249 notePositionalFormalParameter(funNode,
9250 TaggedParserAtomIndex::WellKnown::value(),
9251 /* pos = */ 0, false,
9252 /* duplicatedParam = */ nullptr);
9253
9254 Node initializerExpr;
9255 MOZ_TRY_VAR(initializerExpr,do { auto mozTryVarTempResult_ = (handler_.newName(TaggedParserAtomIndex
::WellKnown::value(), propNamePos)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerExpr) = mozTryVarTempResult_.unwrap
(); } while (0)
9256 handler_.newName(TaggedParserAtomIndex::WellKnown::value(),do { auto mozTryVarTempResult_ = (handler_.newName(TaggedParserAtomIndex
::WellKnown::value(), propNamePos)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerExpr) = mozTryVarTempResult_.unwrap
(); } while (0)
9257 propNamePos))do { auto mozTryVarTempResult_ = (handler_.newName(TaggedParserAtomIndex
::WellKnown::value(), propNamePos)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerExpr) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9258
9259 // 1.b. Perform ? PrivateSet(privateStateName, o, value).
9260 Node assignment;
9261 MOZ_TRY_VAR(assignment,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, propFieldAccess, initializerExpr)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (assignment) = mozTryVarTempResult_.unwrap
(); } while (0)
9262 handler_.newAssignment(ParseNodeKind::AssignExpr,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, propFieldAccess, initializerExpr)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (assignment) = mozTryVarTempResult_.unwrap
(); } while (0)
9263 propFieldAccess, initializerExpr))do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, propFieldAccess, initializerExpr)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (assignment) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9264
9265 MOZ_TRY_VAR(accessorBody,do { auto mozTryVarTempResult_ = (handler_.newExprStatement(assignment
, propNamePos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
9266 handler_.newExprStatement(assignment, propNamePos.end))do { auto mozTryVarTempResult_ = (handler_.newExprStatement(assignment
, propNamePos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
;
9267
9268 // 1.c. Return undefined.
9269 }
9270
9271 ListNodeType statementList;
9272 MOZ_TRY_VAR(statementList, handler_.newStatementList(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (statementList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9273 handler_.addStatementToList(statementList, accessorBody);
9274
9275 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
9276 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
9277 return errorResult();
9278 }
9279 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
9280 return errorResult();
9281 }
9282
9283 LexicalScopeNodeType initializerBody;
9284 MOZ_TRY_VAR(initializerBody,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9285 finishLexicalScope(pc_->varScope(), statementList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9286 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
;
9287
9288 handler_.setFunctionBody(funNode, initializerBody);
9289
9290 if (pc_->superScopeNeedsHomeObject()) {
9291 funbox->setNeedsHomeObject();
9292 }
9293
9294 if (!finishFunction()) {
9295 return errorResult();
9296 }
9297
9298 if (!leaveInnerFunction(outerpc)) {
9299 return errorResult();
9300 }
9301
9302 return funNode;
9303}
9304
9305#endif
9306
9307bool ParserBase::nextTokenContinuesLetDeclaration(TokenKind next) {
9308 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Let))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Let))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Let)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Let)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9308); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 9308; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9309 MOZ_ASSERT(anyChars.nextToken().type == next)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.nextToken().type == next)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.nextToken().type ==
next))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.nextToken().type == next", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9309); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.nextToken().type == next"
")"); do { *((volatile int*)__null) = 9309; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9310
9311 TokenStreamShared::verifyConsistentModifier(TokenStreamShared::SlashIsDiv,
9312 anyChars.nextToken());
9313
9314 // Destructuring continues a let declaration.
9315 if (next == TokenKind::LeftBracket || next == TokenKind::LeftCurly) {
9316 return true;
9317 }
9318
9319 // A "let" edge case deserves special comment. Consider this:
9320 //
9321 // let // not an ASI opportunity
9322 // let;
9323 //
9324 // Static semantics in §13.3.1.1 turn a LexicalDeclaration that binds
9325 // "let" into an early error. Does this retroactively permit ASI so
9326 // that we should parse this as two ExpressionStatements? No. ASI
9327 // resolves during parsing. Static semantics only apply to the full
9328 // parse tree with ASI applied. No backsies!
9329
9330 // Otherwise a let declaration must have a name.
9331 return TokenKindIsPossibleIdentifier(next);
9332}
9333
9334template <class ParseHandler, typename Unit>
9335typename ParseHandler::DeclarationListNodeResult
9336GeneralParser<ParseHandler, Unit>::variableStatement(
9337 YieldHandling yieldHandling) {
9338 DeclarationListNodeType vars;
9339 MOZ_TRY_VAR(vars, declarationList(yieldHandling, ParseNodeKind::VarStmt))do { auto mozTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (vars) = mozTryVarTempResult_.unwrap(); } while (0)
;
9340 if (!matchOrInsertSemicolon()) {
9341 return errorResult();
9342 }
9343 return vars;
9344}
9345
9346template <class ParseHandler, typename Unit>
9347typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::statement(
9348 YieldHandling yieldHandling) {
9349 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 9349; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9350
9351 AutoCheckRecursionLimit recursion(this->fc_);
9352 if (!recursion.check(this->fc_)) {
9353 return errorResult();
9354 }
9355
9356 TokenKind tt;
9357 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
9358 return errorResult();
9359 }
9360
9361 switch (tt) {
9362 // BlockStatement[?Yield, ?Return]
9363 case TokenKind::LeftCurly:
9364 return blockStatement(yieldHandling);
9365
9366 // VariableStatement[?Yield]
9367 case TokenKind::Var:
9368 return variableStatement(yieldHandling);
9369
9370 // EmptyStatement
9371 case TokenKind::Semi:
9372 return handler_.newEmptyStatement(pos());
9373
9374 // ExpressionStatement[?Yield].
9375
9376 case TokenKind::Yield: {
9377 // Don't use a ternary operator here due to obscure linker issues
9378 // around using static consts in the arms of a ternary.
9379 Modifier modifier;
9380 if (yieldExpressionsSupported()) {
9381 modifier = TokenStream::SlashIsRegExp;
9382 } else {
9383 modifier = TokenStream::SlashIsDiv;
9384 }
9385
9386 TokenKind next;
9387 if (!tokenStream.peekToken(&next, modifier)) {
9388 return errorResult();
9389 }
9390
9391 if (next == TokenKind::Colon) {
9392 return labeledStatement(yieldHandling);
9393 }
9394
9395 return expressionStatement(yieldHandling);
9396 }
9397
9398 default: {
9399 // If we encounter an await in a module, and the module is not marked
9400 // as async, mark the module as async.
9401 if (tt == TokenKind::Await && !pc_->isAsync()) {
9402 if (pc_->atModuleTopLevel()) {
9403 if (!options().topLevelAwait) {
9404 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
9405 return errorResult();
9406 }
9407 pc_->sc()->asModuleContext()->setIsAsync();
9408 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9408); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 9408; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9409 }
9410 }
9411
9412 // Avoid getting next token with SlashIsDiv.
9413 if (tt == TokenKind::Await && pc_->isAsync()) {
9414 return expressionStatement(yieldHandling);
9415 }
9416
9417 if (!TokenKindIsPossibleIdentifier(tt)) {
9418 return expressionStatement(yieldHandling);
9419 }
9420
9421 TokenKind next;
9422 if (!tokenStream.peekToken(&next)) {
9423 return errorResult();
9424 }
9425
9426 // |let| here can only be an Identifier, not a declaration. Give nicer
9427 // errors for declaration-looking typos.
9428 if (tt == TokenKind::Let) {
9429 bool forbiddenLetDeclaration = false;
9430
9431 if (next == TokenKind::LeftBracket) {
9432 // Enforce ExpressionStatement's 'let [' lookahead restriction.
9433 forbiddenLetDeclaration = true;
9434 } else if (next == TokenKind::LeftCurly ||
9435 TokenKindIsPossibleIdentifier(next)) {
9436 // 'let {' and 'let foo' aren't completely forbidden, if ASI
9437 // causes 'let' to be the entire Statement. But if they're
9438 // same-line, we can aggressively give a better error message.
9439 //
9440 // Note that this ignores 'yield' as TokenKind::Yield: we'll handle it
9441 // correctly but with a worse error message.
9442 TokenKind nextSameLine;
9443 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
9444 return errorResult();
9445 }
9446
9447 MOZ_ASSERT(TokenKindIsPossibleIdentifier(nextSameLine) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9449); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9449; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9448 nextSameLine == TokenKind::LeftCurly ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9449); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9449; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9449 nextSameLine == TokenKind::Eol)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9449); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9449; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9450
9451 forbiddenLetDeclaration = nextSameLine != TokenKind::Eol;
9452 }
9453
9454 if (forbiddenLetDeclaration) {
9455 error(JSMSG_FORBIDDEN_AS_STATEMENT, "lexical declarations");
9456 return errorResult();
9457 }
9458 } else if (tt == TokenKind::Async) {
9459 // Peek only on the same line: ExpressionStatement's lookahead
9460 // restriction is phrased as
9461 //
9462 // [lookahead ∉ { '{',
9463 // function,
9464 // async [no LineTerminator here] function,
9465 // class,
9466 // let '[' }]
9467 //
9468 // meaning that code like this is valid:
9469 //
9470 // if (true)
9471 // async // ASI opportunity
9472 // function clownshoes() {}
9473 TokenKind maybeFunction;
9474 if (!tokenStream.peekTokenSameLine(&maybeFunction)) {
9475 return errorResult();
9476 }
9477
9478 if (maybeFunction == TokenKind::Function) {
9479 error(JSMSG_FORBIDDEN_AS_STATEMENT, "async function declarations");
9480 return errorResult();
9481 }
9482
9483 // Otherwise this |async| begins an ExpressionStatement or is a
9484 // label name.
9485 }
9486
9487 // NOTE: It's unfortunately allowed to have a label named 'let' in
9488 // non-strict code. 💯
9489 if (next == TokenKind::Colon) {
9490 return labeledStatement(yieldHandling);
9491 }
9492
9493 return expressionStatement(yieldHandling);
9494 }
9495
9496 case TokenKind::New:
9497 return expressionStatement(yieldHandling, PredictInvoked);
9498
9499 // IfStatement[?Yield, ?Return]
9500 case TokenKind::If:
9501 return ifStatement(yieldHandling);
9502
9503 // BreakableStatement[?Yield, ?Return]
9504 //
9505 // BreakableStatement[Yield, Return]:
9506 // IterationStatement[?Yield, ?Return]
9507 // SwitchStatement[?Yield, ?Return]
9508 case TokenKind::Do:
9509 return doWhileStatement(yieldHandling);
9510
9511 case TokenKind::While:
9512 return whileStatement(yieldHandling);
9513
9514 case TokenKind::For:
9515 return forStatement(yieldHandling);
9516
9517 case TokenKind::Switch:
9518 return switchStatement(yieldHandling);
9519
9520 // ContinueStatement[?Yield]
9521 case TokenKind::Continue:
9522 return continueStatement(yieldHandling);
9523
9524 // BreakStatement[?Yield]
9525 case TokenKind::Break:
9526 return breakStatement(yieldHandling);
9527
9528 // [+Return] ReturnStatement[?Yield]
9529 case TokenKind::Return:
9530 // The Return parameter is only used here, and the effect is easily
9531 // detected this way, so don't bother passing around an extra parameter
9532 // everywhere.
9533 if (!pc_->allowReturn()) {
9534 error(JSMSG_BAD_RETURN_OR_YIELD, "return");
9535 return errorResult();
9536 }
9537 return returnStatement(yieldHandling);
9538
9539 // WithStatement[?Yield, ?Return]
9540 case TokenKind::With:
9541 return withStatement(yieldHandling);
9542
9543 // LabelledStatement[?Yield, ?Return]
9544 // This is really handled by default and TokenKind::Yield cases above.
9545
9546 // ThrowStatement[?Yield]
9547 case TokenKind::Throw:
9548 return throwStatement(yieldHandling);
9549
9550 // TryStatement[?Yield, ?Return]
9551 case TokenKind::Try:
9552 return tryStatement(yieldHandling);
9553
9554 // DebuggerStatement
9555 case TokenKind::Debugger:
9556 return debuggerStatement();
9557
9558 // |function| is forbidden by lookahead restriction (unless as child
9559 // statement of |if| or |else|, but Parser::consequentOrAlternative
9560 // handles that).
9561 case TokenKind::Function:
9562 error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
9563 return errorResult();
9564
9565 // |class| is also forbidden by lookahead restriction.
9566 case TokenKind::Class:
9567 error(JSMSG_FORBIDDEN_AS_STATEMENT, "classes");
9568 return errorResult();
9569
9570 // ImportDeclaration (only inside modules)
9571 case TokenKind::Import:
9572 return importDeclarationOrImportExpr(yieldHandling);
9573
9574 // ExportDeclaration (only inside modules)
9575 case TokenKind::Export:
9576 return exportDeclaration();
9577
9578 // Miscellaneous error cases arguably better caught here than elsewhere.
9579
9580 case TokenKind::Catch:
9581 error(JSMSG_CATCH_WITHOUT_TRY);
9582 return errorResult();
9583
9584 case TokenKind::Finally:
9585 error(JSMSG_FINALLY_WITHOUT_TRY);
9586 return errorResult();
9587
9588 // NOTE: default case handled in the ExpressionStatement section.
9589 }
9590}
9591
9592template <class ParseHandler, typename Unit>
9593typename ParseHandler::NodeResult
9594GeneralParser<ParseHandler, Unit>::statementListItem(
9595 YieldHandling yieldHandling, bool canHaveDirectives /* = false */) {
9596 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9596); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 9596; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9597
9598 AutoCheckRecursionLimit recursion(this->fc_);
9599 if (!recursion.check(this->fc_)) {
9600 return errorResult();
9601 }
9602
9603 TokenKind tt;
9604 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
9605 return errorResult();
9606 }
9607
9608 switch (tt) {
9609 // BlockStatement[?Yield, ?Return]
9610 case TokenKind::LeftCurly:
9611 return blockStatement(yieldHandling);
9612
9613 // VariableStatement[?Yield]
9614 case TokenKind::Var:
9615 return variableStatement(yieldHandling);
9616
9617 // EmptyStatement
9618 case TokenKind::Semi:
9619 return handler_.newEmptyStatement(pos());
9620
9621 // ExpressionStatement[?Yield].
9622 //
9623 // These should probably be handled by a single ExpressionStatement
9624 // function in a default, not split up this way.
9625 case TokenKind::String:
9626 if (!canHaveDirectives &&
9627 anyChars.currentToken().atom() ==
9628 TaggedParserAtomIndex::WellKnown::use_asm_()) {
9629 if (!warning(JSMSG_USE_ASM_DIRECTIVE_FAIL)) {
9630 return errorResult();
9631 }
9632 }
9633 return expressionStatement(yieldHandling);
9634
9635 case TokenKind::Yield: {
9636 // Don't use a ternary operator here due to obscure linker issues
9637 // around using static consts in the arms of a ternary.
9638 Modifier modifier;
9639 if (yieldExpressionsSupported()) {
9640 modifier = TokenStream::SlashIsRegExp;
9641 } else {
9642 modifier = TokenStream::SlashIsDiv;
9643 }
9644
9645 TokenKind next;
9646 if (!tokenStream.peekToken(&next, modifier)) {
9647 return errorResult();
9648 }
9649
9650 if (next == TokenKind::Colon) {
9651 return labeledStatement(yieldHandling);
9652 }
9653
9654 return expressionStatement(yieldHandling);
9655 }
9656
9657 default: {
9658 // If we encounter an await in a module, and the module is not marked
9659 // as async, mark the module as async.
9660 if (tt == TokenKind::Await && !pc_->isAsync()) {
9661 if (pc_->atModuleTopLevel()) {
9662 if (!options().topLevelAwait) {
9663 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
9664 return errorResult();
9665 }
9666 pc_->sc()->asModuleContext()->setIsAsync();
9667 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9667); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 9667; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9668 }
9669 }
9670
9671 if (tt == TokenKind::Await && pc_->isAsync()) {
9672#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
9673 // Try finding evidence of a AwaitUsingDeclaration the syntax for which
9674 // would be:
9675 // await [no LineTerminator here] using [no LineTerminator here]
9676 // identifier
9677
9678 TokenKind nextTokUsing = TokenKind::Eof;
9679 // Scan with regex modifier because when its await expression, `/`
9680 // should be treated as a regexp.
9681 if (!tokenStream.peekTokenSameLine(&nextTokUsing,
9682 TokenStream::SlashIsRegExp)) {
9683 return errorResult();
9684 }
9685
9686 if (nextTokUsing == TokenKind::Using &&
9687 this->pc_->isUsingSyntaxAllowed()) {
9688 tokenStream.consumeKnownToken(nextTokUsing,
9689 TokenStream::SlashIsRegExp);
9690 TokenKind nextTokIdentifier = TokenKind::Eof;
9691 // Here we can use the Div modifier because if the next token is using
9692 // then a `/` as the next token can only be considered a division.
9693 if (!tokenStream.peekTokenSameLine(&nextTokIdentifier)) {
9694 return errorResult();
9695 }
9696 if (TokenKindIsPossibleIdentifier(nextTokIdentifier)) {
9697 return lexicalDeclaration(yieldHandling,
9698 DeclarationKind::AwaitUsing);
9699 }
9700 anyChars.ungetToken(); // put back using.
9701 }
9702#endif
9703 return expressionStatement(yieldHandling);
9704 }
9705
9706 if (!TokenKindIsPossibleIdentifier(tt)) {
9707 return expressionStatement(yieldHandling);
9708 }
9709
9710 TokenKind next;
9711 if (!tokenStream.peekToken(&next)) {
9712 return errorResult();
9713 }
9714
9715 if (tt == TokenKind::Let && nextTokenContinuesLetDeclaration(next)) {
9716 return lexicalDeclaration(yieldHandling, DeclarationKind::Let);
9717 }
9718
9719 if (tt == TokenKind::Async) {
9720 TokenKind nextSameLine = TokenKind::Eof;
9721 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
9722 return errorResult();
9723 }
9724 if (nextSameLine == TokenKind::Function) {
9725 uint32_t toStringStart = pos().begin;
9726 tokenStream.consumeKnownToken(TokenKind::Function);
9727 return functionStmt(toStringStart, yieldHandling, NameRequired,
9728 FunctionAsyncKind::AsyncFunction);
9729 }
9730 }
9731
9732 if (next == TokenKind::Colon) {
9733 return labeledStatement(yieldHandling);
9734 }
9735
9736 return expressionStatement(yieldHandling);
9737 }
9738
9739 case TokenKind::New:
9740 return expressionStatement(yieldHandling, PredictInvoked);
9741
9742 // IfStatement[?Yield, ?Return]
9743 case TokenKind::If:
9744 return ifStatement(yieldHandling);
9745
9746 // BreakableStatement[?Yield, ?Return]
9747 //
9748 // BreakableStatement[Yield, Return]:
9749 // IterationStatement[?Yield, ?Return]
9750 // SwitchStatement[?Yield, ?Return]
9751 case TokenKind::Do:
9752 return doWhileStatement(yieldHandling);
9753
9754 case TokenKind::While:
9755 return whileStatement(yieldHandling);
9756
9757 case TokenKind::For:
9758 return forStatement(yieldHandling);
9759
9760 case TokenKind::Switch:
9761 return switchStatement(yieldHandling);
9762
9763 // ContinueStatement[?Yield]
9764 case TokenKind::Continue:
9765 return continueStatement(yieldHandling);
9766
9767 // BreakStatement[?Yield]
9768 case TokenKind::Break:
9769 return breakStatement(yieldHandling);
9770
9771 // [+Return] ReturnStatement[?Yield]
9772 case TokenKind::Return:
9773 // The Return parameter is only used here, and the effect is easily
9774 // detected this way, so don't bother passing around an extra parameter
9775 // everywhere.
9776 if (!pc_->allowReturn()) {
9777 error(JSMSG_BAD_RETURN_OR_YIELD, "return");
9778 return errorResult();
9779 }
9780 return returnStatement(yieldHandling);
9781
9782 // WithStatement[?Yield, ?Return]
9783 case TokenKind::With:
9784 return withStatement(yieldHandling);
9785
9786 // LabelledStatement[?Yield, ?Return]
9787 // This is really handled by default and TokenKind::Yield cases above.
9788
9789 // ThrowStatement[?Yield]
9790 case TokenKind::Throw:
9791 return throwStatement(yieldHandling);
9792
9793 // TryStatement[?Yield, ?Return]
9794 case TokenKind::Try:
9795 return tryStatement(yieldHandling);
9796
9797 // DebuggerStatement
9798 case TokenKind::Debugger:
9799 return debuggerStatement();
9800
9801 // Declaration[Yield]:
9802
9803 // HoistableDeclaration[?Yield, ~Default]
9804 case TokenKind::Function:
9805 return functionStmt(pos().begin, yieldHandling, NameRequired);
9806
9807 // DecoratorList[?Yield, ?Await] opt ClassDeclaration[?Yield, ~Default]
9808#ifdef ENABLE_DECORATORS
9809 case TokenKind::At:
9810 return classDefinition(yieldHandling, ClassStatement, NameRequired);
9811#endif
9812
9813 case TokenKind::Class:
9814 return classDefinition(yieldHandling, ClassStatement, NameRequired);
9815
9816 // LexicalDeclaration[In, ?Yield]
9817 // LetOrConst BindingList[?In, ?Yield]
9818 case TokenKind::Const:
9819 // [In] is the default behavior, because for-loops specially parse
9820 // their heads to handle |in| in this situation.
9821 return lexicalDeclaration(yieldHandling, DeclarationKind::Const);
9822
9823#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT
9824 case TokenKind::Using: {
9825 TokenKind nextTok = TokenKind::Eol;
9826 if (!tokenStream.peekTokenSameLine(&nextTok)) {
9827 return errorResult();
9828 }
9829 if (!TokenKindIsPossibleIdentifier(nextTok) ||
9830 !this->pc_->isUsingSyntaxAllowed()) {
9831 if (!tokenStream.peekToken(&nextTok)) {
9832 return errorResult();
9833 }
9834 // labelled statement could be like using\n:\nexpr
9835 if (nextTok == TokenKind::Colon) {
9836 return labeledStatement(yieldHandling);
9837 }
9838 return expressionStatement(yieldHandling);
9839 }
9840 return lexicalDeclaration(yieldHandling, DeclarationKind::Using);
9841 }
9842#endif
9843
9844 // ImportDeclaration (only inside modules)
9845 case TokenKind::Import:
9846 return importDeclarationOrImportExpr(yieldHandling);
9847
9848 // ExportDeclaration (only inside modules)
9849 case TokenKind::Export:
9850 return exportDeclaration();
9851
9852 // Miscellaneous error cases arguably better caught here than elsewhere.
9853
9854 case TokenKind::Catch:
9855 error(JSMSG_CATCH_WITHOUT_TRY);
9856 return errorResult();
9857
9858 case TokenKind::Finally:
9859 error(JSMSG_FINALLY_WITHOUT_TRY);
9860 return errorResult();
9861
9862 // NOTE: default case handled in the ExpressionStatement section.
9863 }
9864}
9865
9866template <class ParseHandler, typename Unit>
9867typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::expr(
9868 InHandling inHandling, YieldHandling yieldHandling,
9869 TripledotHandling tripledotHandling,
9870 PossibleError* possibleError /* = nullptr */,
9871 InvokedPrediction invoked /* = PredictUninvoked */) {
9872 Node pn;
9873 MOZ_TRY_VAR(pn, assignExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
9874 possibleError, invoked))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
;
9875
9876 bool matched;
9877 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
9878 TokenStream::SlashIsRegExp)) {
9879 return errorResult();
9880 }
9881 if (!matched) {
9882 return pn;
9883 }
9884
9885 ListNodeType seq;
9886 MOZ_TRY_VAR(seq, handler_.newCommaExpressionList(pn))do { auto mozTryVarTempResult_ = (handler_.newCommaExpressionList
(pn)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr())
, 0))) { return mozTryVarTempResult_.propagateErr(); } (seq) =
mozTryVarTempResult_.unwrap(); } while (0)
;
9887 while (true) {
9888 // Trailing comma before the closing parenthesis is valid in an arrow
9889 // function parameters list: `(a, b, ) => body`. Check if we are
9890 // directly under CoverParenthesizedExpressionAndArrowParameterList,
9891 // and the next two tokens are closing parenthesis and arrow. If all
9892 // are present allow the trailing comma.
9893 if (tripledotHandling == TripledotAllowed) {
9894 TokenKind tt;
9895 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
9896 return errorResult();
9897 }
9898
9899 if (tt == TokenKind::RightParen) {
9900 tokenStream.consumeKnownToken(TokenKind::RightParen,
9901 TokenStream::SlashIsRegExp);
9902
9903 if (!tokenStream.peekToken(&tt)) {
9904 return errorResult();
9905 }
9906 if (tt != TokenKind::Arrow) {
9907 error(JSMSG_UNEXPECTED_TOKEN, "expression",
9908 TokenKindToDesc(TokenKind::RightParen));
9909 return errorResult();
9910 }
9911
9912 anyChars.ungetToken(); // put back right paren
9913 break;
9914 }
9915 }
9916
9917 // Additional calls to assignExpr should not reuse the possibleError
9918 // which had been passed into the function. Otherwise we would lose
9919 // information needed to determine whether or not we're dealing with
9920 // a non-recoverable situation.
9921 PossibleError possibleErrorInner(*this);
9922 MOZ_TRY_VAR(pn, assignExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
9923 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
;
9924
9925 if (!possibleError) {
9926 // Report any pending expression error.
9927 if (!possibleErrorInner.checkForExpressionError()) {
9928 return errorResult();
9929 }
9930 } else {
9931 possibleErrorInner.transferErrorsTo(possibleError);
9932 }
9933
9934 handler_.addList(seq, pn);
9935
9936 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
9937 TokenStream::SlashIsRegExp)) {
9938 return errorResult();
9939 }
9940 if (!matched) {
9941 break;
9942 }
9943 }
9944 return seq;
9945}
9946
9947static ParseNodeKind BinaryOpTokenKindToParseNodeKind(TokenKind tok) {
9948 MOZ_ASSERT(TokenKindIsBinaryOp(tok))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsBinaryOp(tok))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(TokenKindIsBinaryOp(tok)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsBinaryOp(tok)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9948); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsBinaryOp(tok)"
")"); do { *((volatile int*)__null) = 9948; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9949 return ParseNodeKind(size_t(ParseNodeKind::BinOpFirst) +
9950 (size_t(tok) - size_t(TokenKind::BinOpFirst)));
9951}
9952
9953// This list must be kept in the same order in several places:
9954// - The binary operators in ParseNode.h ,
9955// - the binary operators in TokenKind.h
9956// - the JSOp code list in BytecodeEmitter.cpp
9957static const int PrecedenceTable[] = {
9958 1, /* ParseNodeKind::Coalesce */
9959 2, /* ParseNodeKind::Or */
9960 3, /* ParseNodeKind::And */
9961 4, /* ParseNodeKind::BitOr */
9962 5, /* ParseNodeKind::BitXor */
9963 6, /* ParseNodeKind::BitAnd */
9964 7, /* ParseNodeKind::StrictEq */
9965 7, /* ParseNodeKind::Eq */
9966 7, /* ParseNodeKind::StrictNe */
9967 7, /* ParseNodeKind::Ne */
9968 8, /* ParseNodeKind::Lt */
9969 8, /* ParseNodeKind::Le */
9970 8, /* ParseNodeKind::Gt */
9971 8, /* ParseNodeKind::Ge */
9972 8, /* ParseNodeKind::InstanceOf */
9973 8, /* ParseNodeKind::In */
9974 8, /* ParseNodeKind::PrivateIn */
9975 9, /* ParseNodeKind::Lsh */
9976 9, /* ParseNodeKind::Rsh */
9977 9, /* ParseNodeKind::Ursh */
9978 10, /* ParseNodeKind::Add */
9979 10, /* ParseNodeKind::Sub */
9980 11, /* ParseNodeKind::Star */
9981 11, /* ParseNodeKind::Div */
9982 11, /* ParseNodeKind::Mod */
9983 12 /* ParseNodeKind::Pow */
9984};
9985
9986static const int PRECEDENCE_CLASSES = 12;
9987
9988static int Precedence(ParseNodeKind pnk) {
9989 // Everything binds tighter than ParseNodeKind::Limit, because we want
9990 // to reduce all nodes to a single node when we reach a token that is not
9991 // another binary operator.
9992 if (pnk == ParseNodeKind::Limit) {
9993 return 0;
9994 }
9995
9996 MOZ_ASSERT(pnk >= ParseNodeKind::BinOpFirst)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pnk >= ParseNodeKind::BinOpFirst)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pnk >= ParseNodeKind::BinOpFirst
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"pnk >= ParseNodeKind::BinOpFirst", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9996); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pnk >= ParseNodeKind::BinOpFirst"
")"); do { *((volatile int*)__null) = 9996; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9997 MOZ_ASSERT(pnk <= ParseNodeKind::BinOpLast)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pnk <= ParseNodeKind::BinOpLast)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pnk <= ParseNodeKind::BinOpLast
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"pnk <= ParseNodeKind::BinOpLast", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9997); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pnk <= ParseNodeKind::BinOpLast"
")"); do { *((volatile int*)__null) = 9997; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9998 return PrecedenceTable[size_t(pnk) - size_t(ParseNodeKind::BinOpFirst)];
9999}
10000
10001enum class EnforcedParentheses : uint8_t { CoalesceExpr, AndOrExpr, None };
10002
10003template <class ParseHandler, typename Unit>
10004MOZ_ALWAYS_INLINEinline typename ParseHandler::NodeResult
10005GeneralParser<ParseHandler, Unit>::orExpr(InHandling inHandling,
10006 YieldHandling yieldHandling,
10007 TripledotHandling tripledotHandling,
10008 PossibleError* possibleError,
10009 InvokedPrediction invoked) {
10010 // Shift-reduce parser for the binary operator part of the JS expression
10011 // syntax.
10012
10013 // Conceptually there's just one stack, a stack of pairs (lhs, op).
10014 // It's implemented using two separate arrays, though.
10015 Node nodeStack[PRECEDENCE_CLASSES];
10016 ParseNodeKind kindStack[PRECEDENCE_CLASSES];
10017 int depth = 0;
10018 Node pn;
10019 EnforcedParentheses unparenthesizedExpression = EnforcedParentheses::None;
10020 for (;;) {
10021 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked, PrivateNameHandling::PrivateNameAllowed
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
10022 pn, unaryExpr(yieldHandling, tripledotHandling, possibleError, invoked,do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked, PrivateNameHandling::PrivateNameAllowed
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
10023 PrivateNameHandling::PrivateNameAllowed))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked, PrivateNameHandling::PrivateNameAllowed
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10024
10025 // If a binary operator follows, consume it and compute the
10026 // corresponding operator.
10027 TokenKind tok;
10028 if (!tokenStream.getToken(&tok)) {
10029 return errorResult();
10030 }
10031
10032 // Ensure that if we have a private name lhs we are legally constructing a
10033 // `#x in obj` expessions:
10034 if (handler_.isPrivateName(pn)) {
10035 if (tok != TokenKind::In || inHandling != InAllowed) {
10036 error(JSMSG_ILLEGAL_PRIVATE_NAME);
10037 return errorResult();
10038 }
10039 }
10040
10041 ParseNodeKind pnk;
10042 if (tok == TokenKind::In ? inHandling == InAllowed
10043 : TokenKindIsBinaryOp(tok)) {
10044 // We're definitely not in a destructuring context, so report any
10045 // pending expression error now.
10046 if (possibleError && !possibleError->checkForExpressionError()) {
10047 return errorResult();
10048 }
10049
10050 bool isErgonomicBrandCheck = false;
10051 switch (tok) {
10052 // Report an error for unary expressions on the LHS of **.
10053 case TokenKind::Pow:
10054 if (handler_.isUnparenthesizedUnaryExpression(pn)) {
10055 error(JSMSG_BAD_POW_LEFTSIDE);
10056 return errorResult();
10057 }
10058 break;
10059
10060 case TokenKind::Or:
10061 case TokenKind::And:
10062 // In the case that the `??` is on the left hand side of the
10063 // expression: Disallow Mixing of ?? and other logical operators (||
10064 // and &&) unless one expression is parenthesized
10065 if (unparenthesizedExpression == EnforcedParentheses::CoalesceExpr) {
10066 error(JSMSG_BAD_COALESCE_MIXING);
10067 return errorResult();
10068 }
10069 // If we have not detected a mixing error at this point, record that
10070 // we have an unparenthesized expression, in case we have one later.
10071 unparenthesizedExpression = EnforcedParentheses::AndOrExpr;
10072 break;
10073
10074 case TokenKind::Coalesce:
10075 if (unparenthesizedExpression == EnforcedParentheses::AndOrExpr) {
10076 error(JSMSG_BAD_COALESCE_MIXING);
10077 return errorResult();
10078 }
10079 // If we have not detected a mixing error at this point, record that
10080 // we have an unparenthesized expression, in case we have one later.
10081 unparenthesizedExpression = EnforcedParentheses::CoalesceExpr;
10082 break;
10083
10084 case TokenKind::In:
10085 // if the LHS is a private name, and the operator is In,
10086 // ensure we're construcing an ergonomic brand check of
10087 // '#x in y', rather than having a higher precedence operator
10088 // like + cause a different reduction, such as
10089 // 1 + #x in y.
10090 if (handler_.isPrivateName(pn)) {
10091 if (depth > 0 && Precedence(kindStack[depth - 1]) >=
10092 Precedence(ParseNodeKind::InExpr)) {
10093 error(JSMSG_INVALID_PRIVATE_NAME_PRECEDENCE);
10094 return errorResult();
10095 }
10096
10097 isErgonomicBrandCheck = true;
10098 }
10099 break;
10100
10101 default:
10102 // do nothing in other cases
10103 break;
10104 }
10105
10106 if (isErgonomicBrandCheck) {
10107 pnk = ParseNodeKind::PrivateInExpr;
10108 } else {
10109 pnk = BinaryOpTokenKindToParseNodeKind(tok);
10110 }
10111
10112 } else {
10113 tok = TokenKind::Eof;
10114 pnk = ParseNodeKind::Limit;
10115 }
10116
10117 // From this point on, destructuring defaults are definitely an error.
10118 possibleError = nullptr;
10119
10120 // If pnk has precedence less than or equal to another operator on the
10121 // stack, reduce. This combines nodes on the stack until we form the
10122 // actual lhs of pnk.
10123 //
10124 // The >= in this condition works because it is appendOrCreateList's
10125 // job to decide if the operator in question is left- or
10126 // right-associative, and build the corresponding tree.
10127 while (depth > 0 && Precedence(kindStack[depth - 1]) >= Precedence(pnk)) {
10128 depth--;
10129 ParseNodeKind combiningPnk = kindStack[depth];
10130 MOZ_TRY_VAR(pn, handler_.appendOrCreateList(combiningPnk,do { auto mozTryVarTempResult_ = (handler_.appendOrCreateList
(combiningPnk, nodeStack[depth], pn, pc_)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
10131 nodeStack[depth], pn, pc_))do { auto mozTryVarTempResult_ = (handler_.appendOrCreateList
(combiningPnk, nodeStack[depth], pn, pc_)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
;
10132 }
10133
10134 if (pnk == ParseNodeKind::Limit) {
10135 break;
10136 }
10137
10138 nodeStack[depth] = pn;
10139 kindStack[depth] = pnk;
10140 depth++;
10141 MOZ_ASSERT(depth <= PRECEDENCE_CLASSES)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(depth <= PRECEDENCE_CLASSES)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(depth <= PRECEDENCE_CLASSES
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"depth <= PRECEDENCE_CLASSES", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10141); AnnotateMozCrashReason("MOZ_ASSERT" "(" "depth <= PRECEDENCE_CLASSES"
")"); do { *((volatile int*)__null) = 10141; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10142 }
10143
10144 anyChars.ungetToken();
10145
10146 // Had the next token been a Div, we would have consumed it. So there's no
10147 // ambiguity if we later (after ASI) re-get this token with SlashIsRegExp.
10148 anyChars.allowGettingNextTokenWithSlashIsRegExp();
10149
10150 MOZ_ASSERT(depth == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(depth == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(depth == 0))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("depth == 0", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10150); AnnotateMozCrashReason("MOZ_ASSERT" "(" "depth == 0"
")"); do { *((volatile int*)__null) = 10150; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10151 return pn;
10152}
10153
10154template <class ParseHandler, typename Unit>
10155MOZ_ALWAYS_INLINEinline typename ParseHandler::NodeResult
10156GeneralParser<ParseHandler, Unit>::condExpr(InHandling inHandling,
10157 YieldHandling yieldHandling,
10158 TripledotHandling tripledotHandling,
10159 PossibleError* possibleError,
10160 InvokedPrediction invoked) {
10161 Node condition;
10162 MOZ_TRY_VAR(condition, orExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (orExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (condition) = mozTryVarTempResult_.unwrap(
); } while (0)
10163 possibleError, invoked))do { auto mozTryVarTempResult_ = (orExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (condition) = mozTryVarTempResult_.unwrap(
); } while (0)
;
10164
10165 bool matched;
10166 if (!tokenStream.matchToken(&matched, TokenKind::Hook,
10167 TokenStream::SlashIsInvalid)) {
10168 return errorResult();
10169 }
10170 if (!matched) {
10171 return condition;
10172 }
10173
10174 Node thenExpr;
10175 MOZ_TRY_VAR(thenExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (thenExpr) = mozTryVarTempResult_.unwrap(); } while (0)
10176 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (thenExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
10177
10178 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_IN_COND)) {
10179 return errorResult();
10180 }
10181
10182 Node elseExpr;
10183 MOZ_TRY_VAR(elseExpr,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (elseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
10184 assignExpr(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (elseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
10185
10186 return handler_.newConditional(condition, thenExpr, elseExpr);
10187}
10188
10189template <class ParseHandler, typename Unit>
10190typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::assignExpr(
10191 InHandling inHandling, YieldHandling yieldHandling,
10192 TripledotHandling tripledotHandling,
10193 PossibleError* possibleError /* = nullptr */,
10194 InvokedPrediction invoked /* = PredictUninvoked */) {
10195 AutoCheckRecursionLimit recursion(this->fc_);
10196 if (!recursion.check(this->fc_)) {
10197 return errorResult();
10198 }
10199
10200 // It's very common at this point to have a "detectably simple" expression,
10201 // i.e. a name/number/string token followed by one of the following tokens
10202 // that obviously isn't part of an expression: , ; : ) ] }
10203 //
10204 // (In Parsemark this happens 81.4% of the time; in code with large
10205 // numeric arrays, such as some Kraken benchmarks, it happens more often.)
10206 //
10207 // In such cases, we can avoid the full expression parsing route through
10208 // assignExpr(), condExpr(), orExpr(), unaryExpr(), memberExpr(), and
10209 // primaryExpr().
10210
10211 TokenKind firstToken;
10212 if (!tokenStream.getToken(&firstToken, TokenStream::SlashIsRegExp)) {
10213 return errorResult();
10214 }
10215
10216 TokenPos exprPos = pos();
10217
10218 bool endsExpr;
10219
10220 // This only handles identifiers that *never* have special meaning anywhere
10221 // in the language. Contextual keywords, reserved words in strict mode,
10222 // and other hard cases are handled outside this fast path.
10223 if (firstToken == TokenKind::Name) {
10224 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10225 return errorResult();
10226 }
10227 if (endsExpr) {
10228 TaggedParserAtomIndex name = identifierReference(yieldHandling);
10229 if (!name) {
10230 return errorResult();
10231 }
10232
10233 return identifierReference(name);
10234 }
10235 }
10236
10237 if (firstToken == TokenKind::Number) {
10238 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10239 return errorResult();
10240 }
10241 if (endsExpr) {
10242 return newNumber(anyChars.currentToken());
10243 }
10244 }
10245
10246 if (firstToken == TokenKind::String) {
10247 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10248 return errorResult();
10249 }
10250 if (endsExpr) {
10251 return stringLiteral();
10252 }
10253 }
10254
10255 if (firstToken == TokenKind::Yield && yieldExpressionsSupported()) {
10256 return yieldExpression(inHandling);
10257 }
10258
10259 bool maybeAsyncArrow = false;
10260 if (firstToken == TokenKind::Async) {
10261 TokenKind nextSameLine = TokenKind::Eof;
10262 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
10263 return errorResult();
10264 }
10265
10266 if (TokenKindIsPossibleIdentifier(nextSameLine)) {
10267 maybeAsyncArrow = true;
10268 }
10269 }
10270
10271 anyChars.ungetToken();
10272
10273 // Save the tokenizer state in case we find an arrow function and have to
10274 // rewind.
10275 Position start(tokenStream);
10276 auto ghostToken = this->compilationState_.getPosition();
10277
10278 PossibleError possibleErrorInner(*this);
10279 Node lhs;
10280 TokenKind tokenAfterLHS;
10281 bool isArrow;
10282 if (maybeAsyncArrow) {
10283 tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::SlashIsRegExp);
10284
10285 TokenKind tokenAfterAsync;
10286 if (!tokenStream.getToken(&tokenAfterAsync)) {
10287 return errorResult();
10288 }
10289 MOZ_ASSERT(TokenKindIsPossibleIdentifier(tokenAfterAsync))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(tokenAfterAsync))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(tokenAfterAsync)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(tokenAfterAsync)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10289); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(tokenAfterAsync)"
")"); do { *((volatile int*)__null) = 10289; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10290
10291 // Check yield validity here.
10292 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
10293 if (!name) {
10294 return errorResult();
10295 }
10296
10297 if (!tokenStream.peekToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)) {
10298 return errorResult();
10299 }
10300
10301 isArrow = tokenAfterLHS == TokenKind::Arrow;
10302
10303 // |async [no LineTerminator] of| without being followed by => is only
10304 // possible in for-await-of loops, e.g. |for await (async of [])|. Pretend
10305 // the |async| token was parsed an identifier reference and then proceed
10306 // with the rest of this function.
10307 if (!isArrow) {
10308 anyChars.ungetToken(); // unget the binding identifier
10309
10310 // The next token is guaranteed to never be a Div (, because it's an
10311 // identifier), so it's okay to re-get the token with SlashIsRegExp.
10312 anyChars.allowGettingNextTokenWithSlashIsRegExp();
10313
10314 TaggedParserAtomIndex asyncName = identifierReference(yieldHandling);
10315 if (!asyncName) {
10316 return errorResult();
10317 }
10318
10319 MOZ_TRY_VAR(lhs, identifierReference(asyncName))do { auto mozTryVarTempResult_ = (identifierReference(asyncName
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10320 }
10321 } else {
10322 MOZ_TRY_VAR(lhs, condExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (condExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner, invoked)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
10323 &possibleErrorInner, invoked))do { auto mozTryVarTempResult_ = (condExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner, invoked)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10324
10325 // Use SlashIsRegExp here because the ConditionalExpression parsed above
10326 // could be the entirety of this AssignmentExpression, and then ASI
10327 // permits this token to be a regular expression.
10328 if (!tokenStream.peekToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)) {
10329 return errorResult();
10330 }
10331
10332 isArrow = tokenAfterLHS == TokenKind::Arrow;
10333 }
10334
10335 if (isArrow) {
10336 // Rewind to reparse as an arrow function.
10337 //
10338 // Note: We do not call CompilationState::rewind here because parsing
10339 // during delazification will see the same rewind and need the same sequence
10340 // of inner functions to skip over.
10341 // Instead, we mark inner functions as "ghost".
10342 //
10343 // See GHOST_FUNCTION in FunctionFlags.h for more details.
10344 tokenStream.rewind(start);
10345 this->compilationState_.markGhost(ghostToken);
10346
10347 TokenKind next;
10348 if (!tokenStream.getToken(&next, TokenStream::SlashIsRegExp)) {
10349 return errorResult();
10350 }
10351 TokenPos startPos = pos();
10352 uint32_t toStringStart = startPos.begin;
10353 anyChars.ungetToken();
10354
10355 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
10356
10357 if (next == TokenKind::Async) {
10358 tokenStream.consumeKnownToken(next, TokenStream::SlashIsRegExp);
10359
10360 TokenKind nextSameLine = TokenKind::Eof;
10361 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
10362 return errorResult();
10363 }
10364
10365 // The AsyncArrowFunction production are
10366 // async [no LineTerminator here] AsyncArrowBindingIdentifier ...
10367 // async [no LineTerminator here] ArrowFormalParameters ...
10368 if (TokenKindIsPossibleIdentifier(nextSameLine) ||
10369 nextSameLine == TokenKind::LeftParen) {
10370 asyncKind = FunctionAsyncKind::AsyncFunction;
10371 } else {
10372 anyChars.ungetToken();
10373 }
10374 }
10375
10376 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Arrow;
10377 FunctionNodeType funNode;
10378 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, startPos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, startPos)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10379
10380 return functionDefinition(funNode, toStringStart, inHandling, yieldHandling,
10381 TaggedParserAtomIndex::null(), syntaxKind,
10382 GeneratorKind::NotGenerator, asyncKind);
10383 }
10384
10385 MOZ_ALWAYS_TRUE(do { if ((__builtin_expect(!!(tokenStream.getToken(&tokenAfterLHS
, TokenStream::SlashIsRegExp)), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10386); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")"); do { *((volatile int*)__null) = 10386; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
10386 tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp))do { if ((__builtin_expect(!!(tokenStream.getToken(&tokenAfterLHS
, TokenStream::SlashIsRegExp)), 1))) { } else { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(false)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("false" " (" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10386); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")"); do { *((volatile int*)__null) = 10386; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
;
10387
10388 ParseNodeKind kind;
10389 switch (tokenAfterLHS) {
10390 case TokenKind::Assign:
10391 kind = ParseNodeKind::AssignExpr;
10392 break;
10393 case TokenKind::AddAssign:
10394 kind = ParseNodeKind::AddAssignExpr;
10395 break;
10396 case TokenKind::SubAssign:
10397 kind = ParseNodeKind::SubAssignExpr;
10398 break;
10399 case TokenKind::CoalesceAssign:
10400 kind = ParseNodeKind::CoalesceAssignExpr;
10401 break;
10402 case TokenKind::OrAssign:
10403 kind = ParseNodeKind::OrAssignExpr;
10404 break;
10405 case TokenKind::AndAssign:
10406 kind = ParseNodeKind::AndAssignExpr;
10407 break;
10408 case TokenKind::BitOrAssign:
10409 kind = ParseNodeKind::BitOrAssignExpr;
10410 break;
10411 case TokenKind::BitXorAssign:
10412 kind = ParseNodeKind::BitXorAssignExpr;
10413 break;
10414 case TokenKind::BitAndAssign:
10415 kind = ParseNodeKind::BitAndAssignExpr;
10416 break;
10417 case TokenKind::LshAssign:
10418 kind = ParseNodeKind::LshAssignExpr;
10419 break;
10420 case TokenKind::RshAssign:
10421 kind = ParseNodeKind::RshAssignExpr;
10422 break;
10423 case TokenKind::UrshAssign:
10424 kind = ParseNodeKind::UrshAssignExpr;
10425 break;
10426 case TokenKind::MulAssign:
10427 kind = ParseNodeKind::MulAssignExpr;
10428 break;
10429 case TokenKind::DivAssign:
10430 kind = ParseNodeKind::DivAssignExpr;
10431 break;
10432 case TokenKind::ModAssign:
10433 kind = ParseNodeKind::ModAssignExpr;
10434 break;
10435 case TokenKind::PowAssign:
10436 kind = ParseNodeKind::PowAssignExpr;
10437 break;
10438
10439 default:
10440 MOZ_ASSERT(!anyChars.isCurrentTokenAssignment())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!anyChars.isCurrentTokenAssignment())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!anyChars.isCurrentTokenAssignment
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!anyChars.isCurrentTokenAssignment()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10440); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!anyChars.isCurrentTokenAssignment()"
")"); do { *((volatile int*)__null) = 10440; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10441 if (!possibleError) {
10442 if (!possibleErrorInner.checkForExpressionError()) {
10443 return errorResult();
10444 }
10445 } else {
10446 possibleErrorInner.transferErrorsTo(possibleError);
10447 }
10448
10449 anyChars.ungetToken();
10450 return lhs;
10451 }
10452
10453 // Verify the left-hand side expression doesn't have a forbidden form.
10454 if (handler_.isUnparenthesizedDestructuringPattern(lhs)) {
10455 if (kind != ParseNodeKind::AssignExpr) {
10456 error(JSMSG_BAD_DESTRUCT_ASS);
10457 return errorResult();
10458 }
10459
10460 if (!possibleErrorInner.checkForDestructuringErrorOrWarning()) {
10461 return errorResult();
10462 }
10463 } else if (handler_.isName(lhs)) {
10464 if (const char* chars = nameIsArgumentsOrEval(lhs)) {
10465 // |chars| is "arguments" or "eval" here.
10466 if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_STRICT_ASSIGN, chars)) {
10467 return errorResult();
10468 }
10469 }
10470 } else if (handler_.isArgumentsLength(lhs)) {
10471 pc_->sc()->setIneligibleForArgumentsLength();
10472 } else if (handler_.isPropertyOrPrivateMemberAccess(lhs)) {
10473 // Permitted: no additional testing/fixup needed.
10474 } else if (handler_.isFunctionCall(lhs)) {
10475 // We don't have to worry about backward compatibility issues with the new
10476 // compound assignment operators, so we always throw here. Also that way we
10477 // don't have to worry if |f() &&= expr| should always throw an error or
10478 // only if |f()| returns true.
10479 if (kind == ParseNodeKind::CoalesceAssignExpr ||
10480 kind == ParseNodeKind::OrAssignExpr ||
10481 kind == ParseNodeKind::AndAssignExpr) {
10482 errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
10483 return errorResult();
10484 }
10485
10486 if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS)) {
10487 return errorResult();
10488 }
10489
10490 if (possibleError) {
10491 possibleError->setPendingDestructuringErrorAt(exprPos,
10492 JSMSG_BAD_DESTRUCT_TARGET);
10493 }
10494 } else {
10495 errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
10496 return errorResult();
10497 }
10498
10499 if (!possibleErrorInner.checkForExpressionError()) {
10500 return errorResult();
10501 }
10502
10503 Node rhs;
10504 MOZ_TRY_VAR(rhs, assignExpr(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
10505
10506 return handler_.newAssignment(kind, lhs, rhs);
10507}
10508
10509template <class ParseHandler>
10510const char* PerHandlerParser<ParseHandler>::nameIsArgumentsOrEval(Node node) {
10511 MOZ_ASSERT(handler_.isName(node),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(handler_.isName(node))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(handler_.isName(node)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("handler_.isName(node)"
" (" "must only call this function on known names" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10512); AnnotateMozCrashReason("MOZ_ASSERT" "(" "handler_.isName(node)"
") (" "must only call this function on known names" ")"); do
{ *((volatile int*)__null) = 10512; __attribute__((nomerge))
::abort(); } while (false); } } while (false)
10512 "must only call this function on known names")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(handler_.isName(node))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(handler_.isName(node)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("handler_.isName(node)"
" (" "must only call this function on known names" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10512); AnnotateMozCrashReason("MOZ_ASSERT" "(" "handler_.isName(node)"
") (" "must only call this function on known names" ")"); do
{ *((volatile int*)__null) = 10512; __attribute__((nomerge))
::abort(); } while (false); } } while (false)
;
10513
10514 if (handler_.isEvalName(node)) {
10515 return "eval";
10516 }
10517 if (handler_.isArgumentsName(node)) {
10518 return "arguments";
10519 }
10520 return nullptr;
10521}
10522
10523template <class ParseHandler, typename Unit>
10524bool GeneralParser<ParseHandler, Unit>::checkIncDecOperand(
10525 Node operand, uint32_t operandOffset) {
10526 if (handler_.isName(operand)) {
10527 if (const char* chars = nameIsArgumentsOrEval(operand)) {
10528 if (!strictModeErrorAt(operandOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) {
10529 return false;
10530 }
10531 }
10532 } else if (handler_.isArgumentsLength(operand)) {
10533 pc_->sc()->setIneligibleForArgumentsLength();
10534 } else if (handler_.isPropertyOrPrivateMemberAccess(operand)) {
10535 // Permitted: no additional testing/fixup needed.
10536 } else if (handler_.isFunctionCall(operand)) {
10537 // Assignment to function calls is forbidden in ES6. We're still
10538 // somewhat concerned about sites using this in dead code, so forbid it
10539 // only in strict mode code.
10540 if (!strictModeErrorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND)) {
10541 return false;
10542 }
10543 } else {
10544 errorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND);
10545 return false;
10546 }
10547 return true;
10548}
10549
10550template <class ParseHandler, typename Unit>
10551typename ParseHandler::UnaryNodeResult
10552GeneralParser<ParseHandler, Unit>::unaryOpExpr(YieldHandling yieldHandling,
10553 ParseNodeKind kind,
10554 uint32_t begin) {
10555 Node kid;
10556 MOZ_TRY_VAR(kid, unaryExpr(yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, TripledotProhibited
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (kid) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10557 return handler_.newUnary(kind, begin, kid);
10558}
10559
10560template <class ParseHandler, typename Unit>
10561typename ParseHandler::NodeResult
10562GeneralParser<ParseHandler, Unit>::optionalExpr(
10563 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10564 TokenKind tt, PossibleError* possibleError /* = nullptr */,
10565 InvokedPrediction invoked /* = PredictUninvoked */) {
10566 AutoCheckRecursionLimit recursion(this->fc_);
10567 if (!recursion.check(this->fc_)) {
10568 return errorResult();
10569 }
10570
10571 uint32_t begin = pos().begin;
10572
10573 Node lhs;
10574 MOZ_TRY_VAR(lhs,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, tripledotHandling
, tt, true, possibleError, invoked)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (lhs) = mozTryVarTempResult_.unwrap(); } while
(0)
10575 memberExpr(yieldHandling, tripledotHandling, tt,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, tripledotHandling
, tt, true, possibleError, invoked)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (lhs) = mozTryVarTempResult_.unwrap(); } while
(0)
10576 /* allowCallSyntax = */ true, possibleError, invoked))do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, tripledotHandling
, tt, true, possibleError, invoked)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (lhs) = mozTryVarTempResult_.unwrap(); } while
(0)
;
10577
10578 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsDiv)) {
10579 return errorResult();
10580 }
10581
10582 if (tt != TokenKind::OptionalChain) {
10583 return lhs;
10584 }
10585
10586 while (true) {
10587 if (!tokenStream.getToken(&tt)) {
10588 return errorResult();
10589 }
10590
10591 if (tt == TokenKind::Eof) {
10592 anyChars.ungetToken();
10593 break;
10594 }
10595
10596 Node nextMember;
10597 if (tt == TokenKind::OptionalChain) {
10598 if (!tokenStream.getToken(&tt)) {
10599 return errorResult();
10600 }
10601 if (TokenKindIsPossibleIdentifierName(tt)) {
10602 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
10603 memberPropertyAccess(lhs, OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10604 } else if (tt == TokenKind::PrivateName) {
10605 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
10606 memberPrivateAccess(lhs, OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10607 } else if (tt == TokenKind::LeftBracket) {
10608 MOZ_TRY_VAR(nextMember, memberElemAccess(lhs, yieldHandling,do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
, OptionalKind::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
10609 OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
, OptionalKind::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
;
10610 } else if (tt == TokenKind::LeftParen) {
10611 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError, OptionalKind::Optional)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nextMember) = mozTryVarTempResult_.unwrap
(); } while (0)
10612 memberCall(tt, lhs, yieldHandling, possibleError,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError, OptionalKind::Optional)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nextMember) = mozTryVarTempResult_.unwrap
(); } while (0)
10613 OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError, OptionalKind::Optional)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nextMember) = mozTryVarTempResult_.unwrap
(); } while (0)
;
10614 } else {
10615 error(JSMSG_NAME_AFTER_DOT);
10616 return errorResult();
10617 }
10618 } else if (tt == TokenKind::Dot) {
10619 if (!tokenStream.getToken(&tt)) {
10620 return errorResult();
10621 }
10622 if (TokenKindIsPossibleIdentifierName(tt)) {
10623 MOZ_TRY_VAR(nextMember, memberPropertyAccess(lhs))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nextMember)
= mozTryVarTempResult_.unwrap(); } while (0)
;
10624 } else if (tt == TokenKind::PrivateName) {
10625 MOZ_TRY_VAR(nextMember, memberPrivateAccess(lhs))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (nextMember) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10626 } else {
10627 error(JSMSG_NAME_AFTER_DOT);
10628 return errorResult();
10629 }
10630 } else if (tt == TokenKind::LeftBracket) {
10631 MOZ_TRY_VAR(nextMember, memberElemAccess(lhs, yieldHandling))do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10632 } else if (tt == TokenKind::LeftParen) {
10633 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
10634 memberCall(tt, lhs, yieldHandling, possibleError))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
;
10635 } else if (tt == TokenKind::TemplateHead ||
10636 tt == TokenKind::NoSubsTemplate) {
10637 error(JSMSG_BAD_OPTIONAL_TEMPLATE);
10638 return errorResult();
10639 } else {
10640 anyChars.ungetToken();
10641 break;
10642 }
10643
10644 MOZ_ASSERT(nextMember)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nextMember)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nextMember))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("nextMember", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10644); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nextMember"
")"); do { *((volatile int*)__null) = 10644; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10645 lhs = nextMember;
10646 }
10647
10648 return handler_.newOptionalChain(begin, lhs);
10649}
10650
10651template <class ParseHandler, typename Unit>
10652typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::unaryExpr(
10653 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10654 PossibleError* possibleError /* = nullptr */,
10655 InvokedPrediction invoked /* = PredictUninvoked */,
10656 PrivateNameHandling privateNameHandling /* = PrivateNameProhibited */) {
10657 AutoCheckRecursionLimit recursion(this->fc_);
10658 if (!recursion.check(this->fc_)) {
10659 return errorResult();
10660 }
10661
10662 TokenKind tt;
10663 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
10664 return errorResult();
10665 }
10666 uint32_t begin = pos().begin;
10667 switch (tt) {
10668 case TokenKind::Void:
10669 return unaryOpExpr(yieldHandling, ParseNodeKind::VoidExpr, begin);
10670 case TokenKind::Not:
10671 return unaryOpExpr(yieldHandling, ParseNodeKind::NotExpr, begin);
10672 case TokenKind::BitNot:
10673 return unaryOpExpr(yieldHandling, ParseNodeKind::BitNotExpr, begin);
10674 case TokenKind::Add:
10675 return unaryOpExpr(yieldHandling, ParseNodeKind::PosExpr, begin);
10676 case TokenKind::Sub:
10677 return unaryOpExpr(yieldHandling, ParseNodeKind::NegExpr, begin);
10678
10679 case TokenKind::TypeOf: {
10680 // The |typeof| operator is specially parsed to distinguish its
10681 // application to a name, from its application to a non-name
10682 // expression:
10683 //
10684 // // Looks up the name, doesn't find it and so evaluates to
10685 // // "undefined".
10686 // assertEq(typeof nonExistentName, "undefined");
10687 //
10688 // // Evaluates expression, triggering a runtime ReferenceError for
10689 // // the undefined name.
10690 // typeof (1, nonExistentName);
10691 Node kid;
10692 MOZ_TRY_VAR(kid, unaryExpr(yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, TripledotProhibited
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (kid) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10693
10694 return handler_.newTypeof(begin, kid);
10695 }
10696
10697 case TokenKind::Inc:
10698 case TokenKind::Dec: {
10699 TokenKind tt2;
10700 if (!tokenStream.getToken(&tt2, TokenStream::SlashIsRegExp)) {
10701 return errorResult();
10702 }
10703
10704 uint32_t operandOffset = pos().begin;
10705 Node operand;
10706 MOZ_TRY_VAR(operand,do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt2)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (operand) = mozTryVarTempResult_.unwrap(); } while (0)
10707 optionalExpr(yieldHandling, TripledotProhibited, tt2))do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt2)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (operand) = mozTryVarTempResult_.unwrap(); } while (0)
;
10708 if (!checkIncDecOperand(operand, operandOffset)) {
10709 return errorResult();
10710 }
10711 ParseNodeKind pnk = (tt == TokenKind::Inc)
10712 ? ParseNodeKind::PreIncrementExpr
10713 : ParseNodeKind::PreDecrementExpr;
10714 return handler_.newUpdate(pnk, begin, operand);
10715 }
10716 case TokenKind::PrivateName: {
10717 if (privateNameHandling == PrivateNameHandling::PrivateNameAllowed) {
10718 TaggedParserAtomIndex field = anyChars.currentName();
10719 return privateNameReference(field);
10720 }
10721 error(JSMSG_INVALID_PRIVATE_NAME_IN_UNARY_EXPR);
10722 return errorResult();
10723 }
10724
10725 case TokenKind::Delete: {
10726 uint32_t exprOffset;
10727 if (!tokenStream.peekOffset(&exprOffset, TokenStream::SlashIsRegExp)) {
10728 return errorResult();
10729 }
10730
10731 Node expr;
10732 MOZ_TRY_VAR(expr, unaryExpr(yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, TripledotProhibited
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (expr) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10733
10734 // Per spec, deleting most unary expressions is valid -- it simply
10735 // returns true -- except for two cases:
10736 // 1. `var x; ...; delete x` is a syntax error in strict mode.
10737 // 2. Private fields cannot be deleted.
10738 if (handler_.isName(expr)) {
10739 if (!strictModeErrorAt(exprOffset, JSMSG_DEPRECATED_DELETE_OPERAND)) {
10740 return errorResult();
10741 }
10742
10743 pc_->sc()->setBindingsAccessedDynamically();
10744 }
10745
10746 if (handler_.isPrivateMemberAccess(expr)) {
10747 errorAt(exprOffset, JSMSG_PRIVATE_DELETE);
10748 return errorResult();
10749 }
10750
10751 return handler_.newDelete(begin, expr);
10752 }
10753 case TokenKind::Await: {
10754 // If we encounter an await in a module, mark it as async.
10755 if (!pc_->isAsync() && pc_->sc()->isModule()) {
10756 if (!options().topLevelAwait) {
10757 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
10758 return errorResult();
10759 }
10760 pc_->sc()->asModuleContext()->setIsAsync();
10761 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10761); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 10761; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10762 }
10763
10764 if (pc_->isAsync()) {
10765 if (inParametersOfAsyncFunction()) {
10766 error(JSMSG_AWAIT_IN_PARAMETER);
10767 return errorResult();
10768 }
10769 Node kid;
10770 MOZ_TRY_VAR(kid, unaryExpr(yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
10771 possibleError, invoked))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
10772 pc_->lastAwaitOffset = begin;
10773 return handler_.newAwaitExpression(begin, kid);
10774 }
10775 }
10776
10777 [[fallthrough]];
10778
10779 default: {
10780 Node expr;
10781 MOZ_TRY_VAR(expr, optionalExpr(yieldHandling, tripledotHandling, tt,do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
tripledotHandling, tt, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
10782 possibleError, invoked))do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
tripledotHandling, tt, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
10783
10784 /* Don't look across a newline boundary for a postfix incop. */
10785 if (!tokenStream.peekTokenSameLine(&tt)) {
10786 return errorResult();
10787 }
10788
10789 if (tt != TokenKind::Inc && tt != TokenKind::Dec) {
10790 return expr;
10791 }
10792
10793 tokenStream.consumeKnownToken(tt);
10794 if (!checkIncDecOperand(expr, begin)) {
10795 return errorResult();
10796 }
10797
10798 ParseNodeKind pnk = (tt == TokenKind::Inc)
10799 ? ParseNodeKind::PostIncrementExpr
10800 : ParseNodeKind::PostDecrementExpr;
10801 return handler_.newUpdate(pnk, begin, expr);
10802 }
10803 }
10804}
10805
10806template <class ParseHandler, typename Unit>
10807typename ParseHandler::NodeResult
10808GeneralParser<ParseHandler, Unit>::assignExprWithoutYieldOrAwait(
10809 YieldHandling yieldHandling) {
10810 uint32_t startYieldOffset = pc_->lastYieldOffset;
10811 uint32_t startAwaitOffset = pc_->lastAwaitOffset;
10812
10813 Node res;
10814 MOZ_TRY_VAR(res, assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (res) = mozTryVarTempResult_.unwrap(); } while (0)
;
10815
10816 if (pc_->lastYieldOffset != startYieldOffset) {
10817 errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
10818 return errorResult();
10819 }
10820 if (pc_->lastAwaitOffset != startAwaitOffset) {
10821 errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
10822 return errorResult();
10823 }
10824 return res;
10825}
10826
10827template <class ParseHandler, typename Unit>
10828typename ParseHandler::ListNodeResult
10829GeneralParser<ParseHandler, Unit>::argumentList(
10830 YieldHandling yieldHandling, bool* isSpread,
10831 PossibleError* possibleError /* = nullptr */) {
10832 ListNodeType argsList;
10833 MOZ_TRY_VAR(argsList, handler_.newArguments(pos()))do { auto mozTryVarTempResult_ = (handler_.newArguments(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10834
10835 bool matched;
10836 if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
10837 TokenStream::SlashIsRegExp)) {
10838 return errorResult();
10839 }
10840 if (matched) {
10841 handler_.setEndPosition(argsList, pos().end);
10842 return argsList;
10843 }
10844
10845 while (true) {
10846 bool spread = false;
10847 uint32_t begin = 0;
10848 if (!tokenStream.matchToken(&matched, TokenKind::TripleDot,
10849 TokenStream::SlashIsRegExp)) {
10850 return errorResult();
10851 }
10852 if (matched) {
10853 spread = true;
10854 begin = pos().begin;
10855 *isSpread = true;
10856 }
10857
10858 Node argNode;
10859 MOZ_TRY_VAR(argNode, assignExpr(InAllowed, yieldHandling,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, possibleError)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (argNode) = mozTryVarTempResult_.unwrap();
} while (0)
10860 TripledotProhibited, possibleError))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, possibleError)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (argNode) = mozTryVarTempResult_.unwrap();
} while (0)
;
10861 if (spread) {
10862 MOZ_TRY_VAR(argNode, handler_.newSpread(begin, argNode))do { auto mozTryVarTempResult_ = (handler_.newSpread(begin, argNode
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argNode)
= mozTryVarTempResult_.unwrap(); } while (0)
;
10863 }
10864
10865 handler_.addList(argsList, argNode);
10866
10867 bool matched;
10868 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
10869 TokenStream::SlashIsRegExp)) {
10870 return errorResult();
10871 }
10872 if (!matched) {
10873 break;
10874 }
10875
10876 TokenKind tt;
10877 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
10878 return errorResult();
10879 }
10880 if (tt == TokenKind::RightParen) {
10881 break;
10882 }
10883 }
10884
10885 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_ARGS)) {
10886 return errorResult();
10887 }
10888
10889 handler_.setEndPosition(argsList, pos().end);
10890 return argsList;
10891}
10892
10893bool ParserBase::checkAndMarkSuperScope() {
10894 if (!pc_->sc()->allowSuperProperty()) {
10895 return false;
10896 }
10897
10898 pc_->setSuperScopeNeedsHomeObject();
10899 return true;
10900}
10901
10902template <class ParseHandler, typename Unit>
10903bool GeneralParser<ParseHandler, Unit>::computeErrorMetadata(
10904 ErrorMetadata* err, const ErrorReportMixin::ErrorOffset& offset) const {
10905 if (offset.is<ErrorReportMixin::Current>()) {
10906 return tokenStream.computeErrorMetadata(err, AsVariant(pos().begin));
10907 }
10908 return tokenStream.computeErrorMetadata(err, offset);
10909}
10910
10911template <class ParseHandler, typename Unit>
10912typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::memberExpr(
10913 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10914 TokenKind tt, bool allowCallSyntax, PossibleError* possibleError,
10915 InvokedPrediction invoked) {
10916 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10916); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 10916; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10917
10918 Node lhs;
10919
10920 AutoCheckRecursionLimit recursion(this->fc_);
10921 if (!recursion.check(this->fc_)) {
10922 return errorResult();
10923 }
10924
10925 /* Check for new expression first. */
10926 if (tt == TokenKind::New) {
10927 uint32_t newBegin = pos().begin;
10928 // Make sure this wasn't a |new.target| in disguise.
10929 NewTargetNodeType newTarget;
10930 if (!tryNewTarget(&newTarget)) {
10931 return errorResult();
10932 }
10933 if (newTarget) {
10934 lhs = newTarget;
10935 } else {
10936 // Gotten by tryNewTarget
10937 tt = anyChars.currentToken().type;
10938 Node ctorExpr;
10939 MOZ_TRY_VAR(ctorExpr,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
10940 memberExpr(yieldHandling, TripledotProhibited, tt,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
10941 /* allowCallSyntax = */ false,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
10942 /* possibleError = */ nullptr, PredictInvoked))do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
;
10943
10944 // If we have encountered an optional chain, in the form of `new
10945 // ClassName?.()` then we need to throw, as this is disallowed by the
10946 // spec.
10947 bool optionalToken;
10948 if (!tokenStream.matchToken(&optionalToken, TokenKind::OptionalChain)) {
10949 return errorResult();
10950 }
10951 if (optionalToken) {
10952 errorAt(newBegin, JSMSG_BAD_NEW_OPTIONAL);
10953 return errorResult();
10954 }
10955
10956 bool matched;
10957 if (!tokenStream.matchToken(&matched, TokenKind::LeftParen)) {
10958 return errorResult();
10959 }
10960
10961 bool isSpread = false;
10962 ListNodeType args;
10963 if (matched) {
10964 MOZ_TRY_VAR(args, argumentList(yieldHandling, &isSpread))do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (args) = mozTryVarTempResult_.unwrap(); } while (0)
;
10965 } else {
10966 MOZ_TRY_VAR(args, handler_.newArguments(pos()))do { auto mozTryVarTempResult_ = (handler_.newArguments(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (args) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10967 }
10968
10969 if (!args) {
10970 return errorResult();
10971 }
10972
10973 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (handler_.newNewExpression(newBegin
, ctorExpr, args, isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
10974 lhs, handler_.newNewExpression(newBegin, ctorExpr, args, isSpread))do { auto mozTryVarTempResult_ = (handler_.newNewExpression(newBegin
, ctorExpr, args, isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
10975 }
10976 } else if (tt == TokenKind::Super) {
10977 NameNodeType thisName;
10978 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
10979 MOZ_TRY_VAR(lhs, handler_.newSuperBase(thisName, pos()))do { auto mozTryVarTempResult_ = (handler_.newSuperBase(thisName
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (lhs
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10980 } else if (tt == TokenKind::Import) {
10981 MOZ_TRY_VAR(lhs, importExpr(yieldHandling, allowCallSyntax))do { auto mozTryVarTempResult_ = (importExpr(yieldHandling, allowCallSyntax
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10982 } else {
10983 MOZ_TRY_VAR(lhs, primaryExpr(yieldHandling, tripledotHandling, tt,do { auto mozTryVarTempResult_ = (primaryExpr(yieldHandling, tripledotHandling
, tt, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
10984 possibleError, invoked))do { auto mozTryVarTempResult_ = (primaryExpr(yieldHandling, tripledotHandling
, tt, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
10985 }
10986
10987 MOZ_ASSERT_IF(handler_.isSuperBase(lhs),do { if (handler_.isSuperBase(lhs)) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Super))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Super)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Super)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10988); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Super)"
")"); do { *((volatile int*)__null) = 10988; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
10988 anyChars.isCurrentTokenType(TokenKind::Super))do { if (handler_.isSuperBase(lhs)) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Super))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Super)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Super)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10988); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Super)"
")"); do { *((volatile int*)__null) = 10988; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
;
10989
10990 while (true) {
10991 if (!tokenStream.getToken(&tt)) {
10992 return errorResult();
10993 }
10994 if (tt == TokenKind::Eof) {
10995 anyChars.ungetToken();
10996 break;
10997 }
10998
10999 Node nextMember;
11000 if (tt == TokenKind::Dot) {
11001 if (!tokenStream.getToken(&tt)) {
11002 return errorResult();
11003 }
11004
11005 if (TokenKindIsPossibleIdentifierName(tt)) {
11006 MOZ_TRY_VAR(nextMember, memberPropertyAccess(lhs))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nextMember)
= mozTryVarTempResult_.unwrap(); } while (0)
;
11007 } else if (tt == TokenKind::PrivateName) {
11008 MOZ_TRY_VAR(nextMember, memberPrivateAccess(lhs))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (nextMember) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11009 } else {
11010 error(JSMSG_NAME_AFTER_DOT);
11011 return errorResult();
11012 }
11013 } else if (tt == TokenKind::LeftBracket) {
11014 MOZ_TRY_VAR(nextMember, memberElemAccess(lhs, yieldHandling))do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11015 } else if ((allowCallSyntax && tt == TokenKind::LeftParen) ||
11016 tt == TokenKind::TemplateHead ||
11017 tt == TokenKind::NoSubsTemplate) {
11018 if (handler_.isSuperBase(lhs)) {
11019 if (!pc_->sc()->allowSuperCall()) {
11020 error(JSMSG_BAD_SUPERCALL);
11021 return errorResult();
11022 }
11023
11024 if (tt != TokenKind::LeftParen) {
11025 error(JSMSG_BAD_SUPER);
11026 return errorResult();
11027 }
11028
11029 MOZ_TRY_VAR(nextMember, memberSuperCall(lhs, yieldHandling))do { auto mozTryVarTempResult_ = (memberSuperCall(lhs, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11030
11031 if (!noteUsedName(
11032 TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
11033 return errorResult();
11034 }
11035#ifdef ENABLE_DECORATORS
11036 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
11037 dot_instanceExtraInitializers_())) {
11038 return null();
11039 }
11040#endif
11041 } else {
11042 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
11043 memberCall(tt, lhs, yieldHandling, possibleError))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
;
11044 }
11045 } else {
11046 anyChars.ungetToken();
11047 if (handler_.isSuperBase(lhs)) {
11048 break;
11049 }
11050 return lhs;
11051 }
11052
11053 lhs = nextMember;
11054 }
11055
11056 if (handler_.isSuperBase(lhs)) {
11057 error(JSMSG_BAD_SUPER);
11058 return errorResult();
11059 }
11060
11061 return lhs;
11062}
11063
11064template <class ParseHandler, typename Unit>
11065typename ParseHandler::NodeResult
11066GeneralParser<ParseHandler, Unit>::decoratorExpr(YieldHandling yieldHandling,
11067 TokenKind tt) {
11068 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11068); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 11068; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11069
11070 AutoCheckRecursionLimit recursion(this->fc_);
11071 if (!recursion.check(this->fc_)) {
11072 return errorResult();
11073 }
11074
11075 if (tt == TokenKind::LeftParen) {
11076 // DecoratorParenthesizedExpression
11077 Node expr;
11078 MOZ_TRY_VAR(expr, exprInParens(InAllowed, yieldHandling, TripledotAllowed,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (expr) = mozTryVarTempResult_.unwrap(); } while (0)
11079 /* possibleError*/ nullptr))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (expr) = mozTryVarTempResult_.unwrap(); } while (0)
;
11080 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_DECORATOR)) {
11081 return errorResult();
11082 }
11083
11084 return handler_.parenthesize(expr);
11085 }
11086
11087 if (!TokenKindIsPossibleIdentifier(tt)) {
11088 error(JSMSG_DECORATOR_NAME_EXPECTED);
11089 return errorResult();
11090 }
11091
11092 TaggedParserAtomIndex name = identifierReference(yieldHandling);
11093 if (!name) {
11094 return errorResult();
11095 }
11096
11097 Node lhs;
11098 MOZ_TRY_VAR(lhs, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11099
11100 while (true) {
11101 if (!tokenStream.getToken(&tt)) {
11102 return errorResult();
11103 }
11104 if (tt == TokenKind::Eof) {
11105 anyChars.ungetToken();
11106 break;
11107 }
11108
11109 Node nextMember;
11110 if (tt == TokenKind::Dot) {
11111 if (!tokenStream.getToken(&tt)) {
11112 return errorResult();
11113 }
11114
11115 if (TokenKindIsPossibleIdentifierName(tt)) {
11116 MOZ_TRY_VAR(nextMember, memberPropertyAccess(lhs))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nextMember)
= mozTryVarTempResult_.unwrap(); } while (0)
;
11117 } else if (tt == TokenKind::PrivateName) {
11118 MOZ_TRY_VAR(nextMember, memberPrivateAccess(lhs))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (nextMember) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11119 } else {
11120 error(JSMSG_NAME_AFTER_DOT);
11121 return errorResult();
11122 }
11123 } else if (tt == TokenKind::LeftParen) {
11124 MOZ_TRY_VAR(nextMember, memberCall(tt, lhs, yieldHandling,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
11125 /* possibleError */ nullptr))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11126 lhs = nextMember;
11127 // This is a `DecoratorCallExpression` and it's defined at the top level
11128 // of `Decorator`, no other `DecoratorMemberExpression` is allowed to
11129 // follow after the arguments.
11130 break;
11131 } else {
11132 anyChars.ungetToken();
11133 break;
11134 }
11135
11136 lhs = nextMember;
11137 }
11138
11139 return lhs;
11140}
11141
11142template <class ParseHandler>
11143inline typename ParseHandler::NameNodeResult
11144PerHandlerParser<ParseHandler>::newName(TaggedParserAtomIndex name) {
11145 return newName(name, pos());
11146}
11147
11148template <class ParseHandler>
11149inline typename ParseHandler::NameNodeResult
11150PerHandlerParser<ParseHandler>::newName(TaggedParserAtomIndex name,
11151 TokenPos pos) {
11152 if (name == TaggedParserAtomIndex::WellKnown::arguments()) {
11153 this->pc_->numberOfArgumentsNames++;
11154 }
11155 return handler_.newName(name, pos);
11156}
11157
11158template <class ParseHandler>
11159inline typename ParseHandler::NameNodeResult
11160PerHandlerParser<ParseHandler>::newPrivateName(TaggedParserAtomIndex name) {
11161 return handler_.newPrivateName(name, pos());
11162}
11163
11164template <class ParseHandler, typename Unit>
11165typename ParseHandler::NodeResult
11166GeneralParser<ParseHandler, Unit>::memberPropertyAccess(
11167 Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11168 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11169); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11169; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
11169 anyChars.currentToken().type == TokenKind::PrivateName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11169); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11169; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11170 TaggedParserAtomIndex field = anyChars.currentName();
11171 if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
11172 error(JSMSG_BAD_SUPERPROP, "property");
11173 return errorResult();
11174 }
11175
11176 NameNodeType name;
11177 MOZ_TRY_VAR(name, handler_.newPropertyName(field, pos()))do { auto mozTryVarTempResult_ = (handler_.newPropertyName(field
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (name
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11178
11179 if (optionalKind == OptionalKind::Optional) {
11180 MOZ_ASSERT(!handler_.isSuperBase(lhs))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!handler_.isSuperBase(lhs))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!handler_.isSuperBase(lhs)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!handler_.isSuperBase(lhs)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11180); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11180; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11181 return handler_.newOptionalPropertyAccess(lhs, name);
11182 }
11183
11184 if (handler_.isArgumentsName(lhs) && handler_.isLengthName(name)) {
11185 MOZ_ASSERT(pc_->numberOfArgumentsNames > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->numberOfArgumentsNames > 0)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(pc_->numberOfArgumentsNames > 0))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->numberOfArgumentsNames > 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11185); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->numberOfArgumentsNames > 0"
")"); do { *((volatile int*)__null) = 11185; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11186 pc_->numberOfArgumentsNames--;
11187 // Currently when resuming Generators don't get their argument length set
11188 // in the interpreter frame (see InterpreterStack::resumeGeneratorCallFrame,
11189 // and its call to initCallFrame).
11190 if (pc_->isGeneratorOrAsync()) {
11191 pc_->sc()->setIneligibleForArgumentsLength();
11192 }
11193 return handler_.newArgumentsLength(lhs, name);
11194 }
11195
11196 return handler_.newPropertyAccess(lhs, name);
11197}
11198
11199template <class ParseHandler, typename Unit>
11200typename ParseHandler::NodeResult
11201GeneralParser<ParseHandler, Unit>::memberPrivateAccess(
11202 Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11203 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::PrivateName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::PrivateName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::PrivateName
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"anyChars.currentToken().type == TokenKind::PrivateName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11203); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11203; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11204
11205 TaggedParserAtomIndex field = anyChars.currentName();
11206 // Cannot access private fields on super.
11207 if (handler_.isSuperBase(lhs)) {
11208 error(JSMSG_BAD_SUPERPRIVATE);
11209 return errorResult();
11210 }
11211
11212 NameNodeType privateName;
11213 MOZ_TRY_VAR(privateName, privateNameReference(field))do { auto mozTryVarTempResult_ = (privateNameReference(field)
); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)
)) { return mozTryVarTempResult_.propagateErr(); } (privateName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11214
11215 if (optionalKind == OptionalKind::Optional) {
11216 MOZ_ASSERT(!handler_.isSuperBase(lhs))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!handler_.isSuperBase(lhs))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!handler_.isSuperBase(lhs)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!handler_.isSuperBase(lhs)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11216); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11216; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11217 return handler_.newOptionalPrivateMemberAccess(lhs, privateName, pos().end);
11218 }
11219 return handler_.newPrivateMemberAccess(lhs, privateName, pos().end);
11220}
11221
11222template <class ParseHandler, typename Unit>
11223typename ParseHandler::NodeResult
11224GeneralParser<ParseHandler, Unit>::memberElemAccess(
11225 Node lhs, YieldHandling yieldHandling,
11226 OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11227 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::LeftBracket)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::LeftBracket
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::LeftBracket
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"anyChars.currentToken().type == TokenKind::LeftBracket", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11227); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::LeftBracket"
")"); do { *((volatile int*)__null) = 11227; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11228 Node propExpr;
11229 MOZ_TRY_VAR(propExpr, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
11230
11231 if (!mustMatchToken(TokenKind::RightBracket, JSMSG_BRACKET_IN_INDEX)) {
11232 return errorResult();
11233 }
11234
11235 if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
11236 error(JSMSG_BAD_SUPERPROP, "member");
11237 return errorResult();
11238 }
11239 if (optionalKind == OptionalKind::Optional) {
11240 MOZ_ASSERT(!handler_.isSuperBase(lhs))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!handler_.isSuperBase(lhs))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!handler_.isSuperBase(lhs)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!handler_.isSuperBase(lhs)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11240); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11240; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11241 return handler_.newOptionalPropertyByValue(lhs, propExpr, pos().end);
11242 }
11243 return handler_.newPropertyByValue(lhs, propExpr, pos().end);
11244}
11245
11246template <class ParseHandler, typename Unit>
11247typename ParseHandler::NodeResult
11248GeneralParser<ParseHandler, Unit>::memberSuperCall(
11249 Node lhs, YieldHandling yieldHandling) {
11250 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::LeftParen)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::LeftParen
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::LeftParen
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"anyChars.currentToken().type == TokenKind::LeftParen", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11250); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::LeftParen"
")"); do { *((volatile int*)__null) = 11250; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11251 // Despite the fact that it's impossible to have |super()| in a
11252 // generator, we still inherit the yieldHandling of the
11253 // memberExpression, per spec. Curious.
11254 bool isSpread = false;
11255 ListNodeType args;
11256 MOZ_TRY_VAR(args, argumentList(yieldHandling, &isSpread))do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (args) = mozTryVarTempResult_.unwrap(); } while (0)
;
11257
11258 CallNodeType superCall;
11259 MOZ_TRY_VAR(superCall, handler_.newSuperCall(lhs, args, isSpread))do { auto mozTryVarTempResult_ = (handler_.newSuperCall(lhs, args
, isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (superCall
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11260
11261 // |super()| implicitly reads |new.target|.
11262 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
11263 return errorResult();
11264 }
11265
11266 NameNodeType thisName;
11267 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
11268
11269 return handler_.newSetThis(thisName, superCall);
11270}
11271
11272template <class ParseHandler, typename Unit>
11273typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::memberCall(
11274 TokenKind tt, Node lhs, YieldHandling yieldHandling,
11275 PossibleError* possibleError /* = nullptr */,
11276 OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11277 if (options().selfHostingMode &&
11278 (handler_.isPropertyOrPrivateMemberAccess(lhs) ||
11279 handler_.isOptionalPropertyOrPrivateMemberAccess(lhs))) {
11280 error(JSMSG_SELFHOSTED_METHOD_CALL);
11281 return errorResult();
11282 }
11283
11284 MOZ_ASSERT(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead
|| tt == TokenKind::NoSubsTemplate)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::LeftParen ||
tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
" (" "Unexpected token kind for member call" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11286; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
11285 tt == TokenKind::NoSubsTemplate,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead
|| tt == TokenKind::NoSubsTemplate)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::LeftParen ||
tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
" (" "Unexpected token kind for member call" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11286; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
11286 "Unexpected token kind for member call")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead
|| tt == TokenKind::NoSubsTemplate)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::LeftParen ||
tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
" (" "Unexpected token kind for member call" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11286; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
11287
11288 JSOp op = JSOp::Call;
11289 bool maybeAsyncArrow = false;
11290 if (tt == TokenKind::LeftParen && optionalKind == OptionalKind::NonOptional) {
11291 if (handler_.isAsyncKeyword(lhs)) {
11292 // |async (| can be the start of an async arrow
11293 // function, so we need to defer reporting possible
11294 // errors from destructuring syntax. To give better
11295 // error messages, we only allow the AsyncArrowHead
11296 // part of the CoverCallExpressionAndAsyncArrowHead
11297 // syntax when the initial name is "async".
11298 maybeAsyncArrow = true;
11299 } else if (handler_.isEvalName(lhs)) {
11300 // Select the right Eval op and flag pc_ as having a
11301 // direct eval.
11302 op = pc_->sc()->strict() ? JSOp::StrictEval : JSOp::Eval;
11303 pc_->sc()->setBindingsAccessedDynamically();
11304 pc_->sc()->setHasDirectEval();
11305
11306 // In non-strict mode code, direct calls to eval can
11307 // add variables to the call object.
11308 if (pc_->isFunctionBox() && !pc_->sc()->strict()) {
11309 pc_->functionBox()->setFunHasExtensibleScope();
11310 }
11311
11312 // If we're in a method, mark the method as requiring
11313 // support for 'super', since direct eval code can use
11314 // it. (If we're not in a method, that's fine, so
11315 // ignore the return value.)
11316 checkAndMarkSuperScope();
11317 }
11318 }
11319
11320 if (tt == TokenKind::LeftParen) {
11321 bool isSpread = false;
11322 PossibleError* asyncPossibleError =
11323 maybeAsyncArrow ? possibleError : nullptr;
11324 ListNodeType args;
11325 MOZ_TRY_VAR(args,do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread, asyncPossibleError)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (args) = mozTryVarTempResult_.unwrap(); } while
(0)
11326 argumentList(yieldHandling, &isSpread, asyncPossibleError))do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread, asyncPossibleError)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (args) = mozTryVarTempResult_.unwrap(); } while
(0)
;
11327 if (isSpread) {
11328 if (op == JSOp::Eval) {
11329 op = JSOp::SpreadEval;
11330 } else if (op == JSOp::StrictEval) {
11331 op = JSOp::StrictSpreadEval;
11332 } else {
11333 op = JSOp::SpreadCall;
11334 }
11335 }
11336
11337 if (optionalKind == OptionalKind::Optional) {
11338 return handler_.newOptionalCall(lhs, args, op);
11339 }
11340 return handler_.newCall(lhs, args, op);
11341 }
11342
11343 ListNodeType args;
11344 MOZ_TRY_VAR(args, handler_.newArguments(pos()))do { auto mozTryVarTempResult_ = (handler_.newArguments(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (args) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11345
11346 if (!taggedTemplate(yieldHandling, args, tt)) {
11347 return errorResult();
11348 }
11349
11350 if (optionalKind == OptionalKind::Optional) {
11351 error(JSMSG_BAD_OPTIONAL_TEMPLATE);
11352 return errorResult();
11353 }
11354
11355 return handler_.newTaggedTemplate(lhs, args, op);
11356}
11357
11358template <class ParseHandler, typename Unit>
11359bool GeneralParser<ParseHandler, Unit>::checkLabelOrIdentifierReference(
11360 TaggedParserAtomIndex ident, uint32_t offset, YieldHandling yieldHandling,
11361 TokenKind hint /* = TokenKind::Limit */) {
11362 TokenKind tt;
11363 if (hint == TokenKind::Limit) {
11364 tt = ReservedWordTokenKind(ident);
11365 } else {
11366 // All non-reserved word kinds are folded into TokenKind::Limit in
11367 // ReservedWordTokenKind and the following code.
11368 if (hint == TokenKind::Name || hint == TokenKind::PrivateName) {
11369 hint = TokenKind::Limit;
11370 }
11371 MOZ_ASSERT(hint == ReservedWordTokenKind(ident),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hint == ReservedWordTokenKind(ident))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hint == ReservedWordTokenKind
(ident)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("hint == ReservedWordTokenKind(ident)" " (" "hint doesn't match actual token kind"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hint == ReservedWordTokenKind(ident)"
") (" "hint doesn't match actual token kind" ")"); do { *((volatile
int*)__null) = 11372; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
11372 "hint doesn't match actual token kind")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hint == ReservedWordTokenKind(ident))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hint == ReservedWordTokenKind
(ident)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("hint == ReservedWordTokenKind(ident)" " (" "hint doesn't match actual token kind"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11372); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hint == ReservedWordTokenKind(ident)"
") (" "hint doesn't match actual token kind" ")"); do { *((volatile
int*)__null) = 11372; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
11373 tt = hint;
11374 }
11375
11376 if (!pc_->sc()->allowArguments() &&
11377 ident == TaggedParserAtomIndex::WellKnown::arguments()) {
11378 error(JSMSG_BAD_ARGUMENTS);
11379 return false;
11380 }
11381
11382 if (tt == TokenKind::Limit) {
11383 // Either TokenKind::Name or TokenKind::PrivateName
11384 return true;
11385 }
11386 if (TokenKindIsContextualKeyword(tt)) {
11387 if (tt == TokenKind::Yield) {
11388 if (yieldHandling == YieldIsKeyword) {
11389 errorAt(offset, JSMSG_RESERVED_ID, "yield");
11390 return false;
11391 }
11392 if (pc_->sc()->strict()) {
11393 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "yield")) {
11394 return false;
11395 }
11396 }
11397 return true;
11398 }
11399 if (tt == TokenKind::Await) {
11400 if (awaitIsKeyword() || awaitIsDisallowed()) {
11401 errorAt(offset, JSMSG_RESERVED_ID, "await");
11402 return false;
11403 }
11404 return true;
11405 }
11406 if (pc_->sc()->strict()) {
11407 if (tt == TokenKind::Let) {
11408 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "let")) {
11409 return false;
11410 }
11411 return true;
11412 }
11413 if (tt == TokenKind::Static) {
11414 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "static")) {
11415 return false;
11416 }
11417 return true;
11418 }
11419 }
11420 return true;
11421 }
11422 if (TokenKindIsStrictReservedWord(tt)) {
11423 if (pc_->sc()->strict()) {
11424 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID,
11425 ReservedWordToCharZ(tt))) {
11426 return false;
11427 }
11428 }
11429 return true;
11430 }
11431 if (TokenKindIsKeyword(tt) || TokenKindIsReservedWordLiteral(tt)) {
11432 errorAt(offset, JSMSG_INVALID_ID, ReservedWordToCharZ(tt));
11433 return false;
11434 }
11435 if (TokenKindIsFutureReservedWord(tt)) {
11436 errorAt(offset, JSMSG_RESERVED_ID, ReservedWordToCharZ(tt));
11437 return false;
11438 }
11439 MOZ_ASSERT_UNREACHABLE("Unexpected reserved word kind.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Unexpected reserved word kind." ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11439); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected reserved word kind." ")"
); do { *((volatile int*)__null) = 11439; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
11440 return false;
11441}
11442
11443template <class ParseHandler, typename Unit>
11444bool GeneralParser<ParseHandler, Unit>::checkBindingIdentifier(
11445 TaggedParserAtomIndex ident, uint32_t offset, YieldHandling yieldHandling,
11446 TokenKind hint /* = TokenKind::Limit */) {
11447 if (pc_->sc()->strict()) {
11448 if (ident == TaggedParserAtomIndex::WellKnown::arguments()) {
11449 if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "arguments")) {
11450 return false;
11451 }
11452 return true;
11453 }
11454
11455 if (ident == TaggedParserAtomIndex::WellKnown::eval()) {
11456 if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "eval")) {
11457 return false;
11458 }
11459 return true;
11460 }
11461 }
11462
11463 return checkLabelOrIdentifierReference(ident, offset, yieldHandling, hint);
11464}
11465
11466template <class ParseHandler, typename Unit>
11467TaggedParserAtomIndex
11468GeneralParser<ParseHandler, Unit>::labelOrIdentifierReference(
11469 YieldHandling yieldHandling) {
11470 // ES 2017 draft 12.1.1.
11471 // StringValue of IdentifierName normalizes any Unicode escape sequences
11472 // in IdentifierName hence such escapes cannot be used to write an
11473 // Identifier whose code point sequence is the same as a ReservedWord.
11474 //
11475 // Use const ParserName* instead of TokenKind to reflect the normalization.
11476
11477 // Unless the name contains escapes, we can reuse the current TokenKind
11478 // to determine if the name is a restricted identifier.
11479 TokenKind hint = !anyChars.currentNameHasEscapes(this->parserAtoms())
11480 ? anyChars.currentToken().type
11481 : TokenKind::Limit;
11482 TaggedParserAtomIndex ident = anyChars.currentName();
11483 if (!checkLabelOrIdentifierReference(ident, pos().begin, yieldHandling,
11484 hint)) {
11485 return TaggedParserAtomIndex::null();
11486 }
11487 return ident;
11488}
11489
11490template <class ParseHandler, typename Unit>
11491TaggedParserAtomIndex GeneralParser<ParseHandler, Unit>::bindingIdentifier(
11492 YieldHandling yieldHandling) {
11493 TokenKind hint = !anyChars.currentNameHasEscapes(this->parserAtoms())
11494 ? anyChars.currentToken().type
11495 : TokenKind::Limit;
11496 TaggedParserAtomIndex ident = anyChars.currentName();
11497 if (!checkBindingIdentifier(ident, pos().begin, yieldHandling, hint)) {
11498 return TaggedParserAtomIndex::null();
11499 }
11500 return ident;
11501}
11502
11503template <class ParseHandler>
11504typename ParseHandler::NameNodeResult
11505PerHandlerParser<ParseHandler>::identifierReference(
11506 TaggedParserAtomIndex name) {
11507 NameNodeType id;
11508 MOZ_TRY_VAR(id, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (id) = mozTryVarTempResult_.unwrap(); } while
(0)
;
11509
11510 if (!noteUsedName(name)) {
11511 return errorResult();
11512 }
11513
11514 return id;
11515}
11516
11517template <class ParseHandler>
11518typename ParseHandler::NameNodeResult
11519PerHandlerParser<ParseHandler>::privateNameReference(
11520 TaggedParserAtomIndex name) {
11521 NameNodeType id;
11522 MOZ_TRY_VAR(id, newPrivateName(name))do { auto mozTryVarTempResult_ = (newPrivateName(name)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (id) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11523
11524 if (!noteUsedName(name, NameVisibility::Private, Some(pos()))) {
11525 return errorResult();
11526 }
11527
11528 return id;
11529}
11530
11531template <class ParseHandler>
11532typename ParseHandler::NameNodeResult
11533PerHandlerParser<ParseHandler>::stringLiteral() {
11534 return handler_.newStringLiteral(anyChars.currentToken().atom(), pos());
11535}
11536
11537template <class ParseHandler>
11538typename ParseHandler::NodeResult
11539PerHandlerParser<ParseHandler>::noSubstitutionTaggedTemplate() {
11540 if (anyChars.hasInvalidTemplateEscape()) {
11541 anyChars.clearInvalidTemplateEscape();
11542 return handler_.newRawUndefinedLiteral(pos());
11543 }
11544
11545 return handler_.newTemplateStringLiteral(anyChars.currentToken().atom(),
11546 pos());
11547}
11548
11549template <class ParseHandler, typename Unit>
11550typename ParseHandler::NameNodeResult
11551GeneralParser<ParseHandler, Unit>::noSubstitutionUntaggedTemplate() {
11552 if (!tokenStream.checkForInvalidTemplateEscapeError()) {
11553 return errorResult();
11554 }
11555
11556 return handler_.newTemplateStringLiteral(anyChars.currentToken().atom(),
11557 pos());
11558}
11559
11560template <typename Unit>
11561FullParseHandler::RegExpLiteralResult
11562Parser<FullParseHandler, Unit>::newRegExp() {
11563 MOZ_ASSERT(!options().selfHostingMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!options().selfHostingMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!options().selfHostingMode))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!options().selfHostingMode"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11563); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 11563; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11564
11565 // Create the regexp and check its syntax.
11566 const auto& chars = tokenStream.getCharBuffer();
11567 mozilla::Range<const char16_t> range(chars.begin(), chars.length());
11568 RegExpFlags flags = anyChars.currentToken().regExpFlags();
11569
11570 uint32_t offset = anyChars.currentToken().pos.begin;
11571 uint32_t line;
11572 JS::LimitedColumnNumberOneOrigin column;
11573 tokenStream.computeLineAndColumn(offset, &line, &column);
11574
11575 if (!handler_.reuseRegexpSyntaxParse()) {
11576 // Verify that the Regexp will syntax parse when the time comes to
11577 // instantiate it. If we have already done a syntax parse, we can
11578 // skip this.
11579 if (!irregexp::CheckPatternSyntax(
11580 this->alloc_, this->fc_->stackLimit(), anyChars, range, flags,
11581 Some(line), Some(JS::ColumnNumberOneOrigin(column)))) {
11582 return errorResult();
11583 }
11584 }
11585
11586 auto atom =
11587 this->parserAtoms().internChar16(fc_, chars.begin(), chars.length());
11588 if (!atom) {
11589 return errorResult();
11590 }
11591 // RegExp patterm must be atomized.
11592 this->parserAtoms().markUsedByStencil(atom, ParserAtom::Atomize::Yes);
11593
11594 RegExpIndex index(this->compilationState_.regExpData.length());
11595 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
11596 ReportAllocationOverflow(fc_);
11597 return errorResult();
11598 }
11599 if (!this->compilationState_.regExpData.emplaceBack(atom, flags)) {
11600 js::ReportOutOfMemory(this->fc_);
11601 return errorResult();
11602 }
11603
11604 return handler_.newRegExp(index, pos());
11605}
11606
11607template <typename Unit>
11608SyntaxParseHandler::RegExpLiteralResult
11609Parser<SyntaxParseHandler, Unit>::newRegExp() {
11610 MOZ_ASSERT(!options().selfHostingMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!options().selfHostingMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!options().selfHostingMode))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!options().selfHostingMode"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11610); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 11610; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11611
11612 // Only check the regexp's syntax, but don't create a regexp object.
11613 const auto& chars = tokenStream.getCharBuffer();
11614 RegExpFlags flags = anyChars.currentToken().regExpFlags();
11615
11616 uint32_t offset = anyChars.currentToken().pos.begin;
11617 uint32_t line;
11618 JS::LimitedColumnNumberOneOrigin column;
11619 tokenStream.computeLineAndColumn(offset, &line, &column);
11620
11621 mozilla::Range<const char16_t> source(chars.begin(), chars.length());
11622 if (!irregexp::CheckPatternSyntax(this->alloc_, this->fc_->stackLimit(),
11623 anyChars, source, flags, Some(line),
11624 Some(JS::ColumnNumberOneOrigin(column)))) {
11625 return errorResult();
11626 }
11627
11628 return handler_.newRegExp(SyntaxParseHandler::Node::NodeGeneric, pos());
11629}
11630
11631template <class ParseHandler, typename Unit>
11632typename ParseHandler::RegExpLiteralResult
11633GeneralParser<ParseHandler, Unit>::newRegExp() {
11634 return asFinalParser()->newRegExp();
11635}
11636
11637template <typename Unit>
11638FullParseHandler::BigIntLiteralResult
11639Parser<FullParseHandler, Unit>::newBigInt() {
11640 // The token's charBuffer contains the DecimalIntegerLiteral or
11641 // NonDecimalIntegerLiteral production, and as such does not include the
11642 // BigIntLiteralSuffix (the trailing "n"). Note that NonDecimalIntegerLiteral
11643 // productions start with 0[bBoOxX], indicating binary/octal/hex.
11644 const auto& chars = tokenStream.getCharBuffer();
11645 if (chars.length() > UINT32_MAX(4294967295U)) {
11646 ReportAllocationOverflow(fc_);
11647 return errorResult();
11648 }
11649
11650 BigIntIndex index(this->compilationState_.bigIntData.length());
11651 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
11652 ReportAllocationOverflow(fc_);
11653 return errorResult();
11654 }
11655 if (!this->compilationState_.bigIntData.emplaceBack()) {
11656 js::ReportOutOfMemory(this->fc_);
11657 return errorResult();
11658 }
11659
11660 if (!this->compilationState_.bigIntData[index].init(
11661 this->fc_, this->stencilAlloc(), chars)) {
11662 return errorResult();
11663 }
11664
11665 bool isZero = this->compilationState_.bigIntData[index].isZero();
11666
11667 // Should the operations below fail, the buffer held by data will
11668 // be cleaned up by the CompilationState destructor.
11669 return handler_.newBigInt(index, isZero, pos());
11670}
11671
11672template <typename Unit>
11673SyntaxParseHandler::BigIntLiteralResult
11674Parser<SyntaxParseHandler, Unit>::newBigInt() {
11675 // The tokenizer has already checked the syntax of the bigint.
11676
11677 return handler_.newBigInt();
11678}
11679
11680template <class ParseHandler, typename Unit>
11681typename ParseHandler::BigIntLiteralResult
11682GeneralParser<ParseHandler, Unit>::newBigInt() {
11683 return asFinalParser()->newBigInt();
11684}
11685
11686// |exprPossibleError| is the PossibleError state within |expr|,
11687// |possibleError| is the surrounding PossibleError state.
11688template <class ParseHandler, typename Unit>
11689bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentTarget(
11690 Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
11691 PossibleError* possibleError, TargetBehavior behavior) {
11692 // Report any pending expression error if we're definitely not in a
11693 // destructuring context or the possible destructuring target is a
11694 // property accessor.
11695 if (!possibleError || handler_.isPropertyOrPrivateMemberAccess(expr)) {
11696 return exprPossibleError->checkForExpressionError();
11697 }
11698
11699 // |expr| may end up as a destructuring assignment target, so we need to
11700 // validate it's either a name or can be parsed as a nested destructuring
11701 // pattern. Property accessors are also valid assignment targets, but
11702 // those are already handled above.
11703
11704 exprPossibleError->transferErrorsTo(possibleError);
11705
11706 // Return early if a pending destructuring error is already present.
11707 if (possibleError->hasPendingDestructuringError()) {
11708 return true;
11709 }
11710
11711 if (handler_.isName(expr)) {
11712 checkDestructuringAssignmentName(handler_.asNameNode(expr), exprPos,
11713 possibleError);
11714 return true;
11715 }
11716
11717 if (handler_.isUnparenthesizedDestructuringPattern(expr)) {
11718 if (behavior == TargetBehavior::ForbidAssignmentPattern) {
11719 possibleError->setPendingDestructuringErrorAt(exprPos,
11720 JSMSG_BAD_DESTRUCT_TARGET);
11721 }
11722 return true;
11723 }
11724
11725 // Parentheses are forbidden around destructuring *patterns* (but allowed
11726 // around names). Use our nicer error message for parenthesized, nested
11727 // patterns if nested destructuring patterns are allowed.
11728 if (handler_.isParenthesizedDestructuringPattern(expr) &&
11729 behavior != TargetBehavior::ForbidAssignmentPattern) {
11730 possibleError->setPendingDestructuringErrorAt(exprPos,
11731 JSMSG_BAD_DESTRUCT_PARENS);
11732 } else {
11733 possibleError->setPendingDestructuringErrorAt(exprPos,
11734 JSMSG_BAD_DESTRUCT_TARGET);
11735 }
11736
11737 return true;
11738}
11739
11740template <class ParseHandler, typename Unit>
11741void GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentName(
11742 NameNodeType name, TokenPos namePos, PossibleError* possibleError) {
11743#ifdef DEBUG1
11744 // GCC 8.0.1 crashes if this is a one-liner.
11745 bool isName = handler_.isName(name);
11746 MOZ_ASSERT(isName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isName)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(isName))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11746); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isName" ")"
); do { *((volatile int*)__null) = 11746; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
11747#endif
11748
11749 // Return early if a pending destructuring error is already present.
11750 if (possibleError->hasPendingDestructuringError()) {
11751 return;
11752 }
11753
11754 if (handler_.isArgumentsLength(name)) {
11755 pc_->sc()->setIneligibleForArgumentsLength();
11756 }
11757
11758 if (pc_->sc()->strict()) {
11759 if (handler_.isArgumentsName(name)) {
11760 if (pc_->sc()->strict()) {
11761 possibleError->setPendingDestructuringErrorAt(
11762 namePos, JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
11763 } else {
11764 possibleError->setPendingDestructuringWarningAt(
11765 namePos, JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
11766 }
11767 return;
11768 }
11769
11770 if (handler_.isEvalName(name)) {
11771 if (pc_->sc()->strict()) {
11772 possibleError->setPendingDestructuringErrorAt(
11773 namePos, JSMSG_BAD_STRICT_ASSIGN_EVAL);
11774 } else {
11775 possibleError->setPendingDestructuringWarningAt(
11776 namePos, JSMSG_BAD_STRICT_ASSIGN_EVAL);
11777 }
11778 return;
11779 }
11780 }
11781}
11782
11783template <class ParseHandler, typename Unit>
11784bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentElement(
11785 Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
11786 PossibleError* possibleError) {
11787 // ES2018 draft rev 0719f44aab93215ed9a626b2f45bd34f36916834
11788 // 12.15.5 Destructuring Assignment
11789 //
11790 // AssignmentElement[Yield, Await]:
11791 // DestructuringAssignmentTarget[?Yield, ?Await]
11792 // DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In,
11793 // ?Yield,
11794 // ?Await]
11795
11796 // If |expr| is an assignment element with an initializer expression, its
11797 // destructuring assignment target was already validated in assignExpr().
11798 // Otherwise we need to check that |expr| is a valid destructuring target.
11799 if (handler_.isUnparenthesizedAssignment(expr)) {
11800 // Report any pending expression error if we're definitely not in a
11801 // destructuring context.
11802 if (!possibleError) {
11803 return exprPossibleError->checkForExpressionError();
11804 }
11805
11806 exprPossibleError->transferErrorsTo(possibleError);
11807 return true;
11808 }
11809 return checkDestructuringAssignmentTarget(expr, exprPos, exprPossibleError,
11810 possibleError);
11811}
11812
11813template <class ParseHandler, typename Unit>
11814typename ParseHandler::ListNodeResult
11815GeneralParser<ParseHandler, Unit>::arrayInitializer(
11816 YieldHandling yieldHandling, PossibleError* possibleError) {
11817 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11817); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 11817; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11818
11819 uint32_t begin = pos().begin;
11820 ListNodeType literal;
11821 MOZ_TRY_VAR(literal, handler_.newArrayLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newArrayLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
11822
11823 TokenKind tt;
11824 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
11825 return errorResult();
11826 }
11827
11828 if (tt == TokenKind::RightBracket) {
11829 /*
11830 * Mark empty arrays as non-constant, since we cannot easily
11831 * determine their type.
11832 */
11833 handler_.setListHasNonConstInitializer(literal);
11834 } else {
11835 anyChars.ungetToken();
11836
11837 for (uint32_t index = 0;; index++) {
11838 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
11839 error(JSMSG_ARRAY_INIT_TOO_BIG);
11840 return errorResult();
11841 }
11842
11843 TokenKind tt;
11844 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
11845 return errorResult();
11846 }
11847 if (tt == TokenKind::RightBracket) {
11848 break;
11849 }
11850
11851 if (tt == TokenKind::Comma) {
11852 tokenStream.consumeKnownToken(TokenKind::Comma,
11853 TokenStream::SlashIsRegExp);
11854 if (!handler_.addElision(literal, pos())) {
11855 return errorResult();
11856 }
11857 continue;
11858 }
11859
11860 if (tt == TokenKind::TripleDot) {
11861 tokenStream.consumeKnownToken(TokenKind::TripleDot,
11862 TokenStream::SlashIsRegExp);
11863 uint32_t begin = pos().begin;
11864
11865 TokenPos innerPos;
11866 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
11867 return errorResult();
11868 }
11869
11870 PossibleError possibleErrorInner(*this);
11871 Node inner;
11872 MOZ_TRY_VAR(inner,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
11873 assignExpr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
11874 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
;
11875 if (!checkDestructuringAssignmentTarget(
11876 inner, innerPos, &possibleErrorInner, possibleError)) {
11877 return errorResult();
11878 }
11879
11880 if (!handler_.addSpreadElement(literal, begin, inner)) {
11881 return errorResult();
11882 }
11883 } else {
11884 TokenPos elementPos;
11885 if (!tokenStream.peekTokenPos(&elementPos,
11886 TokenStream::SlashIsRegExp)) {
11887 return errorResult();
11888 }
11889
11890 PossibleError possibleErrorInner(*this);
11891 Node element;
11892 MOZ_TRY_VAR(element,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (element) = mozTryVarTempResult_.unwrap();
} while (0)
11893 assignExpr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (element) = mozTryVarTempResult_.unwrap();
} while (0)
11894 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (element) = mozTryVarTempResult_.unwrap();
} while (0)
;
11895 if (!checkDestructuringAssignmentElement(
11896 element, elementPos, &possibleErrorInner, possibleError)) {
11897 return errorResult();
11898 }
11899 handler_.addArrayElement(literal, element);
11900 }
11901
11902 bool matched;
11903 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
11904 TokenStream::SlashIsRegExp)) {
11905 return errorResult();
11906 }
11907 if (!matched) {
11908 break;
11909 }
11910
11911 if (tt == TokenKind::TripleDot && possibleError) {
11912 possibleError->setPendingDestructuringErrorAt(pos(),
11913 JSMSG_REST_WITH_COMMA);
11914 }
11915 }
11916
11917 if (!mustMatchToken(
11918 TokenKind::RightBracket, [this, begin](TokenKind actual) {
11919 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
11920 JSMSG_BRACKET_OPENED, begin);
11921 })) {
11922 return errorResult();
11923 }
11924 }
11925
11926 handler_.setEndPosition(literal, pos().end);
11927 return literal;
11928}
11929
11930template <class ParseHandler, typename Unit>
11931typename ParseHandler::NodeResult
11932GeneralParser<ParseHandler, Unit>::propertyName(
11933 YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
11934 const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
11935 TaggedParserAtomIndex* propAtomOut) {
11936 // PropertyName[Yield, Await]:
11937 // LiteralPropertyName
11938 // ComputedPropertyName[?Yield, ?Await]
11939 //
11940 // LiteralPropertyName:
11941 // IdentifierName
11942 // StringLiteral
11943 // NumericLiteral
11944 TokenKind ltok = anyChars.currentToken().type;
11945
11946 *propAtomOut = TaggedParserAtomIndex::null();
11947 switch (ltok) {
11948 case TokenKind::Number: {
11949 auto numAtom = NumberToParserAtom(fc_, this->parserAtoms(),
11950 anyChars.currentToken().number());
11951 if (!numAtom) {
11952 return errorResult();
11953 }
11954 *propAtomOut = numAtom;
11955 return newNumber(anyChars.currentToken());
11956 }
11957
11958 case TokenKind::BigInt: {
11959 Node biNode;
11960 MOZ_TRY_VAR(biNode, newBigInt())do { auto mozTryVarTempResult_ = (newBigInt()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (biNode) = mozTryVarTempResult_.unwrap(); }
while (0)
;
11961 return handler_.newSyntheticComputedName(biNode, pos().begin, pos().end);
11962 }
11963 case TokenKind::String: {
11964 auto str = anyChars.currentToken().atom();
11965 *propAtomOut = str;
11966 uint32_t index;
11967 if (this->parserAtoms().isIndex(str, &index)) {
11968 return handler_.newNumber(index, NoDecimal, pos());
11969 }
11970 return stringLiteral();
11971 }
11972
11973 case TokenKind::LeftBracket:
11974 return computedPropertyName(yieldHandling, maybeDecl, propertyNameContext,
11975 propList);
11976
11977 case TokenKind::PrivateName: {
11978 if (propertyNameContext != PropertyNameContext::PropertyNameInClass) {
11979 error(JSMSG_ILLEGAL_PRIVATE_FIELD);
11980 return errorResult();
11981 }
11982
11983 TaggedParserAtomIndex propName = anyChars.currentName();
11984 *propAtomOut = propName;
11985 return privateNameReference(propName);
11986 }
11987
11988 default: {
11989 if (!TokenKindIsPossibleIdentifierName(ltok)) {
11990 error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(ltok));
11991 return errorResult();
11992 }
11993
11994 TaggedParserAtomIndex name = anyChars.currentName();
11995 *propAtomOut = name;
11996 return handler_.newObjectLiteralPropertyName(name, pos());
11997 }
11998 }
11999}
12000
12001// True if `kind` can be the first token of a PropertyName.
12002static bool TokenKindCanStartPropertyName(TokenKind tt) {
12003 return TokenKindIsPossibleIdentifierName(tt) || tt == TokenKind::String ||
12004 tt == TokenKind::Number || tt == TokenKind::LeftBracket ||
12005 tt == TokenKind::Mul || tt == TokenKind::BigInt ||
12006 tt == TokenKind::PrivateName;
12007}
12008
12009template <class ParseHandler, typename Unit>
12010typename ParseHandler::NodeResult
12011GeneralParser<ParseHandler, Unit>::propertyOrMethodName(
12012 YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
12013 const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
12014 PropertyType* propType, TaggedParserAtomIndex* propAtomOut) {
12015 // We're parsing an object literal, class, or destructuring pattern;
12016 // propertyNameContext tells which one. This method parses any of the
12017 // following, storing the corresponding PropertyType in `*propType` to tell
12018 // the caller what we parsed:
12019 //
12020 // async [no LineTerminator here] PropertyName
12021 // ==> PropertyType::AsyncMethod
12022 // async [no LineTerminator here] * PropertyName
12023 // ==> PropertyType::AsyncGeneratorMethod
12024 // * PropertyName ==> PropertyType::GeneratorMethod
12025 // get PropertyName ==> PropertyType::Getter
12026 // set PropertyName ==> PropertyType::Setter
12027 // accessor PropertyName ==> PropertyType::FieldWithAccessor
12028 // PropertyName : ==> PropertyType::Normal
12029 // PropertyName ==> see below
12030 //
12031 // In the last case, where there's not a `:` token to consume, we peek at
12032 // (but don't consume) the next token to decide how to set `*propType`.
12033 //
12034 // `,` or `}` ==> PropertyType::Shorthand
12035 // `(` ==> PropertyType::Method
12036 // `=`, not in a class ==> PropertyType::CoverInitializedName
12037 // '=', in a class ==> PropertyType::Field
12038 // any token, in a class ==> PropertyType::Field (ASI)
12039 //
12040 // The caller must check `*propType` and throw if whatever we parsed isn't
12041 // allowed here (for example, a getter in a destructuring pattern).
12042 //
12043 // This method does *not* match `static` (allowed in classes) or `...`
12044 // (allowed in object literals and patterns). The caller must take care of
12045 // those before calling this method.
12046
12047 TokenKind ltok;
12048 if (!tokenStream.getToken(&ltok, TokenStream::SlashIsInvalid)) {
12049 return errorResult();
12050 }
12051
12052 MOZ_ASSERT(ltok != TokenKind::RightCurly,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ltok != TokenKind::RightCurly)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(ltok != TokenKind::RightCurly
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"ltok != TokenKind::RightCurly" " (" "caller should have handled TokenKind::RightCurly"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12053); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ltok != TokenKind::RightCurly"
") (" "caller should have handled TokenKind::RightCurly" ")"
); do { *((volatile int*)__null) = 12053; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
12053 "caller should have handled TokenKind::RightCurly")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ltok != TokenKind::RightCurly)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(ltok != TokenKind::RightCurly
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"ltok != TokenKind::RightCurly" " (" "caller should have handled TokenKind::RightCurly"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12053); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ltok != TokenKind::RightCurly"
") (" "caller should have handled TokenKind::RightCurly" ")"
); do { *((volatile int*)__null) = 12053; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
12054
12055 // Accept `async` and/or `*`, indicating an async or generator method;
12056 // or `get` or `set` or `accessor`, indicating an accessor.
12057 bool isGenerator = false;
12058 bool isAsync = false;
12059 bool isGetter = false;
12060 bool isSetter = false;
12061#ifdef ENABLE_DECORATORS
12062 bool hasAccessor = false;
12063#endif
12064
12065 if (ltok == TokenKind::Async) {
12066 // `async` is also a PropertyName by itself (it's a conditional keyword),
12067 // so peek at the next token to see if we're really looking at a method.
12068 TokenKind tt = TokenKind::Eof;
12069 if (!tokenStream.peekTokenSameLine(&tt)) {
12070 return errorResult();
12071 }
12072 if (TokenKindCanStartPropertyName(tt)) {
12073 isAsync = true;
12074 tokenStream.consumeKnownToken(tt);
12075 ltok = tt;
12076 }
12077 }
12078
12079 if (ltok == TokenKind::Mul) {
12080 isGenerator = true;
12081 if (!tokenStream.getToken(&ltok)) {
12082 return errorResult();
12083 }
12084 }
12085
12086 if (!isAsync && !isGenerator &&
12087 (ltok == TokenKind::Get || ltok == TokenKind::Set)) {
12088 // We have parsed |get| or |set|. Look for an accessor property
12089 // name next.
12090 TokenKind tt;
12091 if (!tokenStream.peekToken(&tt)) {
12092 return errorResult();
12093 }
12094 if (TokenKindCanStartPropertyName(tt)) {
12095 tokenStream.consumeKnownToken(tt);
12096 isGetter = (ltok == TokenKind::Get);
12097 isSetter = (ltok == TokenKind::Set);
12098 }
12099 }
12100
12101#ifdef ENABLE_DECORATORS
12102 if (!isGenerator && !isAsync && propertyNameContext == PropertyNameInClass &&
12103 ltok == TokenKind::Accessor) {
12104 MOZ_ASSERT(!isGetter && !isSetter)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!isGetter && !isSetter)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!isGetter && !isSetter
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!isGetter && !isSetter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12104); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!isGetter && !isSetter"
")"); do { *((volatile int*)__null) = 12104; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12105 TokenKind tt;
12106 if (!tokenStream.peekTokenSameLine(&tt)) {
12107 return errorResult();
12108 }
12109
12110 // The target rule is `accessor [no LineTerminator here]
12111 // ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt`
12112 if (TokenKindCanStartPropertyName(tt)) {
12113 tokenStream.consumeKnownToken(tt);
12114 hasAccessor = true;
12115 }
12116 }
12117#endif
12118
12119 Node propName;
12120 MOZ_TRY_VAR(propName, propertyName(yieldHandling, propertyNameContext,do { auto mozTryVarTempResult_ = (propertyName(yieldHandling,
propertyNameContext, maybeDecl, propList, propAtomOut)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propName) = mozTryVarTempResult_
.unwrap(); } while (0)
12121 maybeDecl, propList, propAtomOut))do { auto mozTryVarTempResult_ = (propertyName(yieldHandling,
propertyNameContext, maybeDecl, propList, propAtomOut)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propName) = mozTryVarTempResult_
.unwrap(); } while (0)
;
12122
12123 // Grab the next token following the property/method name.
12124 // (If this isn't a colon, we're going to either put it back or throw.)
12125 TokenKind tt;
12126 if (!tokenStream.getToken(&tt)) {
12127 return errorResult();
12128 }
12129
12130 if (tt == TokenKind::Colon) {
12131 if (isGenerator || isAsync || isGetter || isSetter
12132#ifdef ENABLE_DECORATORS
12133 || hasAccessor
12134#endif
12135 ) {
12136 error(JSMSG_BAD_PROP_ID);
12137 return errorResult();
12138 }
12139 *propType = PropertyType::Normal;
12140 return propName;
12141 }
12142
12143 if (propertyNameContext != PropertyNameInClass &&
12144 TokenKindIsPossibleIdentifierName(ltok) &&
12145 (tt == TokenKind::Comma || tt == TokenKind::RightCurly ||
12146 tt == TokenKind::Assign)) {
12147#ifdef ENABLE_DECORATORS
12148 MOZ_ASSERT(!hasAccessor)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!hasAccessor)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!hasAccessor))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!hasAccessor", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12148); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!hasAccessor"
")"); do { *((volatile int*)__null) = 12148; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12149#endif
12150 if (isGenerator || isAsync || isGetter || isSetter) {
12151 error(JSMSG_BAD_PROP_ID);
12152 return errorResult();
12153 }
12154
12155 anyChars.ungetToken();
12156 *propType = tt == TokenKind::Assign ? PropertyType::CoverInitializedName
12157 : PropertyType::Shorthand;
12158 return propName;
12159 }
12160
12161 if (tt == TokenKind::LeftParen) {
12162 anyChars.ungetToken();
12163
12164#ifdef ENABLE_RECORD_TUPLE
12165 if (propertyNameContext == PropertyNameInRecord) {
12166 // Record & Tuple proposal, section 7.1.1:
12167 // RecordPropertyDefinition doesn't cover methods
12168 error(JSMSG_BAD_PROP_ID);
12169 return errorResult();
12170 }
12171#endif
12172
12173#ifdef ENABLE_DECORATORS
12174 if (hasAccessor) {
12175 error(JSMSG_BAD_PROP_ID);
12176 return errorResult();
12177 }
12178#endif
12179
12180 if (isGenerator && isAsync) {
12181 *propType = PropertyType::AsyncGeneratorMethod;
12182 } else if (isGenerator) {
12183 *propType = PropertyType::GeneratorMethod;
12184 } else if (isAsync) {
12185 *propType = PropertyType::AsyncMethod;
12186 } else if (isGetter) {
12187 *propType = PropertyType::Getter;
12188 } else if (isSetter) {
12189 *propType = PropertyType::Setter;
12190 } else {
12191 *propType = PropertyType::Method;
12192 }
12193 return propName;
12194 }
12195
12196 if (propertyNameContext == PropertyNameInClass) {
12197 if (isGenerator || isAsync || isGetter || isSetter) {
12198 error(JSMSG_BAD_PROP_ID);
12199 return errorResult();
12200 }
12201 anyChars.ungetToken();
12202#ifdef ENABLE_DECORATORS
12203 if (!hasAccessor) {
12204 *propType = PropertyType::Field;
12205 } else {
12206 *propType = PropertyType::FieldWithAccessor;
12207 }
12208#else
12209 *propType = PropertyType::Field;
12210#endif
12211 return propName;
12212 }
12213
12214 error(JSMSG_COLON_AFTER_ID);
12215 return errorResult();
12216}
12217
12218template <class ParseHandler, typename Unit>
12219typename ParseHandler::UnaryNodeResult
12220GeneralParser<ParseHandler, Unit>::computedPropertyName(
12221 YieldHandling yieldHandling, const Maybe<DeclarationKind>& maybeDecl,
12222 PropertyNameContext propertyNameContext, ListNodeType literal) {
12223 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12223); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 12223; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12224
12225 uint32_t begin = pos().begin;
12226
12227 if (maybeDecl) {
12228 if (*maybeDecl == DeclarationKind::FormalParameter) {
12229 pc_->functionBox()->hasParameterExprs = true;
12230 }
12231 } else if (propertyNameContext ==
12232 PropertyNameContext::PropertyNameInLiteral) {
12233 handler_.setListHasNonConstInitializer(literal);
12234 }
12235
12236 Node assignNode;
12237 MOZ_TRY_VAR(assignNode,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assignNode) = mozTryVarTempResult_.unwrap(); } while (0)
12238 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assignNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
12239
12240 if (!mustMatchToken(TokenKind::RightBracket, JSMSG_COMP_PROP_UNTERM_EXPR)) {
12241 return errorResult();
12242 }
12243 return handler_.newComputedName(assignNode, begin, pos().end);
12244}
12245
12246template <class ParseHandler, typename Unit>
12247typename ParseHandler::ListNodeResult
12248GeneralParser<ParseHandler, Unit>::objectLiteral(YieldHandling yieldHandling,
12249 PossibleError* possibleError) {
12250 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12250); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 12250; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12251
12252 uint32_t openedPos = pos().begin;
12253
12254 ListNodeType literal;
12255 MOZ_TRY_VAR(literal, handler_.newObjectLiteral(pos().begin))do { auto mozTryVarTempResult_ = (handler_.newObjectLiteral(pos
().begin)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (literal
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12256
12257 bool seenPrototypeMutation = false;
12258 bool seenCoverInitializedName = false;
12259 Maybe<DeclarationKind> declKind = Nothing();
12260 TaggedParserAtomIndex propAtom;
12261 for (;;) {
12262 TokenKind tt;
12263 if (!tokenStream.peekToken(&tt)) {
12264 return errorResult();
12265 }
12266 if (tt == TokenKind::RightCurly) {
12267 break;
12268 }
12269
12270 if (tt == TokenKind::TripleDot) {
12271 tokenStream.consumeKnownToken(TokenKind::TripleDot);
12272 uint32_t begin = pos().begin;
12273
12274 TokenPos innerPos;
12275 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12276 return errorResult();
12277 }
12278
12279 PossibleError possibleErrorInner(*this);
12280 Node inner;
12281 MOZ_TRY_VAR(inner, assignExpr(InAllowed, yieldHandling,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
12282 TripledotProhibited, &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
;
12283 if (!checkDestructuringAssignmentTarget(
12284 inner, innerPos, &possibleErrorInner, possibleError,
12285 TargetBehavior::ForbidAssignmentPattern)) {
12286 return errorResult();
12287 }
12288 if (!handler_.addSpreadProperty(literal, begin, inner)) {
12289 return errorResult();
12290 }
12291 } else {
12292 TokenPos namePos = anyChars.nextToken().pos;
12293
12294 PropertyType propType;
12295 Node propName;
12296 MOZ_TRY_VAR(propName, propertyOrMethodName(do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInLiteral, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12297 yieldHandling, PropertyNameInLiteral, declKind,do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInLiteral, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12298 literal, &propType, &propAtom))do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInLiteral, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12299
12300 if (propType == PropertyType::Normal) {
12301 TokenPos exprPos;
12302 if (!tokenStream.peekTokenPos(&exprPos, TokenStream::SlashIsRegExp)) {
12303 return errorResult();
12304 }
12305
12306 PossibleError possibleErrorInner(*this);
12307 Node propExpr;
12308 MOZ_TRY_VAR(propExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
12309 assignExpr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
12310 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
;
12311
12312 if (!checkDestructuringAssignmentElement(
12313 propExpr, exprPos, &possibleErrorInner, possibleError)) {
12314 return errorResult();
12315 }
12316
12317 if (propAtom == TaggedParserAtomIndex::WellKnown::proto_()) {
12318 if (seenPrototypeMutation) {
12319 // Directly report the error when we're definitely not
12320 // in a destructuring context.
12321 if (!possibleError) {
12322 errorAt(namePos.begin, JSMSG_DUPLICATE_PROTO_PROPERTY);
12323 return errorResult();
12324 }
12325
12326 // Otherwise delay error reporting until we've
12327 // determined whether or not we're destructuring.
12328 possibleError->setPendingExpressionErrorAt(
12329 namePos, JSMSG_DUPLICATE_PROTO_PROPERTY);
12330 }
12331 seenPrototypeMutation = true;
12332
12333 // This occurs *only* if we observe PropertyType::Normal!
12334 // Only |__proto__: v| mutates [[Prototype]]. Getters,
12335 // setters, method/generator definitions, computed
12336 // property name versions of all of these, and shorthands
12337 // do not.
12338 if (!handler_.addPrototypeMutation(literal, namePos.begin,
12339 propExpr)) {
12340 return errorResult();
12341 }
12342 } else {
12343 BinaryNodeType propDef;
12344 MOZ_TRY_VAR(propDef,do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
12345 handler_.newPropertyDefinition(propName, propExpr))do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
;
12346
12347 handler_.addPropertyDefinition(literal, propDef);
12348 }
12349 } else if (propType == PropertyType::Shorthand) {
12350 /*
12351 * Support, e.g., |({x, y} = o)| as destructuring shorthand
12352 * for |({x: x, y: y} = o)|, and |var o = {x, y}| as
12353 * initializer shorthand for |var o = {x: x, y: y}|.
12354 */
12355 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12356 if (!name) {
12357 return errorResult();
12358 }
12359
12360 NameNodeType nameExpr;
12361 MOZ_TRY_VAR(nameExpr, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nameExpr) =
mozTryVarTempResult_.unwrap(); } while (0)
;
12362
12363 if (possibleError) {
12364 checkDestructuringAssignmentName(nameExpr, namePos, possibleError);
12365 }
12366
12367 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
12368 nameExpr)) {
12369 return errorResult();
12370 }
12371 } else if (propType == PropertyType::CoverInitializedName) {
12372 /*
12373 * Support, e.g., |({x=1, y=2} = o)| as destructuring
12374 * shorthand with default values, as per ES6 12.14.5
12375 */
12376 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12377 if (!name) {
12378 return errorResult();
12379 }
12380
12381 Node lhs;
12382 MOZ_TRY_VAR(lhs, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
12383
12384 tokenStream.consumeKnownToken(TokenKind::Assign);
12385
12386 if (!seenCoverInitializedName) {
12387 // "shorthand default" or "CoverInitializedName" syntax is
12388 // only valid in the case of destructuring.
12389 seenCoverInitializedName = true;
12390
12391 if (!possibleError) {
12392 // Destructuring defaults are definitely not allowed
12393 // in this object literal, because of something the
12394 // caller knows about the preceding code. For example,
12395 // maybe the preceding token is an operator:
12396 // |x + {y=z}|.
12397 error(JSMSG_COLON_AFTER_ID);
12398 return errorResult();
12399 }
12400
12401 // Here we set a pending error so that later in the parse,
12402 // once we've determined whether or not we're
12403 // destructuring, the error can be reported or ignored
12404 // appropriately.
12405 possibleError->setPendingExpressionErrorAt(pos(),
12406 JSMSG_COLON_AFTER_ID);
12407 }
12408
12409 if (const char* chars = nameIsArgumentsOrEval(lhs)) {
12410 // |chars| is "arguments" or "eval" here.
12411 if (!strictModeErrorAt(namePos.begin, JSMSG_BAD_STRICT_ASSIGN,
12412 chars)) {
12413 return errorResult();
12414 }
12415 }
12416
12417 if (handler_.isArgumentsLength(lhs)) {
12418 pc_->sc()->setIneligibleForArgumentsLength();
12419 }
12420
12421 Node rhs;
12422 MOZ_TRY_VAR(rhs,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
12423 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
12424
12425 BinaryNodeType propExpr;
12426 MOZ_TRY_VAR(propExpr, handler_.newAssignment(ParseNodeKind::AssignExpr,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
12427 lhs, rhs))do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
12428
12429 if (!handler_.addPropertyDefinition(literal, propName, propExpr)) {
12430 return errorResult();
12431 }
12432 } else {
12433 TaggedParserAtomIndex funName;
12434 bool hasStaticName =
12435 !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom;
12436 if (hasStaticName) {
12437 funName = propAtom;
12438
12439 if (propType == PropertyType::Getter ||
12440 propType == PropertyType::Setter) {
12441 funName = prefixAccessorName(propType, propAtom);
12442 if (!funName) {
12443 return errorResult();
12444 }
12445 }
12446 }
12447
12448 FunctionNodeType funNode;
12449 MOZ_TRY_VAR(funNode,do { auto mozTryVarTempResult_ = (methodDefinition(namePos.begin
, propType, funName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
12450 methodDefinition(namePos.begin, propType, funName))do { auto mozTryVarTempResult_ = (methodDefinition(namePos.begin
, propType, funName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
12451
12452 AccessorType atype = ToAccessorType(propType);
12453 if (!handler_.addObjectMethodDefinition(literal, propName, funNode,
12454 atype)) {
12455 return errorResult();
12456 }
12457
12458 if (possibleError) {
12459 possibleError->setPendingDestructuringErrorAt(
12460 namePos, JSMSG_BAD_DESTRUCT_TARGET);
12461 }
12462 }
12463 }
12464
12465 bool matched;
12466 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12467 TokenStream::SlashIsInvalid)) {
12468 return errorResult();
12469 }
12470 if (!matched) {
12471 break;
12472 }
12473 if (tt == TokenKind::TripleDot && possibleError) {
12474 possibleError->setPendingDestructuringErrorAt(pos(),
12475 JSMSG_REST_WITH_COMMA);
12476 }
12477 }
12478
12479 if (!mustMatchToken(
12480 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
12481 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
12482 JSMSG_CURLY_OPENED, openedPos);
12483 })) {
12484 return errorResult();
12485 }
12486
12487 handler_.setEndPosition(literal, pos().end);
12488 return literal;
12489}
12490
12491#ifdef ENABLE_RECORD_TUPLE
12492template <class ParseHandler, typename Unit>
12493typename ParseHandler::ListNodeResult
12494GeneralParser<ParseHandler, Unit>::recordLiteral(YieldHandling yieldHandling) {
12495 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::HashCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::HashCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::HashCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::HashCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12495); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::HashCurly)"
")"); do { *((volatile int*)__null) = 12495; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12496
12497 uint32_t openedPos = pos().begin;
12498
12499 ListNodeType literal;
12500 MOZ_TRY_VAR(literal, handler_.newRecordLiteral(pos().begin))do { auto mozTryVarTempResult_ = (handler_.newRecordLiteral(pos
().begin)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (literal
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12501
12502 TaggedParserAtomIndex propAtom;
12503 for (;;) {
12504 TokenKind tt;
12505 if (!tokenStream.peekToken(&tt)) {
12506 return errorResult();
12507 }
12508 if (tt == TokenKind::RightCurly) {
12509 break;
12510 }
12511
12512 if (tt == TokenKind::TripleDot) {
12513 tokenStream.consumeKnownToken(TokenKind::TripleDot);
12514 uint32_t begin = pos().begin;
12515
12516 TokenPos innerPos;
12517 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12518 return errorResult();
12519 }
12520
12521 Node inner;
12522 MOZ_TRY_VAR(inner,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
12523 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
;
12524
12525 if (!handler_.addSpreadProperty(literal, begin, inner)) {
12526 return errorResult();
12527 }
12528 } else {
12529 TokenPos namePos = anyChars.nextToken().pos;
12530
12531 PropertyType propType;
12532 Node propName;
12533 MOZ_TRY_VAR(propName,do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12534 propertyOrMethodName(yieldHandling, PropertyNameInRecord,do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12535 /* maybeDecl */ Nothing(), literal,do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12536 &propType, &propAtom))do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12537
12538 if (propType == PropertyType::Normal) {
12539 TokenPos exprPos;
12540 if (!tokenStream.peekTokenPos(&exprPos, TokenStream::SlashIsRegExp)) {
12541 return errorResult();
12542 }
12543
12544 Node propExpr;
12545 MOZ_TRY_VAR(propExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
12546 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
12547
12548 if (propAtom == TaggedParserAtomIndex::WellKnown::proto_()) {
12549 errorAt(namePos.begin, JSMSG_RECORD_NO_PROTO);
12550 return errorResult();
12551 }
12552
12553 BinaryNodeType propDef;
12554 MOZ_TRY_VAR(propDef,do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
12555 handler_.newPropertyDefinition(propName, propExpr))do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
;
12556
12557 handler_.addPropertyDefinition(literal, propDef);
12558 } else if (propType == PropertyType::Shorthand) {
12559 /*
12560 * Support |var o = #{x, y}| as initializer shorthand for
12561 * |var o = #{x: x, y: y}|.
12562 */
12563 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12564 if (!name) {
12565 return errorResult();
12566 }
12567
12568 NameNodeType nameExpr;
12569 MOZ_TRY_VAR(nameExpr, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nameExpr) =
mozTryVarTempResult_.unwrap(); } while (0)
;
12570
12571 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
12572 nameExpr)) {
12573 return errorResult();
12574 }
12575 } else {
12576 error(JSMSG_BAD_PROP_ID);
12577 return errorResult();
12578 }
12579 }
12580
12581 bool matched;
12582 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12583 TokenStream::SlashIsInvalid)) {
12584 return errorResult();
12585 }
12586 if (!matched) {
12587 break;
12588 }
12589 }
12590
12591 if (!mustMatchToken(
12592 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
12593 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
12594 JSMSG_CURLY_OPENED, openedPos);
12595 })) {
12596 return errorResult();
12597 }
12598
12599 handler_.setEndPosition(literal, pos().end);
12600 return literal;
12601}
12602
12603template <class ParseHandler, typename Unit>
12604typename ParseHandler::ListNodeResult
12605GeneralParser<ParseHandler, Unit>::tupleLiteral(YieldHandling yieldHandling) {
12606 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::HashBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::HashBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::HashBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::HashBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12606); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::HashBracket)"
")"); do { *((volatile int*)__null) = 12606; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12607
12608 uint32_t begin = pos().begin;
12609 ListNodeType literal;
12610 MOZ_TRY_VAR(literal, handler_.newTupleLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newTupleLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
12611
12612 for (uint32_t index = 0;; index++) {
12613 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
12614 error(JSMSG_ARRAY_INIT_TOO_BIG);
12615 return errorResult();
12616 }
12617
12618 TokenKind tt;
12619 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
12620 return errorResult();
12621 }
12622 if (tt == TokenKind::RightBracket) {
12623 break;
12624 }
12625
12626 if (tt == TokenKind::TripleDot) {
12627 tokenStream.consumeKnownToken(TokenKind::TripleDot,
12628 TokenStream::SlashIsRegExp);
12629 uint32_t begin = pos().begin;
12630
12631 TokenPos innerPos;
12632 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12633 return errorResult();
12634 }
12635
12636 Node inner;
12637 MOZ_TRY_VAR(inner,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
12638 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
;
12639
12640 if (!handler_.addSpreadElement(literal, begin, inner)) {
12641 return errorResult();
12642 }
12643 } else {
12644 TokenPos elementPos;
12645 if (!tokenStream.peekTokenPos(&elementPos, TokenStream::SlashIsRegExp)) {
12646 return errorResult();
12647 }
12648
12649 Node element;
12650 MOZ_TRY_VAR(element,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (element) = mozTryVarTempResult_.unwrap(); } while (0)
12651 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (element) = mozTryVarTempResult_.unwrap(); } while (0)
;
12652 handler_.addArrayElement(literal, element);
12653 }
12654
12655 bool matched;
12656 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12657 TokenStream::SlashIsRegExp)) {
12658 return errorResult();
12659 }
12660 if (!matched) {
12661 break;
12662 }
12663 }
12664
12665 if (!mustMatchToken(TokenKind::RightBracket, [this, begin](TokenKind actual) {
12666 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
12667 JSMSG_BRACKET_OPENED, begin);
12668 })) {
12669 return errorResult();
12670 }
12671
12672 handler_.setEndPosition(literal, pos().end);
12673 return literal;
12674}
12675#endif
12676
12677template <class ParseHandler, typename Unit>
12678typename ParseHandler::FunctionNodeResult
12679GeneralParser<ParseHandler, Unit>::methodDefinition(
12680 uint32_t toStringStart, PropertyType propType,
12681 TaggedParserAtomIndex funName) {
12682 FunctionSyntaxKind syntaxKind;
12683 switch (propType) {
12684 case PropertyType::Getter:
12685 syntaxKind = FunctionSyntaxKind::Getter;
12686 break;
12687
12688 case PropertyType::Setter:
12689 syntaxKind = FunctionSyntaxKind::Setter;
12690 break;
12691
12692 case PropertyType::Method:
12693 case PropertyType::GeneratorMethod:
12694 case PropertyType::AsyncMethod:
12695 case PropertyType::AsyncGeneratorMethod:
12696 syntaxKind = FunctionSyntaxKind::Method;
12697 break;
12698
12699 case PropertyType::Constructor:
12700 syntaxKind = FunctionSyntaxKind::ClassConstructor;
12701 break;
12702
12703 case PropertyType::DerivedConstructor:
12704 syntaxKind = FunctionSyntaxKind::DerivedClassConstructor;
12705 break;
12706
12707 default:
12708 MOZ_CRASH("unexpected property type")do { do { } while (false); MOZ_ReportCrash("" "unexpected property type"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12708); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected property type"
")"); do { *((volatile int*)__null) = 12708; __attribute__((
nomerge)) ::abort(); } while (false); } while (false)
;
12709 }
12710
12711 GeneratorKind generatorKind = (propType == PropertyType::GeneratorMethod ||
12712 propType == PropertyType::AsyncGeneratorMethod)
12713 ? GeneratorKind::Generator
12714 : GeneratorKind::NotGenerator;
12715
12716 FunctionAsyncKind asyncKind = (propType == PropertyType::AsyncMethod ||
12717 propType == PropertyType::AsyncGeneratorMethod)
12718 ? FunctionAsyncKind::AsyncFunction
12719 : FunctionAsyncKind::SyncFunction;
12720
12721 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
12722
12723 FunctionNodeType funNode;
12724 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12725
12726 return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
12727 funName, syntaxKind, generatorKind, asyncKind);
12728}
12729
12730template <class ParseHandler, typename Unit>
12731bool GeneralParser<ParseHandler, Unit>::tryNewTarget(
12732 NewTargetNodeType* newTarget) {
12733 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::New))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::New))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::New)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::New)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12733); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::New)"
")"); do { *((volatile int*)__null) = 12733; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12734
12735 *newTarget = null();
12736
12737 NullaryNodeType newHolder;
12738 MOZ_TRY_VAR_OR_RETURN(newHolder, handler_.newPosHolder(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newPosHolder(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (newHolder) = parserTryVarTempResult_
.unwrap(); } while (0)
;
12739
12740 uint32_t begin = pos().begin;
12741
12742 // |new| expects to look for an operand, so we will honor that.
12743 TokenKind next;
12744 if (!tokenStream.getToken(&next, TokenStream::SlashIsRegExp)) {
12745 return false;
12746 }
12747
12748 // Don't unget the token, since lookahead cannot handle someone calling
12749 // getToken() with a different modifier. Callers should inspect
12750 // currentToken().
12751 if (next != TokenKind::Dot) {
12752 return true;
12753 }
12754
12755 if (!tokenStream.getToken(&next)) {
12756 return false;
12757 }
12758 if (next != TokenKind::Target) {
12759 error(JSMSG_UNEXPECTED_TOKEN, "target", TokenKindToDesc(next));
12760 return false;
12761 }
12762
12763 if (!pc_->sc()->allowNewTarget()) {
12764 errorAt(begin, JSMSG_BAD_NEWTARGET);
12765 return false;
12766 }
12767
12768 NullaryNodeType targetHolder;
12769 MOZ_TRY_VAR_OR_RETURN(targetHolder, handler_.newPosHolder(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newPosHolder(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (targetHolder) = parserTryVarTempResult_
.unwrap(); } while (0)
;
12770
12771 NameNodeType newTargetName;
12772 MOZ_TRY_VAR_OR_RETURN(newTargetName, newNewTargetName(), false)do { auto parserTryVarTempResult_ = (newNewTargetName()); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (newTargetName) = parserTryVarTempResult_.
unwrap(); } while (0)
;
12773
12774 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newNewTarget(newHolder
, targetHolder, newTargetName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*newTarget) = parserTryVarTempResult_
.unwrap(); } while (0)
12775 *newTarget, handler_.newNewTarget(newHolder, targetHolder, newTargetName),do { auto parserTryVarTempResult_ = (handler_.newNewTarget(newHolder
, targetHolder, newTargetName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*newTarget) = parserTryVarTempResult_
.unwrap(); } while (0)
12776 false)do { auto parserTryVarTempResult_ = (handler_.newNewTarget(newHolder
, targetHolder, newTargetName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*newTarget) = parserTryVarTempResult_
.unwrap(); } while (0)
;
12777
12778 return true;
12779}
12780
12781template <class ParseHandler, typename Unit>
12782typename ParseHandler::BinaryNodeResult
12783GeneralParser<ParseHandler, Unit>::importExpr(YieldHandling yieldHandling,
12784 bool allowCallSyntax) {
12785 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Import))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Import)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Import)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12785); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 12785; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12786
12787 NullaryNodeType importHolder;
12788 MOZ_TRY_VAR(importHolder, handler_.newPosHolder(pos()))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (importHolder
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12789
12790 TokenKind next;
12791 if (!tokenStream.getToken(&next)) {
12792 return errorResult();
12793 }
12794
12795 if (next == TokenKind::Dot) {
12796 if (!tokenStream.getToken(&next)) {
12797 return errorResult();
12798 }
12799 if (next != TokenKind::Meta) {
12800 error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
12801 return errorResult();
12802 }
12803
12804 if (parseGoal() != ParseGoal::Module) {
12805 errorAt(pos().begin, JSMSG_IMPORT_META_OUTSIDE_MODULE);
12806 return errorResult();
12807 }
12808
12809 NullaryNodeType metaHolder;
12810 MOZ_TRY_VAR(metaHolder, handler_.newPosHolder(pos()))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (metaHolder
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12811
12812 return handler_.newImportMeta(importHolder, metaHolder);
12813 }
12814
12815 if (next == TokenKind::LeftParen && allowCallSyntax) {
12816 Node arg;
12817 MOZ_TRY_VAR(arg, assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (arg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12818
12819 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12820 return errorResult();
12821 }
12822
12823 Node optionalArg;
12824 if (options().importAttributes()) {
12825 if (next == TokenKind::Comma) {
12826 tokenStream.consumeKnownToken(TokenKind::Comma,
12827 TokenStream::SlashIsRegExp);
12828
12829 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12830 return errorResult();
12831 }
12832
12833 if (next != TokenKind::RightParen) {
12834 MOZ_TRY_VAR(optionalArg, assignExpr(InAllowed, yieldHandling,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12835 TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12836
12837 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12838 return errorResult();
12839 }
12840
12841 if (next == TokenKind::Comma) {
12842 tokenStream.consumeKnownToken(TokenKind::Comma,
12843 TokenStream::SlashIsRegExp);
12844 }
12845 } else {
12846 MOZ_TRY_VAR(optionalArg,do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12847 handler_.newPosHolder(TokenPos(pos().end, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12848 }
12849 } else {
12850 MOZ_TRY_VAR(optionalArg,do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12851 handler_.newPosHolder(TokenPos(pos().end, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12852 }
12853 } else {
12854 MOZ_TRY_VAR(optionalArg,do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12855 handler_.newPosHolder(TokenPos(pos().end, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12856 }
12857
12858 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_ARGS)) {
12859 return errorResult();
12860 }
12861
12862 Node spec;
12863 MOZ_TRY_VAR(spec, handler_.newCallImportSpec(arg, optionalArg))do { auto mozTryVarTempResult_ = (handler_.newCallImportSpec(
arg, optionalArg)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (spec) = mozTryVarTempResult_.unwrap(); } while (0)
;
12864
12865 return handler_.newCallImport(importHolder, spec);
12866 }
12867
12868 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
12869 return errorResult();
12870}
12871
12872template <class ParseHandler, typename Unit>
12873typename ParseHandler::NodeResult
12874GeneralParser<ParseHandler, Unit>::primaryExpr(
12875 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
12876 TokenKind tt, PossibleError* possibleError, InvokedPrediction invoked) {
12877 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12877); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 12877; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12878 AutoCheckRecursionLimit recursion(this->fc_);
12879 if (!recursion.check(this->fc_)) {
12880 return errorResult();
12881 }
12882
12883 switch (tt) {
12884 case TokenKind::Function:
12885 return functionExpr(pos().begin, invoked,
12886 FunctionAsyncKind::SyncFunction);
12887
12888 case TokenKind::Class:
12889 return classDefinition(yieldHandling, ClassExpression, NameRequired);
12890
12891 case TokenKind::LeftBracket:
12892 return arrayInitializer(yieldHandling, possibleError);
12893
12894 case TokenKind::LeftCurly:
12895 return objectLiteral(yieldHandling, possibleError);
12896
12897#ifdef ENABLE_RECORD_TUPLE
12898 case TokenKind::HashCurly:
12899 return recordLiteral(yieldHandling);
12900
12901 case TokenKind::HashBracket:
12902 return tupleLiteral(yieldHandling);
12903#endif
12904
12905#ifdef ENABLE_DECORATORS
12906 case TokenKind::At:
12907 return classDefinition(yieldHandling, ClassExpression, NameRequired);
12908#endif
12909
12910 case TokenKind::LeftParen: {
12911 TokenKind next;
12912 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12913 return errorResult();
12914 }
12915
12916 if (next == TokenKind::RightParen) {
12917 // Not valid expression syntax, but this is valid in an arrow function
12918 // with no params: `() => body`.
12919 tokenStream.consumeKnownToken(TokenKind::RightParen,
12920 TokenStream::SlashIsRegExp);
12921
12922 if (!tokenStream.peekToken(&next)) {
12923 return errorResult();
12924 }
12925 if (next != TokenKind::Arrow) {
12926 error(JSMSG_UNEXPECTED_TOKEN, "expression",
12927 TokenKindToDesc(TokenKind::RightParen));
12928 return errorResult();
12929 }
12930
12931 // Now just return something that will allow parsing to continue.
12932 // It doesn't matter what; when we reach the =>, we will rewind and
12933 // reparse the whole arrow function. See Parser::assignExpr.
12934 return handler_.newNullLiteral(pos());
12935 }
12936
12937 // Pass |possibleError| to support destructuring in arrow parameters.
12938 Node expr;
12939 MOZ_TRY_VAR(expr, exprInParens(InAllowed, yieldHandling, TripledotAllowed,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, possibleError)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
12940 possibleError))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, possibleError)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
12941 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_IN_PAREN)) {
12942 return errorResult();
12943 }
12944 return handler_.parenthesize(expr);
12945 }
12946
12947 case TokenKind::TemplateHead:
12948 return templateLiteral(yieldHandling);
12949
12950 case TokenKind::NoSubsTemplate:
12951 return noSubstitutionUntaggedTemplate();
12952
12953 case TokenKind::String:
12954 return stringLiteral();
12955
12956 default: {
12957 if (!TokenKindIsPossibleIdentifier(tt)) {
12958 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
12959 return errorResult();
12960 }
12961
12962 if (tt == TokenKind::Async) {
12963 TokenKind nextSameLine = TokenKind::Eof;
12964 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
12965 return errorResult();
12966 }
12967
12968 if (nextSameLine == TokenKind::Function) {
12969 uint32_t toStringStart = pos().begin;
12970 tokenStream.consumeKnownToken(TokenKind::Function);
12971 return functionExpr(toStringStart, PredictUninvoked,
12972 FunctionAsyncKind::AsyncFunction);
12973 }
12974 }
12975
12976 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12977 if (!name) {
12978 return errorResult();
12979 }
12980
12981 return identifierReference(name);
12982 }
12983
12984 case TokenKind::RegExp:
12985 return newRegExp();
12986
12987 case TokenKind::Number:
12988 return newNumber(anyChars.currentToken());
12989
12990 case TokenKind::BigInt:
12991 return newBigInt();
12992
12993 case TokenKind::True:
12994 return handler_.newBooleanLiteral(true, pos());
12995 case TokenKind::False:
12996 return handler_.newBooleanLiteral(false, pos());
12997 case TokenKind::This: {
12998 NameNodeType thisName = null();
12999 if (pc_->sc()->hasFunctionThisBinding()) {
13000 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
13001 }
13002 return handler_.newThisLiteral(pos(), thisName);
13003 }
13004 case TokenKind::Null:
13005 return handler_.newNullLiteral(pos());
13006
13007 case TokenKind::TripleDot: {
13008 // This isn't valid expression syntax, but it's valid in an arrow
13009 // function as a trailing rest param: `(a, b, ...rest) => body`. Check
13010 // if it's directly under
13011 // CoverParenthesizedExpressionAndArrowParameterList, and check for a
13012 // name, closing parenthesis, and arrow, and allow it only if all are
13013 // present.
13014 if (tripledotHandling != TripledotAllowed) {
13015 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
13016 return errorResult();
13017 }
13018
13019 TokenKind next;
13020 if (!tokenStream.getToken(&next)) {
13021 return errorResult();
13022 }
13023
13024 if (next == TokenKind::LeftBracket || next == TokenKind::LeftCurly) {
13025 // Validate, but don't store the pattern right now. The whole arrow
13026 // function is reparsed in functionFormalParametersAndBody().
13027 MOZ_TRY(destructuringDeclaration(DeclarationKind::CoverArrowParameter,do { auto mozTryTempResult_ = ::mozilla::ToResult(destructuringDeclaration
(DeclarationKind::CoverArrowParameter, yieldHandling, next));
if ((__builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return
mozTryTempResult_.propagateErr(); } } while (0)
13028 yieldHandling, next))do { auto mozTryTempResult_ = ::mozilla::ToResult(destructuringDeclaration
(DeclarationKind::CoverArrowParameter, yieldHandling, next));
if ((__builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return
mozTryTempResult_.propagateErr(); } } while (0)
;
13029 } else {
13030 // This doesn't check that the provided name is allowed, e.g. if
13031 // the enclosing code is strict mode code, any of "let", "yield",
13032 // or "arguments" should be prohibited. Argument-parsing code
13033 // handles that.
13034 if (!TokenKindIsPossibleIdentifier(next)) {
13035 error(JSMSG_UNEXPECTED_TOKEN, "rest argument name",
13036 TokenKindToDesc(next));
13037 return errorResult();
13038 }
13039 }
13040
13041 if (!tokenStream.getToken(&next)) {
13042 return errorResult();
13043 }
13044 if (next != TokenKind::RightParen) {
13045 error(JSMSG_UNEXPECTED_TOKEN, "closing parenthesis",
13046 TokenKindToDesc(next));
13047 return errorResult();
13048 }
13049
13050 if (!tokenStream.peekToken(&next)) {
13051 return errorResult();
13052 }
13053 if (next != TokenKind::Arrow) {
13054 // Advance the scanner for proper error location reporting.
13055 tokenStream.consumeKnownToken(next);
13056 error(JSMSG_UNEXPECTED_TOKEN, "'=>' after argument list",
13057 TokenKindToDesc(next));
13058 return errorResult();
13059 }
13060
13061 anyChars.ungetToken(); // put back right paren
13062
13063 // Return an arbitrary expression node. See case TokenKind::RightParen
13064 // above.
13065 return handler_.newNullLiteral(pos());
13066 }
13067 }
13068}
13069
13070template <class ParseHandler, typename Unit>
13071typename ParseHandler::NodeResult
13072GeneralParser<ParseHandler, Unit>::exprInParens(
13073 InHandling inHandling, YieldHandling yieldHandling,
13074 TripledotHandling tripledotHandling,
13075 PossibleError* possibleError /* = nullptr */) {
13076 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftParen))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftParen))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftParen))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftParen)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 13076); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftParen)"
")"); do { *((volatile int*)__null) = 13076; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
13077 return expr(inHandling, yieldHandling, tripledotHandling, possibleError,
13078 PredictInvoked);
13079}
13080
13081template class PerHandlerParser<FullParseHandler>;
13082template class PerHandlerParser<SyntaxParseHandler>;
13083template class GeneralParser<FullParseHandler, Utf8Unit>;
13084template class GeneralParser<SyntaxParseHandler, Utf8Unit>;
13085template class GeneralParser<FullParseHandler, char16_t>;
13086template class GeneralParser<SyntaxParseHandler, char16_t>;
13087template class Parser<FullParseHandler, Utf8Unit>;
13088template class Parser<SyntaxParseHandler, Utf8Unit>;
13089template class Parser<FullParseHandler, char16_t>;
13090template class Parser<SyntaxParseHandler, char16_t>;
13091
13092} // namespace js::frontend

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