Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name Parser.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src/frontend -fcoverage-compilation-dir=/var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src/frontend -resource-dir /usr/lib/llvm-20/lib/clang/20 -include /var/lib/jenkins/workspace/firefox-scan-build/config/gcc_hidden.h -include /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D WASM_SUPPORTS_HUGE_MEMORY -D JS_CACHEIR_SPEW -D JS_STRUCTURED_SPEW -D JS_HAS_CTYPES -D FFI_BUILDING -D EXPORT_JS_API -D MOZ_HAS_MOZGLUE -D MOZ_SUPPORT_LEAKCHECKING -I /var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src/frontend -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/js/src -I /var/lib/jenkins/workspace/firefox-scan-build/js/src -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /var/lib/jenkins/workspace/firefox-scan-build/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-20/lib/clang/20/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-01-20-090804-167946-1 -x c++ /var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp

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

1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7/*
8 * JS parser.
9 *
10 * This is a recursive-descent parser for the JavaScript language specified by
11 * "The ECMAScript Language Specification" (Standard ECMA-262). It uses
12 * lexical and semantic feedback to disambiguate non-LL(1) structures. It
13 * generates trees of nodes induced by the recursive parsing (not precise
14 * syntax trees, see Parser.h). After tree construction, it rewrites trees to
15 * fold constants and evaluate compile-time expressions.
16 *
17 * This parser attempts no error recovery.
18 */
19
20#include "frontend/Parser.h"
21
22#include "mozilla/ArrayUtils.h"
23#include "mozilla/Assertions.h"
24#include "mozilla/Casting.h"
25#include "mozilla/Range.h"
26#include "mozilla/Sprintf.h"
27#include "mozilla/Try.h" // MOZ_TRY*
28#include "mozilla/Utf8.h"
29#include "mozilla/Variant.h"
30
31#include <memory>
32#include <new>
33#include <type_traits>
34
35#include "jsnum.h"
36#include "jstypes.h"
37
38#include "frontend/FoldConstants.h"
39#include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind
40#include "frontend/ModuleSharedContext.h"
41#include "frontend/ParseNode.h"
42#include "frontend/ParseNodeVerify.h"
43#include "frontend/Parser-macros.h" // MOZ_TRY_VAR_OR_RETURN
44#include "frontend/ParserAtom.h" // TaggedParserAtomIndex, ParserAtomsTable, ParserAtom
45#include "frontend/ScriptIndex.h" // ScriptIndex
46#include "frontend/TokenStream.h" // IsKeyword, ReservedWordTokenKind, ReservedWordToCharZ, DeprecatedContent, *TokenStream*, CharBuffer, TokenKindToDesc
47#include "irregexp/RegExpAPI.h"
48#include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin, JS::ColumnNumberOneOrigin
49#include "js/ErrorReport.h" // JSErrorBase
50#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
51#include "js/HashTable.h"
52#include "js/RegExpFlags.h" // JS::RegExpFlags
53#include "js/Stack.h" // JS::NativeStackLimit
54#include "util/StringBuilder.h" // StringBuilder
55#include "vm/BytecodeUtil.h"
56#include "vm/FunctionFlags.h" // js::FunctionFlags
57#include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind
58#include "vm/JSContext.h"
59#include "vm/JSScript.h"
60#include "vm/ModuleBuilder.h" // js::ModuleBuilder
61#include "vm/Scope.h" // GetScopeDataTrailingNames
62#include "wasm/AsmJS.h"
63
64#include "frontend/ParseContext-inl.h"
65#include "frontend/SharedContext-inl.h"
66
67using namespace js;
68
69using mozilla::AssertedCast;
70using mozilla::AsVariant;
71using mozilla::Maybe;
72using mozilla::Nothing;
73using mozilla::PointerRangeSize;
74using mozilla::Some;
75using mozilla::Utf8Unit;
76
77using JS::ReadOnlyCompileOptions;
78using JS::RegExpFlags;
79
80namespace js::frontend {
81
82using DeclaredNamePtr = ParseContext::Scope::DeclaredNamePtr;
83using AddDeclaredNamePtr = ParseContext::Scope::AddDeclaredNamePtr;
84using BindingIter = ParseContext::Scope::BindingIter;
85using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr;
86
87using ParserBindingNameVector = Vector<ParserBindingName, 6>;
88
89static inline void PropagateTransitiveParseFlags(const FunctionBox* inner,
90 SharedContext* outer) {
91 if (inner->bindingsAccessedDynamically()) {
92 outer->setBindingsAccessedDynamically();
93 }
94 if (inner->hasDirectEval()) {
95 outer->setHasDirectEval();
96 }
97}
98
99static bool StatementKindIsBraced(StatementKind kind) {
100 return kind == StatementKind::Block || kind == StatementKind::Switch ||
101 kind == StatementKind::Try || kind == StatementKind::Catch ||
102 kind == StatementKind::Finally;
103}
104
105template <class ParseHandler, typename Unit>
106inline typename GeneralParser<ParseHandler, Unit>::FinalParser*
107GeneralParser<ParseHandler, Unit>::asFinalParser() {
108 static_assert(
109 std::is_base_of_v<GeneralParser<ParseHandler, Unit>, FinalParser>,
110 "inheritance relationship required by the static_cast<> below");
111
112 return static_cast<FinalParser*>(this);
113}
114
115template <class ParseHandler, typename Unit>
116inline const typename GeneralParser<ParseHandler, Unit>::FinalParser*
117GeneralParser<ParseHandler, Unit>::asFinalParser() const {
118 static_assert(
119 std::is_base_of_v<GeneralParser<ParseHandler, Unit>, FinalParser>,
120 "inheritance relationship required by the static_cast<> below");
121
122 return static_cast<const FinalParser*>(this);
123}
124
125template <class ParseHandler, typename Unit>
126template <typename ConditionT, typename ErrorReportT>
127bool GeneralParser<ParseHandler, Unit>::mustMatchTokenInternal(
128 ConditionT condition, ErrorReportT errorReport) {
129 MOZ_ASSERT(condition(TokenKind::Div) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::Div) == false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(condition(TokenKind::Div) ==
false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("condition(TokenKind::Div) == false", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::Div) == false"
")"); do { *((volatile int*)__null) = 129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
130 MOZ_ASSERT(condition(TokenKind::DivAssign) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::DivAssign) == false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(condition(TokenKind::DivAssign) == false))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("condition(TokenKind::DivAssign) == false"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::DivAssign) == false"
")"); do { *((volatile int*)__null) = 130; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
131 MOZ_ASSERT(condition(TokenKind::RegExp) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::RegExp) == false)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(condition(TokenKind::RegExp) == false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("condition(TokenKind::RegExp) == false"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 131); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::RegExp) == false"
")"); do { *((volatile int*)__null) = 131; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
132
133 TokenKind actual;
134 if (!tokenStream.getToken(&actual, TokenStream::SlashIsInvalid)) {
135 return false;
136 }
137 if (!condition(actual)) {
138 errorReport(actual);
139 return false;
140 }
141 return true;
142}
143
144ParserSharedBase::ParserSharedBase(FrontendContext* fc,
145 CompilationState& compilationState,
146 Kind kind)
147 : fc_(fc),
148 alloc_(compilationState.parserAllocScope.alloc()),
149 compilationState_(compilationState),
150 pc_(nullptr),
151 usedNames_(compilationState.usedNames) {
152 fc_->nameCollectionPool().addActiveCompilation();
153}
154
155ParserSharedBase::~ParserSharedBase() {
156 fc_->nameCollectionPool().removeActiveCompilation();
157}
158
159#if defined(DEBUG1) || defined(JS_JITSPEW1)
160void ParserSharedBase::dumpAtom(TaggedParserAtomIndex index) const {
161 parserAtoms().dump(index);
162}
163#endif
164
165ParserBase::ParserBase(FrontendContext* fc,
166 const ReadOnlyCompileOptions& options,
167 CompilationState& compilationState)
168 : ParserSharedBase(fc, compilationState, ParserSharedBase::Kind::Parser),
169 anyChars(fc, options, this),
170 ss(nullptr),
171#ifdef DEBUG1
172 checkOptionsCalled_(false),
173#endif
174 isUnexpectedEOF_(false),
175 awaitHandling_(AwaitIsName),
176 inParametersOfAsyncFunction_(false) {
177}
178
179bool ParserBase::checkOptions() {
180#ifdef DEBUG1
181 checkOptionsCalled_ = true;
182#endif
183
184 return anyChars.checkOptions();
185}
186
187ParserBase::~ParserBase() { MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 187); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 187; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; }
188
189JSAtom* ParserBase::liftParserAtomToJSAtom(TaggedParserAtomIndex index) {
190 JSContext* cx = fc_->maybeCurrentJSContext();
191 MOZ_ASSERT(cx)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(cx)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(cx))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("cx", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 191); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cx" ")"); do
{ *((volatile int*)__null) = 191; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
192 return parserAtoms().toJSAtom(cx, fc_, index,
193 compilationState_.input.atomCache);
194}
195
196template <class ParseHandler>
197PerHandlerParser<ParseHandler>::PerHandlerParser(
198 FrontendContext* fc, const ReadOnlyCompileOptions& options,
199 CompilationState& compilationState, void* internalSyntaxParser)
200 : ParserBase(fc, options, compilationState),
201 handler_(fc, compilationState),
202 internalSyntaxParser_(internalSyntaxParser) {
203 MOZ_ASSERT(compilationState.isInitialStencil() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(compilationState.isInitialStencil() == compilationState
.input.isInitialStencil())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(compilationState.isInitialStencil
() == compilationState.input.isInitialStencil()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 204); AnnotateMozCrashReason("MOZ_ASSERT" "(" "compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
")"); do { *((volatile int*)__null) = 204; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
204 compilationState.input.isInitialStencil())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(compilationState.isInitialStencil() == compilationState
.input.isInitialStencil())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(compilationState.isInitialStencil
() == compilationState.input.isInitialStencil()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 204); AnnotateMozCrashReason("MOZ_ASSERT" "(" "compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
")"); do { *((volatile int*)__null) = 204; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
205}
206
207template <class ParseHandler, typename Unit>
208GeneralParser<ParseHandler, Unit>::GeneralParser(
209 FrontendContext* fc, const ReadOnlyCompileOptions& options,
210 const Unit* units, size_t length, CompilationState& compilationState,
211 SyntaxParser* syntaxParser)
212 : Base(fc, options, compilationState, syntaxParser),
213 tokenStream(fc, &compilationState.parserAtoms, options, units, length) {}
214
215template <typename Unit>
216void Parser<SyntaxParseHandler, Unit>::setAwaitHandling(
217 AwaitHandling awaitHandling) {
218 this->awaitHandling_ = awaitHandling;
219}
220
221template <typename Unit>
222void Parser<FullParseHandler, Unit>::setAwaitHandling(
223 AwaitHandling awaitHandling) {
224 this->awaitHandling_ = awaitHandling;
225 if (SyntaxParser* syntaxParser = getSyntaxParser()) {
226 syntaxParser->setAwaitHandling(awaitHandling);
227 }
228}
229
230template <class ParseHandler, typename Unit>
231inline void GeneralParser<ParseHandler, Unit>::setAwaitHandling(
232 AwaitHandling awaitHandling) {
233 asFinalParser()->setAwaitHandling(awaitHandling);
234}
235
236template <typename Unit>
237void Parser<SyntaxParseHandler, Unit>::setInParametersOfAsyncFunction(
238 bool inParameters) {
239 this->inParametersOfAsyncFunction_ = inParameters;
240}
241
242template <typename Unit>
243void Parser<FullParseHandler, Unit>::setInParametersOfAsyncFunction(
244 bool inParameters) {
245 this->inParametersOfAsyncFunction_ = inParameters;
246 if (SyntaxParser* syntaxParser = getSyntaxParser()) {
247 syntaxParser->setInParametersOfAsyncFunction(inParameters);
248 }
249}
250
251template <class ParseHandler, typename Unit>
252inline void GeneralParser<ParseHandler, Unit>::setInParametersOfAsyncFunction(
253 bool inParameters) {
254 asFinalParser()->setInParametersOfAsyncFunction(inParameters);
255}
256
257template <class ParseHandler>
258FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
259 FunctionNodeType funNode, TaggedParserAtomIndex explicitName,
260 FunctionFlags flags, uint32_t toStringStart, Directives inheritedDirectives,
261 GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
262 MOZ_ASSERT(funNode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funNode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funNode))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("funNode", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 262); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funNode" ")"
); do { *((volatile int*)__null) = 262; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
263
264 ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
265 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
266 ReportAllocationOverflow(fc_);
267 return nullptr;
268 }
269 if (!compilationState_.appendScriptStencilAndData(fc_)) {
270 return nullptr;
271 }
272
273 bool isInitialStencil = compilationState_.isInitialStencil();
274
275 // This source extent will be further filled in during the remainder of parse.
276 SourceExtent extent;
277 extent.toStringStart = toStringStart;
278
279 FunctionBox* funbox = alloc_.new_<FunctionBox>(
280 fc_, extent, compilationState_, inheritedDirectives, generatorKind,
281 asyncKind, isInitialStencil, explicitName, flags, index);
282 if (!funbox) {
283 ReportOutOfMemory(fc_);
284 return nullptr;
285 }
286
287 handler_.setFunctionBox(funNode, funbox);
288
289 return funbox;
290}
291
292template <class ParseHandler>
293FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
294 FunctionNodeType funNode, const ScriptStencil& cachedScriptData,
295 const ScriptStencilExtra& cachedScriptExtra) {
296 MOZ_ASSERT(funNode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funNode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funNode))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("funNode", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 296); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funNode" ")"
); do { *((volatile int*)__null) = 296; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
297
298 ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
299 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
300 ReportAllocationOverflow(fc_);
301 return nullptr;
302 }
303 if (!compilationState_.appendScriptStencilAndData(fc_)) {
304 return nullptr;
305 }
306
307 FunctionBox* funbox = alloc_.new_<FunctionBox>(
308 fc_, cachedScriptExtra.extent, compilationState_,
309 Directives(/* strict = */ false), cachedScriptExtra.generatorKind(),
310 cachedScriptExtra.asyncKind(), compilationState_.isInitialStencil(),
311 cachedScriptData.functionAtom, cachedScriptData.functionFlags, index);
312 if (!funbox) {
313 ReportOutOfMemory(fc_);
314 return nullptr;
315 }
316
317 handler_.setFunctionBox(funNode, funbox);
318 funbox->initFromScriptStencilExtra(cachedScriptExtra);
319
320 return funbox;
321}
322
323bool ParserBase::setSourceMapInfo() {
324 // If support for source pragmas have been fully disabled, we can skip
325 // processing of all of these values.
326 if (!options().sourcePragmas()) {
327 return true;
328 }
329
330 // Not all clients initialize ss. Can't update info to an object that isn't
331 // there.
332 if (!ss) {
333 return true;
334 }
335
336 if (anyChars.hasDisplayURL()) {
337 if (!ss->setDisplayURL(fc_, anyChars.displayURL())) {
338 return false;
339 }
340 }
341
342 if (anyChars.hasSourceMapURL()) {
343 MOZ_ASSERT(!ss->hasSourceMapURL())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!ss->hasSourceMapURL())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!ss->hasSourceMapURL())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("!ss->hasSourceMapURL()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 343); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!ss->hasSourceMapURL()"
")"); do { *((volatile int*)__null) = 343; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
344 if (!ss->setSourceMapURL(fc_, anyChars.sourceMapURL())) {
345 return false;
346 }
347 }
348
349 /*
350 * Source map URLs passed as a compile option (usually via a HTTP source map
351 * header) override any source map urls passed as comment pragmas.
352 */
353 if (options().sourceMapURL()) {
354 // Warn about the replacement, but use the new one.
355 if (ss->hasSourceMapURL()) {
356 if (!warningNoOffset(JSMSG_ALREADY_HAS_PRAGMA, ss->filename(),
357 "//# sourceMappingURL")) {
358 return false;
359 }
360 }
361
362 if (!ss->setSourceMapURL(fc_, options().sourceMapURL())) {
363 return false;
364 }
365 }
366
367 return true;
368}
369
370/*
371 * Parse a top-level JS script.
372 */
373template <class ParseHandler, typename Unit>
374typename ParseHandler::ListNodeResult
375GeneralParser<ParseHandler, Unit>::parse() {
376 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 376); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 376; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
377
378 SourceExtent extent = SourceExtent::makeGlobalExtent(
379 /* len = */ 0, options().lineno,
380 JS::LimitedColumnNumberOneOrigin::fromUnlimited(
381 JS::ColumnNumberOneOrigin(options().column)));
382 Directives directives(options().forceStrictMode());
383 GlobalSharedContext globalsc(this->fc_, ScopeKind::Global, options(),
384 directives, extent);
385 SourceParseContext globalpc(this, &globalsc, /* newDirectives = */ nullptr);
386 if (!globalpc.init()) {
387 return errorResult();
388 }
389
390 ParseContext::VarScope varScope(this);
391 if (!varScope.init(pc_)) {
392 return errorResult();
393 }
394
395 ListNodeType stmtList;
396 MOZ_TRY_VAR(stmtList, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (stmtList) =
mozTryVarTempResult_.unwrap(); } while (0)
;
397
398 TokenKind tt;
399 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
400 return errorResult();
401 }
402 if (tt != TokenKind::Eof) {
403 error(JSMSG_GARBAGE_AFTER_INPUT, "script", TokenKindToDesc(tt));
404 return errorResult();
405 }
406
407 if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
408 return errorResult();
409 }
410
411 return stmtList;
412}
413
414/*
415 * Strict mode forbids introducing new definitions for 'eval', 'arguments',
416 * 'let', 'static', 'yield', or for any strict mode reserved word.
417 */
418bool ParserBase::isValidStrictBinding(TaggedParserAtomIndex name) {
419 TokenKind tt = ReservedWordTokenKind(name);
420 if (tt == TokenKind::Limit) {
421 return name != TaggedParserAtomIndex::WellKnown::eval() &&
422 name != TaggedParserAtomIndex::WellKnown::arguments();
423 }
424 return tt != TokenKind::Let && tt != TokenKind::Static &&
425 tt != TokenKind::Yield && !TokenKindIsStrictReservedWord(tt);
426}
427
428/*
429 * Returns true if all parameter names are valid strict mode binding names and
430 * no duplicate parameter names are present.
431 */
432bool ParserBase::hasValidSimpleStrictParameterNames() {
433 MOZ_ASSERT(pc_->isFunctionBox() &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox() && pc_->functionBox
()->hasSimpleParameterList())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox() &&
pc_->functionBox()->hasSimpleParameterList()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 434); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
")"); do { *((volatile int*)__null) = 434; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
434 pc_->functionBox()->hasSimpleParameterList())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox() && pc_->functionBox
()->hasSimpleParameterList())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox() &&
pc_->functionBox()->hasSimpleParameterList()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 434); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
")"); do { *((volatile int*)__null) = 434; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
435
436 if (pc_->functionBox()->hasDuplicateParameters) {
437 return false;
438 }
439
440 for (auto name : pc_->positionalFormalParameterNames()) {
441 MOZ_ASSERT(name)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(name))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("name", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 441); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name" ")"); do
{ *((volatile int*)__null) = 441; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
442 if (!isValidStrictBinding(name)) {
443 return false;
444 }
445 }
446 return true;
447}
448
449template <class ParseHandler, typename Unit>
450void GeneralParser<ParseHandler, Unit>::reportMissingClosing(
451 unsigned errorNumber, unsigned noteNumber, uint32_t openedPos) {
452 auto notes = MakeUnique<JSErrorNotes>();
453 if (!notes) {
454 ReportOutOfMemory(this->fc_);
455 return;
456 }
457
458 uint32_t line;
459 JS::LimitedColumnNumberOneOrigin column;
460 tokenStream.computeLineAndColumn(openedPos, &line, &column);
461
462 const size_t MaxWidth = sizeof("4294967295");
463 char columnNumber[MaxWidth];
464 SprintfLiteral(columnNumber, "%" PRIu32"u", column.oneOriginValue());
465 char lineNumber[MaxWidth];
466 SprintfLiteral(lineNumber, "%" PRIu32"u", line);
467
468 if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
469 JS::ColumnNumberOneOrigin(column), GetErrorMessage,
470 nullptr, noteNumber, lineNumber, columnNumber)) {
471 return;
472 }
473
474 errorWithNotes(std::move(notes), errorNumber);
475}
476
477template <class ParseHandler, typename Unit>
478void GeneralParser<ParseHandler, Unit>::reportRedeclarationHelper(
479 TaggedParserAtomIndex& name, DeclarationKind& prevKind, TokenPos& pos,
480 uint32_t& prevPos, const unsigned& errorNumber,
481 const unsigned& noteErrorNumber) {
482 UniqueChars bytes = this->parserAtoms().toPrintableString(name);
483 if (!bytes) {
484 ReportOutOfMemory(this->fc_);
485 return;
486 }
487
488 if (prevPos == DeclaredNameInfo::npos) {
489 errorAt(pos.begin, errorNumber, DeclarationKindString(prevKind),
490 bytes.get());
491 return;
492 }
493
494 auto notes = MakeUnique<JSErrorNotes>();
495 if (!notes) {
496 ReportOutOfMemory(this->fc_);
497 return;
498 }
499
500 uint32_t line;
501 JS::LimitedColumnNumberOneOrigin column;
502 tokenStream.computeLineAndColumn(prevPos, &line, &column);
503
504 const size_t MaxWidth = sizeof("4294967295");
505 char columnNumber[MaxWidth];
506 SprintfLiteral(columnNumber, "%" PRIu32"u", column.oneOriginValue());
507 char lineNumber[MaxWidth];
508 SprintfLiteral(lineNumber, "%" PRIu32"u", line);
509
510 if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
511 JS::ColumnNumberOneOrigin(column), GetErrorMessage,
512 nullptr, noteErrorNumber, lineNumber,
513 columnNumber)) {
514 return;
515 }
516
517 errorWithNotesAt(std::move(notes), pos.begin, errorNumber,
518 DeclarationKindString(prevKind), bytes.get());
519}
520
521template <class ParseHandler, typename Unit>
522void GeneralParser<ParseHandler, Unit>::reportRedeclaration(
523 TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
524 uint32_t prevPos) {
525 reportRedeclarationHelper(name, prevKind, pos, prevPos, JSMSG_REDECLARED_VAR,
526 JSMSG_PREV_DECLARATION);
527}
528
529template <class ParseHandler, typename Unit>
530void GeneralParser<ParseHandler, Unit>::reportMismatchedPlacement(
531 TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
532 uint32_t prevPos) {
533 reportRedeclarationHelper(name, prevKind, pos, prevPos,
534 JSMSG_MISMATCHED_PLACEMENT, JSMSG_PREV_DECLARATION);
535}
536
537// notePositionalFormalParameter is called for both the arguments of a regular
538// function definition and the arguments specified by the Function
539// constructor.
540//
541// The 'disallowDuplicateParams' bool indicates whether the use of another
542// feature (destructuring or default arguments) disables duplicate arguments.
543// (ECMA-262 requires us to support duplicate parameter names, but, for newer
544// features, we consider the code to have "opted in" to higher standards and
545// forbid duplicates.)
546template <class ParseHandler, typename Unit>
547bool GeneralParser<ParseHandler, Unit>::notePositionalFormalParameter(
548 FunctionNodeType funNode, TaggedParserAtomIndex name, uint32_t beginPos,
549 bool disallowDuplicateParams, bool* duplicatedParam) {
550 if (AddDeclaredNamePtr p =
551 pc_->functionScope().lookupDeclaredNameForAdd(name)) {
552 if (disallowDuplicateParams) {
553 error(JSMSG_BAD_DUP_ARGS);
554 return false;
555 }
556
557 // Strict-mode disallows duplicate args. We may not know whether we are
558 // in strict mode or not (since the function body hasn't been parsed).
559 // In such cases, report will queue up the potential error and return
560 // 'true'.
561 if (pc_->sc()->strict()) {
562 UniqueChars bytes = this->parserAtoms().toPrintableString(name);
563 if (!bytes) {
564 ReportOutOfMemory(this->fc_);
565 return false;
566 }
567 if (!strictModeError(JSMSG_DUPLICATE_FORMAL, bytes.get())) {
568 return false;
569 }
570 }
571
572 *duplicatedParam = true;
573 } else {
574 DeclarationKind kind = DeclarationKind::PositionalFormalParameter;
575 if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, beginPos)) {
576 return false;
577 }
578 }
579
580 if (!pc_->positionalFormalParameterNames().append(
581 TrivialTaggedParserAtomIndex::from(name))) {
582 ReportOutOfMemory(this->fc_);
583 return false;
584 }
585
586 NameNodeType paramNode;
587 MOZ_TRY_VAR_OR_RETURN(paramNode, newName(name), false)do { auto parserTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(paramNode) = parserTryVarTempResult_.unwrap(); } while (0)
;
588
589 handler_.addFunctionFormalParameter(funNode, paramNode);
590 return true;
591}
592
593template <class ParseHandler>
594bool PerHandlerParser<ParseHandler>::noteDestructuredPositionalFormalParameter(
595 FunctionNodeType funNode, Node destruct) {
596 // Append an empty name to the positional formals vector to keep track of
597 // argument slots when making FunctionScope::ParserData.
598 if (!pc_->positionalFormalParameterNames().append(
599 TrivialTaggedParserAtomIndex::null())) {
600 ReportOutOfMemory(fc_);
601 return false;
602 }
603
604 handler_.addFunctionFormalParameter(funNode, destruct);
605 return true;
606}
607
608template <class ParseHandler, typename Unit>
609bool GeneralParser<ParseHandler, Unit>::noteDeclaredName(
610 TaggedParserAtomIndex name, DeclarationKind kind, TokenPos pos,
611 ClosedOver isClosedOver) {
612 // The asm.js validator does all its own symbol-table management so, as an
613 // optimization, avoid doing any work here.
614 if (pc_->useAsmOrInsideUseAsm()) {
615 return true;
616 }
617
618 switch (kind) {
619 case DeclarationKind::Var:
620 case DeclarationKind::BodyLevelFunction: {
621 Maybe<DeclarationKind> redeclaredKind;
622 uint32_t prevPos;
623 if (!pc_->tryDeclareVar(name, this, kind, pos.begin, &redeclaredKind,
624 &prevPos)) {
625 return false;
626 }
627
628 if (redeclaredKind) {
629 reportRedeclaration(name, *redeclaredKind, pos, prevPos);
630 return false;
631 }
632
633 break;
634 }
635
636 case DeclarationKind::ModuleBodyLevelFunction: {
637 MOZ_ASSERT(pc_->atModuleLevel())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->atModuleLevel())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->atModuleLevel()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->atModuleLevel()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 637); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->atModuleLevel()"
")"); do { *((volatile int*)__null) = 637; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
638
639 AddDeclaredNamePtr p = pc_->varScope().lookupDeclaredNameForAdd(name);
640 if (p) {
641 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
642 return false;
643 }
644
645 if (!pc_->varScope().addDeclaredName(pc_, p, name, kind, pos.begin,
646 isClosedOver)) {
647 return false;
648 }
649
650 // Body-level functions in modules are always closed over.
651 pc_->varScope().lookupDeclaredName(name)->value()->setClosedOver();
652
653 break;
654 }
655
656 case DeclarationKind::FormalParameter: {
657 // It is an early error if any non-positional formal parameter name
658 // (e.g., destructuring formal parameter) is duplicated.
659
660 AddDeclaredNamePtr p =
661 pc_->functionScope().lookupDeclaredNameForAdd(name);
662 if (p) {
663 error(JSMSG_BAD_DUP_ARGS);
664 return false;
665 }
666
667 if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, pos.begin,
668 isClosedOver)) {
669 return false;
670 }
671
672 break;
673 }
674
675 case DeclarationKind::LexicalFunction:
676 case DeclarationKind::PrivateName:
677 case DeclarationKind::Synthetic:
678 case DeclarationKind::PrivateMethod: {
679 ParseContext::Scope* scope = pc_->innermostScope();
680 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
681 if (p) {
682 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
683 return false;
684 }
685
686 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
687 isClosedOver)) {
688 return false;
689 }
690
691 break;
692 }
693
694 case DeclarationKind::SloppyLexicalFunction: {
695 // Functions in block have complex allowances in sloppy mode for being
696 // labelled that other lexical declarations do not have. Those checks
697 // are done in functionStmt.
698
699 ParseContext::Scope* scope = pc_->innermostScope();
700 if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
701 // It is usually an early error if there is another declaration
702 // with the same name in the same scope.
703 //
704 // Sloppy lexical functions may redeclare other sloppy lexical
705 // functions for web compatibility reasons.
706 if (p->value()->kind() != DeclarationKind::SloppyLexicalFunction) {
707 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
708 return false;
709 }
710 } else {
711 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
712 isClosedOver)) {
713 return false;
714 }
715 }
716
717 break;
718 }
719
720 case DeclarationKind::Let:
721 case DeclarationKind::Const:
722#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
723 case DeclarationKind::Using:
724 case DeclarationKind::AwaitUsing:
725#endif
726 case DeclarationKind::Class:
727 // The BoundNames of LexicalDeclaration and ForDeclaration must not
728 // contain 'let'. (CatchParameter is the only lexical binding form
729 // without this restriction.)
730 if (name == TaggedParserAtomIndex::WellKnown::let()) {
731 errorAt(pos.begin, JSMSG_LEXICAL_DECL_DEFINES_LET);
732 return false;
733 }
734
735 // For body-level lexically declared names in a function, it is an
736 // early error if there is a formal parameter of the same name. This
737 // needs a special check if there is an extra var scope due to
738 // parameter expressions.
739 if (pc_->isFunctionExtraBodyVarScopeInnermost()) {
740 DeclaredNamePtr p = pc_->functionScope().lookupDeclaredName(name);
741 if (p && DeclarationKindIsParameter(p->value()->kind())) {
742 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
743 return false;
744 }
745 }
746
747 [[fallthrough]];
748
749 case DeclarationKind::Import:
750 // Module code is always strict, so 'let' is always a keyword and never a
751 // name.
752 MOZ_ASSERT(name != TaggedParserAtomIndex::WellKnown::let())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name != TaggedParserAtomIndex::WellKnown::let())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(name != TaggedParserAtomIndex::WellKnown::let()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("name != TaggedParserAtomIndex::WellKnown::let()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 752); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name != TaggedParserAtomIndex::WellKnown::let()"
")"); do { *((volatile int*)__null) = 752; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
753 [[fallthrough]];
754
755 case DeclarationKind::SimpleCatchParameter:
756 case DeclarationKind::CatchParameter: {
757 ParseContext::Scope* scope = pc_->innermostScope();
758
759 // It is an early error if there is another declaration with the same
760 // name in the same scope.
761 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
762 if (p) {
763 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
764 return false;
765 }
766
767 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
768 isClosedOver)) {
769 return false;
770 }
771
772 break;
773 }
774
775 case DeclarationKind::CoverArrowParameter:
776 // CoverArrowParameter is only used as a placeholder declaration kind.
777 break;
778
779 case DeclarationKind::PositionalFormalParameter:
780 MOZ_CRASH(do { do { } while (false); MOZ_ReportCrash("" "Positional formal parameter names should use "
"notePositionalFormalParameter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 782); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 782; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
781 "Positional formal parameter names should use "do { do { } while (false); MOZ_ReportCrash("" "Positional formal parameter names should use "
"notePositionalFormalParameter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 782); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 782; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
782 "notePositionalFormalParameter")do { do { } while (false); MOZ_ReportCrash("" "Positional formal parameter names should use "
"notePositionalFormalParameter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 782); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 782; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
;
783 break;
784
785 case DeclarationKind::VarForAnnexBLexicalFunction:
786 MOZ_CRASH(do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 789); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 789; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
787 "Synthesized Annex B vars should go through "do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 789); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 789; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
788 "addPossibleAnnexBFunctionBox, and "do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 789); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 789; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
789 "propagateAndMarkAnnexBFunctionBoxes")do { do { } while (false); MOZ_ReportCrash("" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 789); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 789; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
790 break;
791 }
792
793 return true;
794}
795
796template <class ParseHandler, typename Unit>
797bool GeneralParser<ParseHandler, Unit>::noteDeclaredPrivateName(
798 Node nameNode, TaggedParserAtomIndex name, PropertyType propType,
799 FieldPlacement placement, TokenPos pos) {
800 ParseContext::Scope* scope = pc_->innermostScope();
801 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
802
803 DeclarationKind declKind = DeclarationKind::PrivateName;
804
805 // Our strategy for enabling debugger functionality is to mark names as closed
806 // over, even if they don't necessarily need to be, to ensure that they are
807 // included in the environment object. This allows us to easily look them up
808 // by name when needed, even if there is no corresponding property on an
809 // object, as is the case with getter, setters and private methods.
810 ClosedOver closedOver = ClosedOver::Yes;
811 PrivateNameKind kind;
812 switch (propType) {
813 case PropertyType::Field:
814 kind = PrivateNameKind::Field;
815 closedOver = ClosedOver::No;
816 break;
817 case PropertyType::FieldWithAccessor:
818 // In this case, we create a new private field for the underlying storage,
819 // and use the current name for the getter and setter.
820 kind = PrivateNameKind::GetterSetter;
821 break;
822 case PropertyType::Method:
823 case PropertyType::GeneratorMethod:
824 case PropertyType::AsyncMethod:
825 case PropertyType::AsyncGeneratorMethod:
826 if (placement == FieldPlacement::Instance) {
827 // Optimized private method. Non-optimized paths still get
828 // DeclarationKind::Synthetic.
829 declKind = DeclarationKind::PrivateMethod;
830 }
831 kind = PrivateNameKind::Method;
832 break;
833 case PropertyType::Getter:
834 kind = PrivateNameKind::Getter;
835 break;
836 case PropertyType::Setter:
837 kind = PrivateNameKind::Setter;
838 break;
839 default:
840 MOZ_CRASH("Invalid Property Type for noteDeclarePrivateName")do { do { } while (false); MOZ_ReportCrash("" "Invalid Property Type for noteDeclarePrivateName"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 840); AnnotateMozCrashReason("MOZ_CRASH(" "Invalid Property Type for noteDeclarePrivateName"
")"); do { *((volatile int*)__null) = 840; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
841 }
842
843 if (p) {
844 PrivateNameKind prevKind = p->value()->privateNameKind();
845 if ((prevKind == PrivateNameKind::Getter &&
846 kind == PrivateNameKind::Setter) ||
847 (prevKind == PrivateNameKind::Setter &&
848 kind == PrivateNameKind::Getter)) {
849 // Private methods demands that
850 //
851 // class A {
852 // static set #x(_) {}
853 // get #x() { }
854 // }
855 //
856 // Report a SyntaxError.
857 if (placement == p->value()->placement()) {
858 p->value()->setPrivateNameKind(PrivateNameKind::GetterSetter);
859 handler_.setPrivateNameKind(nameNode, PrivateNameKind::GetterSetter);
860 return true;
861 }
862 }
863
864 reportMismatchedPlacement(name, p->value()->kind(), pos, p->value()->pos());
865 return false;
866 }
867
868 if (!scope->addDeclaredName(pc_, p, name, declKind, pos.begin, closedOver)) {
869 return false;
870 }
871
872 DeclaredNamePtr declared = scope->lookupDeclaredName(name);
873 declared->value()->setPrivateNameKind(kind);
874 declared->value()->setFieldPlacement(placement);
875 handler_.setPrivateNameKind(nameNode, kind);
876
877 return true;
878}
879
880bool ParserBase::noteUsedNameInternal(TaggedParserAtomIndex name,
881 NameVisibility visibility,
882 mozilla::Maybe<TokenPos> tokenPosition) {
883 // The asm.js validator does all its own symbol-table management so, as an
884 // optimization, avoid doing any work here.
885 if (pc_->useAsmOrInsideUseAsm()) {
886 return true;
887 }
888
889 // Global bindings are properties and not actual bindings; we don't need
890 // to know if they are closed over. So no need to track used name at the
891 // global scope. It is not incorrect to track them, this is an
892 // optimization.
893 //
894 // Exceptions:
895 // (a) Track private name references, as the used names tracker is used to
896 // provide early errors for undeclared private name references
897 // (b) If the script has extra bindings, track all references to detect
898 // references to extra bindings
899 ParseContext::Scope* scope = pc_->innermostScope();
900 if (pc_->sc()->isGlobalContext() && scope == &pc_->varScope() &&
901 visibility == NameVisibility::Public &&
902 !this->compilationState_.input.hasExtraBindings()) {
903 return true;
904 }
905
906 return usedNames_.noteUse(fc_, name, visibility, pc_->scriptId(), scope->id(),
907 tokenPosition);
908}
909
910template <class ParseHandler>
911bool PerHandlerParser<ParseHandler>::
912 propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope) {
913 // Now that we have all the declared names in the scope, check which
914 // functions should exhibit Annex B semantics.
915 if (!scope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
916 return false;
917 }
918
919 if (handler_.reuseClosedOverBindings()) {
920 MOZ_ASSERT(pc_->isOutermostOfCurrentCompile())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isOutermostOfCurrentCompile())>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(pc_->isOutermostOfCurrentCompile()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->isOutermostOfCurrentCompile()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 920); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isOutermostOfCurrentCompile()"
")"); do { *((volatile int*)__null) = 920; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
921
922 // Closed over bindings for all scopes are stored in a contiguous array, in
923 // the same order as the order in which scopes are visited, and seprated by
924 // TaggedParserAtomIndex::null().
925 uint32_t slotCount = scope.declaredCount();
926 while (auto parserAtom = handler_.nextLazyClosedOverBinding()) {
927 scope.lookupDeclaredName(parserAtom)->value()->setClosedOver();
928 MOZ_ASSERT(slotCount > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(slotCount > 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(slotCount > 0))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("slotCount > 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 928); AnnotateMozCrashReason("MOZ_ASSERT" "(" "slotCount > 0"
")"); do { *((volatile int*)__null) = 928; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
929 slotCount--;
930 }
931
932 if (pc_->isGeneratorOrAsync()) {
933 scope.setOwnStackSlotCount(slotCount);
934 }
935 return true;
936 }
937
938 constexpr bool isSyntaxParser =
939 std::is_same_v<ParseHandler, SyntaxParseHandler>;
940 uint32_t scriptId = pc_->scriptId();
941 uint32_t scopeId = scope.id();
942
943 uint32_t slotCount = 0;
944 for (BindingIter bi = scope.bindings(pc_); bi; bi++) {
945 bool closedOver = false;
946 if (UsedNamePtr p = usedNames_.lookup(bi.name())) {
947 p->value().noteBoundInScope(scriptId, scopeId, &closedOver);
948 if (closedOver) {
949 bi.setClosedOver();
950
951 if constexpr (isSyntaxParser) {
952 if (!pc_->closedOverBindingsForLazy().append(
953 TrivialTaggedParserAtomIndex::from(bi.name()))) {
954 ReportOutOfMemory(fc_);
955 return false;
956 }
957 }
958 }
959 }
960
961 if constexpr (!isSyntaxParser) {
962 if (!closedOver) {
963 slotCount++;
964 }
965 }
966 }
967 if constexpr (!isSyntaxParser) {
968 if (pc_->isGeneratorOrAsync()) {
969 scope.setOwnStackSlotCount(slotCount);
970 }
971 }
972
973 // Append a nullptr to denote end-of-scope.
974 if constexpr (isSyntaxParser) {
975 if (!pc_->closedOverBindingsForLazy().append(
976 TrivialTaggedParserAtomIndex::null())) {
977 ReportOutOfMemory(fc_);
978 return false;
979 }
980 }
981
982 return true;
983}
984
985template <typename Unit>
986bool Parser<FullParseHandler, Unit>::checkStatementsEOF() {
987 // This is designed to be paired with parsing a statement list at the top
988 // level.
989 //
990 // The statementList() call breaks on TokenKind::RightCurly, so make sure
991 // we've reached EOF here.
992 TokenKind tt;
993 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
994 return false;
995 }
996 if (tt != TokenKind::Eof) {
997 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
998 return false;
999 }
1000 return true;
1001}
1002
1003template <typename ScopeT>
1004typename ScopeT::ParserData* NewEmptyBindingData(FrontendContext* fc,
1005 LifoAlloc& alloc,
1006 uint32_t numBindings) {
1007 using Data = typename ScopeT::ParserData;
1008 size_t allocSize = SizeOfScopeData<Data>(numBindings);
1009 auto* bindings = alloc.newWithSize<Data>(allocSize, numBindings);
1010 if (!bindings) {
1011 ReportOutOfMemory(fc);
1012 }
1013 return bindings;
1014}
1015
1016GlobalScope::ParserData* NewEmptyGlobalScopeData(FrontendContext* fc,
1017 LifoAlloc& alloc,
1018 uint32_t numBindings) {
1019 return NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
1020}
1021
1022LexicalScope::ParserData* NewEmptyLexicalScopeData(FrontendContext* fc,
1023 LifoAlloc& alloc,
1024 uint32_t numBindings) {
1025 return NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
1026}
1027
1028FunctionScope::ParserData* NewEmptyFunctionScopeData(FrontendContext* fc,
1029 LifoAlloc& alloc,
1030 uint32_t numBindings) {
1031 return NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
1032}
1033
1034namespace detail {
1035
1036template <class SlotInfo>
1037static MOZ_ALWAYS_INLINEinline ParserBindingName* InitializeIndexedBindings(
1038 SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor) {
1039 return cursor;
1040}
1041
1042template <class SlotInfo, typename UnsignedInteger, typename... Step>
1043static MOZ_ALWAYS_INLINEinline ParserBindingName* InitializeIndexedBindings(
1044 SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor,
1045 UnsignedInteger SlotInfo::* field, const ParserBindingNameVector& bindings,
1046 Step&&... step) {
1047 slotInfo.*field =
1048 AssertedCast<UnsignedInteger>(PointerRangeSize(start, cursor));
1049
1050 ParserBindingName* newCursor =
1051 std::uninitialized_copy(bindings.begin(), bindings.end(), cursor);
1052
1053 return InitializeIndexedBindings(slotInfo, start, newCursor,
1054 std::forward<Step>(step)...);
1055}
1056
1057} // namespace detail
1058
1059// Initialize the trailing name bindings of |data|, then set |data->length| to
1060// the count of bindings added (which must equal |count|).
1061//
1062// First, |firstBindings| are added to the trailing names. Then any
1063// "steps" present are performed first to last. Each step is 1) a pointer to a
1064// member of |data| to be set to the current number of bindings added, and 2) a
1065// vector of |ParserBindingName|s to then copy into |data->trailingNames|.
1066// (Thus each |data| member field indicates where the corresponding vector's
1067// names start.)
1068template <class Data, typename... Step>
1069static MOZ_ALWAYS_INLINEinline void InitializeBindingData(
1070 Data* data, uint32_t count, const ParserBindingNameVector& firstBindings,
1071 Step&&... step) {
1072 MOZ_ASSERT(data->length == 0, "data shouldn't be filled yet")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(data->length == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(data->length == 0))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("data->length == 0"
" (" "data shouldn't be filled yet" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1072); AnnotateMozCrashReason("MOZ_ASSERT" "(" "data->length == 0"
") (" "data shouldn't be filled yet" ")"); do { *((volatile int
*)__null) = 1072; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1073
1074 ParserBindingName* start = GetScopeDataTrailingNamesPointer(data);
1075 ParserBindingName* cursor = std::uninitialized_copy(
1076 firstBindings.begin(), firstBindings.end(), start);
1077
1078#ifdef DEBUG1
1079 ParserBindingName* end =
1080#endif
1081 detail::InitializeIndexedBindings(data->slotInfo, start, cursor,
1082 std::forward<Step>(step)...);
1083
1084 MOZ_ASSERT(PointerRangeSize(start, end) == count)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(PointerRangeSize(start, end) == count)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(PointerRangeSize(start, end) == count))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("PointerRangeSize(start, end) == count"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1084); AnnotateMozCrashReason("MOZ_ASSERT" "(" "PointerRangeSize(start, end) == count"
")"); do { *((volatile int*)__null) = 1084; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1085 data->length = count;
1086}
1087
1088static Maybe<GlobalScope::ParserData*> NewGlobalScopeData(
1089 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1090 ParseContext* pc) {
1091 ParserBindingNameVector vars(fc);
1092 ParserBindingNameVector lets(fc);
1093 ParserBindingNameVector consts(fc);
1094
1095 bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
1096 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1097 bool closedOver = allBindingsClosedOver || bi.closedOver();
1098
1099 switch (bi.kind()) {
1100 case BindingKind::Var: {
1101 bool isTopLevelFunction =
1102 bi.declarationKind() == DeclarationKind::BodyLevelFunction;
1103
1104 ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
1105 if (!vars.append(binding)) {
1106 return Nothing();
1107 }
1108 break;
1109 }
1110 case BindingKind::Let: {
1111 ParserBindingName binding(bi.name(), closedOver);
1112 if (!lets.append(binding)) {
1113 return Nothing();
1114 }
1115 break;
1116 }
1117 case BindingKind::Const: {
1118 ParserBindingName binding(bi.name(), closedOver);
1119 if (!consts.append(binding)) {
1120 return Nothing();
1121 }
1122 break;
1123 }
1124 default:
1125 MOZ_CRASH("Bad global scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "Bad global scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1125); AnnotateMozCrashReason("MOZ_CRASH(" "Bad global scope BindingKind"
")"); do { *((volatile int*)__null) = 1125; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1126 }
1127 }
1128
1129 GlobalScope::ParserData* bindings = nullptr;
1130 uint32_t numBindings = vars.length() + lets.length() + consts.length();
1131
1132 if (numBindings > 0) {
1133 bindings = NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
1134 if (!bindings) {
1135 return Nothing();
1136 }
1137
1138 // The ordering here is important. See comments in GlobalScope.
1139 InitializeBindingData(bindings, numBindings, vars,
1140 &ParserGlobalScopeSlotInfo::letStart, lets,
1141 &ParserGlobalScopeSlotInfo::constStart, consts);
1142 }
1143
1144 return Some(bindings);
1145}
1146
1147Maybe<GlobalScope::ParserData*> ParserBase::newGlobalScopeData(
1148 ParseContext::Scope& scope) {
1149 return NewGlobalScopeData(fc_, scope, stencilAlloc(), pc_);
1150}
1151
1152static Maybe<ModuleScope::ParserData*> NewModuleScopeData(
1153 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1154 ParseContext* pc) {
1155 ParserBindingNameVector imports(fc);
1156 ParserBindingNameVector vars(fc);
1157 ParserBindingNameVector lets(fc);
1158 ParserBindingNameVector consts(fc);
1159#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1160 ParserBindingNameVector usings(fc);
1161#endif
1162
1163 bool allBindingsClosedOver =
1164 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1165
1166 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1167 // Imports are indirect bindings and must not be given known slots.
1168 ParserBindingName binding(bi.name(),
1169 (allBindingsClosedOver || bi.closedOver()) &&
1170 bi.kind() != BindingKind::Import);
1171 switch (bi.kind()) {
1172 case BindingKind::Import:
1173 if (!imports.append(binding)) {
1174 return Nothing();
1175 }
1176 break;
1177 case BindingKind::Var:
1178 if (!vars.append(binding)) {
1179 return Nothing();
1180 }
1181 break;
1182 case BindingKind::Let:
1183 if (!lets.append(binding)) {
1184 return Nothing();
1185 }
1186 break;
1187 case BindingKind::Const:
1188 if (!consts.append(binding)) {
1189 return Nothing();
1190 }
1191 break;
1192#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1193 case BindingKind::Using:
1194 if (!usings.append(binding)) {
1195 return Nothing();
1196 }
1197 break;
1198#endif
1199 default:
1200 MOZ_CRASH("Bad module scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "Bad module scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1200); AnnotateMozCrashReason("MOZ_CRASH(" "Bad module scope BindingKind"
")"); do { *((volatile int*)__null) = 1200; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1201 }
1202 }
1203
1204 ModuleScope::ParserData* bindings = nullptr;
1205 uint32_t numBindings = imports.length() + vars.length() + lets.length() +
1206 consts.length()
1207#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1208 + usings.length()
1209#endif
1210 ;
1211
1212 if (numBindings > 0) {
1213 bindings = NewEmptyBindingData<ModuleScope>(fc, alloc, numBindings);
1214 if (!bindings) {
1215 return Nothing();
1216 }
1217
1218 // The ordering here is important. See comments in ModuleScope.
1219 InitializeBindingData(bindings, numBindings, imports,
1220 &ParserModuleScopeSlotInfo::varStart, vars,
1221 &ParserModuleScopeSlotInfo::letStart, lets,
1222 &ParserModuleScopeSlotInfo::constStart, consts
1223#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1224 ,
1225 &ParserModuleScopeSlotInfo::usingStart, usings
1226#endif
1227 );
1228 }
1229
1230 return Some(bindings);
1231}
1232
1233Maybe<ModuleScope::ParserData*> ParserBase::newModuleScopeData(
1234 ParseContext::Scope& scope) {
1235 return NewModuleScopeData(fc_, scope, stencilAlloc(), pc_);
1236}
1237
1238static Maybe<EvalScope::ParserData*> NewEvalScopeData(
1239 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1240 ParseContext* pc) {
1241 ParserBindingNameVector vars(fc);
1242
1243 // Treat all bindings as closed over in non-strict eval.
1244 bool allBindingsClosedOver =
1245 !pc->sc()->strict() || pc->sc()->allBindingsClosedOver();
1246 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1247 // Eval scopes only contain 'var' bindings.
1248 MOZ_ASSERT(bi.kind() == BindingKind::Var)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Var)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(bi.kind() == BindingKind::Var
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"bi.kind() == BindingKind::Var", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1248); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Var"
")"); do { *((volatile int*)__null) = 1248; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1249 bool isTopLevelFunction =
1250 bi.declarationKind() == DeclarationKind::BodyLevelFunction;
1251 bool closedOver = allBindingsClosedOver || bi.closedOver();
1252
1253 ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
1254 if (!vars.append(binding)) {
1255 return Nothing();
1256 }
1257 }
1258
1259 EvalScope::ParserData* bindings = nullptr;
1260 uint32_t numBindings = vars.length();
1261
1262 if (numBindings > 0) {
1263 bindings = NewEmptyBindingData<EvalScope>(fc, alloc, numBindings);
1264 if (!bindings) {
1265 return Nothing();
1266 }
1267
1268 InitializeBindingData(bindings, numBindings, vars);
1269 }
1270
1271 return Some(bindings);
1272}
1273
1274Maybe<EvalScope::ParserData*> ParserBase::newEvalScopeData(
1275 ParseContext::Scope& scope) {
1276 return NewEvalScopeData(fc_, scope, stencilAlloc(), pc_);
1277}
1278
1279static Maybe<FunctionScope::ParserData*> NewFunctionScopeData(
1280 FrontendContext* fc, ParseContext::Scope& scope, bool hasParameterExprs,
1281 LifoAlloc& alloc, ParseContext* pc) {
1282 ParserBindingNameVector positionalFormals(fc);
1283 ParserBindingNameVector formals(fc);
1284 ParserBindingNameVector vars(fc);
1285
1286 bool allBindingsClosedOver =
1287 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1288 bool argumentBindingsClosedOver =
1289 allBindingsClosedOver || pc->isGeneratorOrAsync();
1290 bool hasDuplicateParams = pc->functionBox()->hasDuplicateParameters;
1291
1292 // Positional parameter names must be added in order of appearance as they are
1293 // referenced using argument slots.
1294 for (size_t i = 0; i < pc->positionalFormalParameterNames().length(); i++) {
1295 TaggedParserAtomIndex name = pc->positionalFormalParameterNames()[i];
1296
1297 ParserBindingName bindName;
1298 if (name) {
1299 DeclaredNamePtr p = scope.lookupDeclaredName(name);
1300
1301 // Do not consider any positional formal parameters closed over if
1302 // there are parameter defaults. It is the binding in the defaults
1303 // scope that is closed over instead.
1304 bool closedOver =
1305 argumentBindingsClosedOver || (p && p->value()->closedOver());
1306
1307 // If the parameter name has duplicates, only the final parameter
1308 // name should be on the environment, as otherwise the environment
1309 // object would have multiple, same-named properties.
1310 if (hasDuplicateParams) {
1311 for (size_t j = pc->positionalFormalParameterNames().length() - 1;
1312 j > i; j--) {
1313 if (TaggedParserAtomIndex(pc->positionalFormalParameterNames()[j]) ==
1314 name) {
1315 closedOver = false;
1316 break;
1317 }
1318 }
1319 }
1320
1321 bindName = ParserBindingName(name, closedOver);
1322 }
1323
1324 if (!positionalFormals.append(bindName)) {
1325 return Nothing();
1326 }
1327 }
1328
1329 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1330 ParserBindingName binding(bi.name(),
1331 allBindingsClosedOver || bi.closedOver());
1332 switch (bi.kind()) {
1333 case BindingKind::FormalParameter:
1334 // Positional parameter names are already handled above.
1335 if (bi.declarationKind() == DeclarationKind::FormalParameter) {
1336 if (!formals.append(binding)) {
1337 return Nothing();
1338 }
1339 }
1340 break;
1341 case BindingKind::Var:
1342 // The only vars in the function scope when there are parameter
1343 // exprs, which induces a separate var environment, should be the
1344 // special bindings.
1345 MOZ_ASSERT_IF(hasParameterExprs,do { if (hasParameterExprs) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(FunctionScope::isSpecialName
(bi.name()))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(FunctionScope::isSpecialName(bi.name
())))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("FunctionScope::isSpecialName(bi.name())", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "FunctionScope::isSpecialName(bi.name())"
")"); do { *((volatile int*)__null) = 1346; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1346 FunctionScope::isSpecialName(bi.name()))do { if (hasParameterExprs) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(FunctionScope::isSpecialName
(bi.name()))>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(FunctionScope::isSpecialName(bi.name
())))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("FunctionScope::isSpecialName(bi.name())", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1346); AnnotateMozCrashReason("MOZ_ASSERT" "(" "FunctionScope::isSpecialName(bi.name())"
")"); do { *((volatile int*)__null) = 1346; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1347 if (!vars.append(binding)) {
1348 return Nothing();
1349 }
1350 break;
1351 case BindingKind::Let:
1352 case BindingKind::Const:
1353#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1354 case BindingKind::Using:
1355#endif
1356 break;
1357 default:
1358 MOZ_CRASH("bad function scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "bad function scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1358); AnnotateMozCrashReason("MOZ_CRASH(" "bad function scope BindingKind"
")"); do { *((volatile int*)__null) = 1358; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1359 break;
1360 }
1361 }
1362
1363 FunctionScope::ParserData* bindings = nullptr;
1364 uint32_t numBindings =
1365 positionalFormals.length() + formals.length() + vars.length();
1366
1367 if (numBindings > 0) {
1368 bindings = NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
1369 if (!bindings) {
1370 return Nothing();
1371 }
1372
1373 // The ordering here is important. See comments in FunctionScope.
1374 InitializeBindingData(
1375 bindings, numBindings, positionalFormals,
1376 &ParserFunctionScopeSlotInfo::nonPositionalFormalStart, formals,
1377 &ParserFunctionScopeSlotInfo::varStart, vars);
1378 }
1379
1380 return Some(bindings);
1381}
1382
1383// Compute if `NewFunctionScopeData` would return any binding list with any
1384// entry marked as closed-over. This is done without the need to allocate the
1385// binding list. If true, an EnvironmentObject will be needed at runtime.
1386bool FunctionScopeHasClosedOverBindings(ParseContext* pc) {
1387 bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver() ||
1388 pc->functionScope().tooBigToOptimize();
1389
1390 for (BindingIter bi = pc->functionScope().bindings(pc); bi; bi++) {
1391 switch (bi.kind()) {
1392 case BindingKind::FormalParameter:
1393 case BindingKind::Var:
1394 if (allBindingsClosedOver || bi.closedOver()) {
1395 return true;
1396 }
1397 break;
1398
1399 default:
1400 break;
1401 }
1402 }
1403
1404 return false;
1405}
1406
1407Maybe<FunctionScope::ParserData*> ParserBase::newFunctionScopeData(
1408 ParseContext::Scope& scope, bool hasParameterExprs) {
1409 return NewFunctionScopeData(fc_, scope, hasParameterExprs, stencilAlloc(),
1410 pc_);
1411}
1412
1413VarScope::ParserData* NewEmptyVarScopeData(FrontendContext* fc,
1414 LifoAlloc& alloc,
1415 uint32_t numBindings) {
1416 return NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
1417}
1418
1419static Maybe<VarScope::ParserData*> NewVarScopeData(FrontendContext* fc,
1420 ParseContext::Scope& scope,
1421 LifoAlloc& alloc,
1422 ParseContext* pc) {
1423 ParserBindingNameVector vars(fc);
1424
1425 bool allBindingsClosedOver =
1426 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1427
1428 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1429 if (bi.kind() == BindingKind::Var) {
1430 ParserBindingName binding(bi.name(),
1431 allBindingsClosedOver || bi.closedOver());
1432 if (!vars.append(binding)) {
1433 return Nothing();
1434 }
1435 } else {
1436 MOZ_ASSERT(bi.kind() == BindingKind::Let ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1437 bi.kind() == BindingKind::Constdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1438#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENTdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1439 || bi.kind() == BindingKind::Usingdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1440#endifdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1441 ,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1442 "bad var scope BindingKind")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const ifdef 1 || bi.kind() == BindingKind::Using endif))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1442); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Constifdef 1 || bi.kind() == BindingKind::Usingendif"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1442; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1443 }
1444 }
1445
1446 VarScope::ParserData* bindings = nullptr;
1447 uint32_t numBindings = vars.length();
1448
1449 if (numBindings > 0) {
1450 bindings = NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
1451 if (!bindings) {
1452 return Nothing();
1453 }
1454
1455 InitializeBindingData(bindings, numBindings, vars);
1456 }
1457
1458 return Some(bindings);
1459}
1460
1461// Compute if `NewVarScopeData` would return any binding list. This is done
1462// without allocate the binding list.
1463static bool VarScopeHasBindings(ParseContext* pc) {
1464 for (BindingIter bi = pc->varScope().bindings(pc); bi; bi++) {
1465 if (bi.kind() == BindingKind::Var) {
1466 return true;
1467 }
1468 }
1469
1470 return false;
1471}
1472
1473Maybe<VarScope::ParserData*> ParserBase::newVarScopeData(
1474 ParseContext::Scope& scope) {
1475 return NewVarScopeData(fc_, scope, stencilAlloc(), pc_);
1476}
1477
1478static Maybe<LexicalScope::ParserData*> NewLexicalScopeData(
1479 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1480 ParseContext* pc) {
1481 ParserBindingNameVector lets(fc);
1482 ParserBindingNameVector consts(fc);
1483#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1484 ParserBindingNameVector usings(fc);
1485#endif
1486
1487 bool allBindingsClosedOver =
1488 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1489
1490 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1491 ParserBindingName binding(bi.name(),
1492 allBindingsClosedOver || bi.closedOver());
1493 switch (bi.kind()) {
1494 case BindingKind::Let:
1495 if (!lets.append(binding)) {
1496 return Nothing();
1497 }
1498 break;
1499 case BindingKind::Const:
1500 if (!consts.append(binding)) {
1501 return Nothing();
1502 }
1503 break;
1504#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1505 case BindingKind::Using:
1506 if (!usings.append(binding)) {
1507 return Nothing();
1508 }
1509 break;
1510#endif
1511 case BindingKind::Var:
1512 case BindingKind::FormalParameter:
1513 break;
1514 default:
1515 MOZ_CRASH("Bad lexical scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "Bad lexical scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1515); AnnotateMozCrashReason("MOZ_CRASH(" "Bad lexical scope BindingKind"
")"); do { *((volatile int*)__null) = 1515; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1516 break;
1517 }
1518 }
1519
1520 LexicalScope::ParserData* bindings = nullptr;
1521 uint32_t numBindings = lets.length() + consts.length()
1522#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1523 + usings.length()
1524#endif
1525 ;
1526
1527 if (numBindings > 0) {
1528 bindings = NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
1529 if (!bindings) {
1530 return Nothing();
1531 }
1532
1533 // The ordering here is important. See comments in LexicalScope.
1534 InitializeBindingData(bindings, numBindings, lets,
1535 &ParserLexicalScopeSlotInfo::constStart, consts
1536#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
1537 ,
1538 &ParserLexicalScopeSlotInfo::usingStart, usings
1539#endif
1540 );
1541 }
1542
1543 return Some(bindings);
1544}
1545
1546// Compute if `NewLexicalScopeData` would return any binding list with any entry
1547// marked as closed-over. This is done without the need to allocate the binding
1548// list. If true, an EnvironmentObject will be needed at runtime.
1549bool LexicalScopeHasClosedOverBindings(ParseContext* pc,
1550 ParseContext::Scope& scope) {
1551 bool allBindingsClosedOver =
1552 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1553
1554 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1555 switch (bi.kind()) {
1556 case BindingKind::Let:
1557 case BindingKind::Const:
1558 if (allBindingsClosedOver || bi.closedOver()) {
1559 return true;
1560 }
1561 break;
1562
1563 default:
1564 break;
1565 }
1566 }
1567
1568 return false;
1569}
1570
1571Maybe<LexicalScope::ParserData*> ParserBase::newLexicalScopeData(
1572 ParseContext::Scope& scope) {
1573 return NewLexicalScopeData(fc_, scope, stencilAlloc(), pc_);
1574}
1575
1576static Maybe<ClassBodyScope::ParserData*> NewClassBodyScopeData(
1577 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1578 ParseContext* pc) {
1579 ParserBindingNameVector privateBrand(fc);
1580 ParserBindingNameVector synthetics(fc);
1581 ParserBindingNameVector privateMethods(fc);
1582
1583 bool allBindingsClosedOver =
1584 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
5
Assuming the condition is true
1585
1586 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1587 ParserBindingName binding(bi.name(),
1588 allBindingsClosedOver || bi.closedOver());
1589 switch (bi.kind()) {
1590 case BindingKind::Synthetic:
1591 if (bi.name() ==
1592 TaggedParserAtomIndex::WellKnown::dot_privateBrand_()) {
1593 MOZ_ASSERT(privateBrand.empty())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(privateBrand.empty())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(privateBrand.empty()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("privateBrand.empty()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1593); AnnotateMozCrashReason("MOZ_ASSERT" "(" "privateBrand.empty()"
")"); do { *((volatile int*)__null) = 1593; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1594 if (!privateBrand.append(binding)) {
1595 return Nothing();
1596 }
1597 } else {
1598 if (!synthetics.append(binding)) {
1599 return Nothing();
1600 }
1601 }
1602 break;
1603
1604 case BindingKind::PrivateMethod:
1605 if (!privateMethods.append(binding)) {
1606 return Nothing();
1607 }
1608 break;
1609
1610 default:
1611 MOZ_CRASH("bad class body scope BindingKind")do { do { } while (false); MOZ_ReportCrash("" "bad class body scope BindingKind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1611); AnnotateMozCrashReason("MOZ_CRASH(" "bad class body scope BindingKind"
")"); do { *((volatile int*)__null) = 1611; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1612 break;
1613 }
1614 }
1615
1616 // We should have zero or one private brands.
1617 MOZ_ASSERT(privateBrand.length() == 0 || privateBrand.length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(privateBrand.length() == 0 || privateBrand.length() ==
1)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(privateBrand.length() == 0 || privateBrand.length() ==
1))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("privateBrand.length() == 0 || privateBrand.length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1617); AnnotateMozCrashReason("MOZ_ASSERT" "(" "privateBrand.length() == 0 || privateBrand.length() == 1"
")"); do { *((volatile int*)__null) = 1617; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6
Loop condition is false. Execution continues on line 1617
7
Assuming the condition is true
8
Taking false branch
9
Loop condition is false. Exiting loop
1618
1619 ClassBodyScope::ParserData* bindings = nullptr;
10
'bindings' initialized to a null pointer value
1620 uint32_t numBindings =
1621 privateBrand.length() + synthetics.length() + privateMethods.length();
1622
1623 if (numBindings > 0) {
11
Assuming 'numBindings' is <= 0
12
Taking false branch
1624 bindings = NewEmptyBindingData<ClassBodyScope>(fc, alloc, numBindings);
1625 if (!bindings) {
1626 return Nothing();
1627 }
1628 // To simplify initialization of the bindings, we concatenate the
1629 // synthetics+privateBrand vector such that the private brand is always the
1630 // first element, as ordering is important. See comments in ClassBodyScope.
1631 ParserBindingNameVector brandAndSynthetics(fc);
1632 if (!brandAndSynthetics.appendAll(privateBrand)) {
1633 return Nothing();
1634 }
1635 if (!brandAndSynthetics.appendAll(synthetics)) {
1636 return Nothing();
1637 }
1638
1639 // The ordering here is important. See comments in ClassBodyScope.
1640 InitializeBindingData(bindings, numBindings, brandAndSynthetics,
1641 &ParserClassBodyScopeSlotInfo::privateMethodStart,
1642 privateMethods);
1643 }
1644
1645 // `EmitterScope::lookupPrivate()` requires `.privateBrand` to be stored in a
1646 // predictable slot: the first slot available in the environment object,
1647 // `ClassBodyLexicalEnvironmentObject::privateBrandSlot()`. We assume that
1648 // if `.privateBrand` is first in the scope, it will be stored there.
1649 MOZ_ASSERT_IF(!privateBrand.empty(),do { if (!privateBrand.empty()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(GetScopeDataTrailingNames
(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex
::WellKnown::dot_privateBrand_()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
13
Assuming the condition is true
14
Taking true branch
15
Passing null pointer value via 1st parameter 'data'
16
Calling 'GetScopeDataTrailingNames<js::ParserScopeData<js::ClassBodyScope::SlotInfo>>'
1650 GetScopeDataTrailingNames(bindings)[0].name() ==do { if (!privateBrand.empty()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(GetScopeDataTrailingNames
(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex
::WellKnown::dot_privateBrand_()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1651 TaggedParserAtomIndex::WellKnown::dot_privateBrand_())do { if (!privateBrand.empty()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(GetScopeDataTrailingNames
(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex
::WellKnown::dot_privateBrand_()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1652
1653 return Some(bindings);
1654}
1655
1656Maybe<ClassBodyScope::ParserData*> ParserBase::newClassBodyScopeData(
1657 ParseContext::Scope& scope) {
1658 return NewClassBodyScopeData(fc_, scope, stencilAlloc(), pc_);
4
Calling 'NewClassBodyScopeData'
1659}
1660
1661template <>
1662SyntaxParseHandler::LexicalScopeNodeResult
1663PerHandlerParser<SyntaxParseHandler>::finishLexicalScope(
1664 ParseContext::Scope& scope, Node body, ScopeKind kind) {
1665 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1666 return errorResult();
1667 }
1668
1669 return handler_.newLexicalScope(body);
1670}
1671
1672template <>
1673FullParseHandler::LexicalScopeNodeResult
1674PerHandlerParser<FullParseHandler>::finishLexicalScope(
1675 ParseContext::Scope& scope, ParseNode* body, ScopeKind kind) {
1676 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1677 return errorResult();
1678 }
1679
1680 Maybe<LexicalScope::ParserData*> bindings = newLexicalScopeData(scope);
1681 if (!bindings) {
1682 return errorResult();
1683 }
1684
1685 return handler_.newLexicalScope(*bindings, body, kind);
1686}
1687
1688template <>
1689SyntaxParseHandler::ClassBodyScopeNodeResult
1690PerHandlerParser<SyntaxParseHandler>::finishClassBodyScope(
1691 ParseContext::Scope& scope, ListNodeType body) {
1692 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1693 return errorResult();
1694 }
1695
1696 return handler_.newClassBodyScope(body);
1697}
1698
1699template <>
1700FullParseHandler::ClassBodyScopeNodeResult
1701PerHandlerParser<FullParseHandler>::finishClassBodyScope(
1702 ParseContext::Scope& scope, ListNode* body) {
1703 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1
Assuming the condition is false
2
Taking false branch
1704 return errorResult();
1705 }
1706
1707 Maybe<ClassBodyScope::ParserData*> bindings = newClassBodyScopeData(scope);
3
Calling 'ParserBase::newClassBodyScopeData'
1708 if (!bindings) {
1709 return errorResult();
1710 }
1711
1712 return handler_.newClassBodyScope(*bindings, body);
1713}
1714
1715template <class ParseHandler>
1716bool PerHandlerParser<ParseHandler>::checkForUndefinedPrivateFields(
1717 EvalSharedContext* evalSc) {
1718 if (!this->compilationState_.isInitialStencil()) {
1719 // We're delazifying -- so we already checked private names during first
1720 // parse.
1721 return true;
1722 }
1723
1724 Vector<UnboundPrivateName, 8> unboundPrivateNames(fc_);
1725 if (!usedNames_.getUnboundPrivateNames(unboundPrivateNames)) {
1726 return false;
1727 }
1728
1729 // No unbound names, let's get out of here!
1730 if (unboundPrivateNames.empty()) {
1731 return true;
1732 }
1733
1734 // It is an early error if there's private name references unbound,
1735 // unless it's an eval, in which case we need to check the scope
1736 // chain.
1737 if (!evalSc) {
1738 // The unbound private names are sorted, so just grab the first one.
1739 UnboundPrivateName minimum = unboundPrivateNames[0];
1740 UniqueChars str = this->parserAtoms().toPrintableString(minimum.atom);
1741 if (!str) {
1742 ReportOutOfMemory(this->fc_);
1743 return false;
1744 }
1745
1746 errorAt(minimum.position.begin, JSMSG_MISSING_PRIVATE_DECL, str.get());
1747 return false;
1748 }
1749
1750 // It's important that the unbound private names are sorted, as we
1751 // want our errors to always be issued to the first textually.
1752 for (UnboundPrivateName unboundName : unboundPrivateNames) {
1753 // If the enclosingScope is non-syntactic, then we are in a
1754 // Debugger.Frame.prototype.eval call. In order to find the declared private
1755 // names, we must use the effective scope that was determined when creating
1756 // the scopeContext.
1757 if (!this->compilationState_.scopeContext
1758 .effectiveScopePrivateFieldCacheHas(unboundName.atom)) {
1759 UniqueChars str = this->parserAtoms().toPrintableString(unboundName.atom);
1760 if (!str) {
1761 ReportOutOfMemory(this->fc_);
1762 return false;
1763 }
1764 errorAt(unboundName.position.begin, JSMSG_MISSING_PRIVATE_DECL,
1765 str.get());
1766 return false;
1767 }
1768 }
1769
1770 return true;
1771}
1772
1773template <typename Unit>
1774FullParseHandler::LexicalScopeNodeResult
1775Parser<FullParseHandler, Unit>::evalBody(EvalSharedContext* evalsc) {
1776 SourceParseContext evalpc(this, evalsc, /* newDirectives = */ nullptr);
1777 if (!evalpc.init()) {
1778 return errorResult();
1779 }
1780
1781 ParseContext::VarScope varScope(this);
1782 if (!varScope.init(pc_)) {
1783 return errorResult();
1784 }
1785
1786 LexicalScopeNode* body;
1787 {
1788 // All evals have an implicit non-extensible lexical scope.
1789 ParseContext::Scope lexicalScope(this);
1790 if (!lexicalScope.init(pc_)) {
1791 return errorResult();
1792 }
1793
1794 ListNode* list;
1795 MOZ_TRY_VAR(list, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (list) = mozTryVarTempResult_
.unwrap(); } while (0)
;
1796
1797 if (!checkStatementsEOF()) {
1798 return errorResult();
1799 }
1800
1801 // Private names not lexically defined must trigger a syntax error.
1802 if (!checkForUndefinedPrivateFields(evalsc)) {
1803 return errorResult();
1804 }
1805
1806 MOZ_TRY_VAR(body, finishLexicalScope(lexicalScope, list))do { auto mozTryVarTempResult_ = (finishLexicalScope(lexicalScope
, list)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (body
) = mozTryVarTempResult_.unwrap(); } while (0)
;
1807 }
1808
1809#ifdef DEBUG1
1810 if (evalpc.superScopeNeedsHomeObject() &&
1811 !this->compilationState_.input.enclosingScope.isNull()) {
1812 // If superScopeNeedsHomeObject_ is set and we are an entry-point
1813 // ParseContext, then we must be emitting an eval script, and the
1814 // outer function must already be marked as needing a home object
1815 // since it contains an eval.
1816 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1819); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1819; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1817 this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1819); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1819; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1818 "Eval must have found an enclosing function box scope that "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1819); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1819; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1819 "allows super.property")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
" (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1819); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1819; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
1820 }
1821#endif
1822
1823 if (!CheckParseTree(this->fc_, alloc_, body)) {
1824 return errorResult();
1825 }
1826
1827 ParseNode* node = body;
1828 // Don't constant-fold inside "use asm" code, as this could create a parse
1829 // tree that doesn't type-check as asm.js.
1830 if (!pc_->useAsmOrInsideUseAsm()) {
1831 if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
1832 &handler_)) {
1833 return errorResult();
1834 }
1835 }
1836 body = handler_.asLexicalScopeNode(node);
1837
1838 if (!this->setSourceMapInfo()) {
1839 return errorResult();
1840 }
1841
1842 if (pc_->sc()->strict()) {
1843 if (!propagateFreeNamesAndMarkClosedOverBindings(varScope)) {
1844 return errorResult();
1845 }
1846 } else {
1847 // For non-strict eval scripts, since all bindings are automatically
1848 // considered closed over, we don't need to call propagateFreeNames-
1849 // AndMarkClosedOverBindings. However, Annex B.3.3 functions still need to
1850 // be marked.
1851 if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
1852 return errorResult();
1853 }
1854 }
1855
1856 Maybe<EvalScope::ParserData*> bindings = newEvalScopeData(pc_->varScope());
1857 if (!bindings) {
1858 return errorResult();
1859 }
1860 evalsc->bindings = *bindings;
1861
1862 return body;
1863}
1864
1865template <typename Unit>
1866FullParseHandler::ListNodeResult Parser<FullParseHandler, Unit>::globalBody(
1867 GlobalSharedContext* globalsc) {
1868 SourceParseContext globalpc(this, globalsc, /* newDirectives = */ nullptr);
1869 if (!globalpc.init()) {
1870 return errorResult();
1871 }
1872
1873 ParseContext::VarScope varScope(this);
1874 if (!varScope.init(pc_)) {
1875 return errorResult();
1876 }
1877
1878 ListNode* body;
1879 MOZ_TRY_VAR(body, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
1880
1881 if (!checkStatementsEOF()) {
1882 return errorResult();
1883 }
1884
1885 if (!CheckParseTree(this->fc_, alloc_, body)) {
1886 return errorResult();
1887 }
1888
1889 if (!checkForUndefinedPrivateFields()) {
1890 return errorResult();
1891 }
1892
1893 ParseNode* node = body;
1894 // Don't constant-fold inside "use asm" code, as this could create a parse
1895 // tree that doesn't type-check as asm.js.
1896 if (!pc_->useAsmOrInsideUseAsm()) {
1897 if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
1898 &handler_)) {
1899 return errorResult();
1900 }
1901 }
1902 body = &node->as<ListNode>();
1903
1904 if (!this->setSourceMapInfo()) {
1905 return errorResult();
1906 }
1907
1908 // For global scripts, whether bindings are closed over or not doesn't
1909 // matter, so no need to call propagateFreeNamesAndMarkClosedOver-
1910 // Bindings. However, Annex B.3.3 functions still need to be marked.
1911 if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
1912 return errorResult();
1913 }
1914
1915 Maybe<GlobalScope::ParserData*> bindings =
1916 newGlobalScopeData(pc_->varScope());
1917 if (!bindings) {
1918 return errorResult();
1919 }
1920 globalsc->bindings = *bindings;
1921
1922 return body;
1923}
1924
1925template <typename Unit>
1926FullParseHandler::ModuleNodeResult Parser<FullParseHandler, Unit>::moduleBody(
1927 ModuleSharedContext* modulesc) {
1928 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1928); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 1928; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1929
1930 this->compilationState_.moduleMetadata =
1931 fc_->getAllocator()->template new_<StencilModuleMetadata>();
1932 if (!this->compilationState_.moduleMetadata) {
1933 return errorResult();
1934 }
1935
1936 SourceParseContext modulepc(this, modulesc, nullptr);
1937 if (!modulepc.init()) {
1938 return errorResult();
1939 }
1940
1941 ParseContext::VarScope varScope(this);
1942 if (!varScope.init(pc_)) {
1943 return errorResult();
1944 }
1945
1946 ModuleNodeType moduleNode;
1947 MOZ_TRY_VAR(moduleNode, handler_.newModule(pos()))do { auto mozTryVarTempResult_ = (handler_.newModule(pos()));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (moduleNode)
= mozTryVarTempResult_.unwrap(); } while (0)
;
1948
1949 AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(
1950 this, AwaitIsModuleKeyword);
1951 ListNode* stmtList;
1952 MOZ_TRY_VAR(stmtList, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (stmtList) =
mozTryVarTempResult_.unwrap(); } while (0)
;
1953
1954 MOZ_ASSERT(stmtList->isKind(ParseNodeKind::StatementList))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(stmtList->isKind(ParseNodeKind::StatementList))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(stmtList->isKind(ParseNodeKind::StatementList))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("stmtList->isKind(ParseNodeKind::StatementList)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1954); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stmtList->isKind(ParseNodeKind::StatementList)"
")"); do { *((volatile int*)__null) = 1954; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1955 moduleNode->setBody(&stmtList->template as<ListNode>());
1956
1957 if (pc_->isAsync()) {
1958 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_generator_())) {
1959 return errorResult();
1960 }
1961
1962 if (!pc_->declareTopLevelDotGeneratorName()) {
1963 return errorResult();
1964 }
1965 }
1966
1967 TokenKind tt;
1968 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
1969 return errorResult();
1970 }
1971 if (tt != TokenKind::Eof) {
1972 error(JSMSG_GARBAGE_AFTER_INPUT, "module", TokenKindToDesc(tt));
1973 return errorResult();
1974 }
1975
1976 // Set the module to async if an await keyword was found at the top level.
1977 if (pc_->isAsync()) {
1978 pc_->sc()->asModuleContext()->builder.noteAsync(
1979 *this->compilationState_.moduleMetadata);
1980 }
1981
1982 // Generate the Import/Export tables and store in CompilationState.
1983 if (!modulesc->builder.buildTables(*this->compilationState_.moduleMetadata)) {
1984 return errorResult();
1985 }
1986
1987 // Check exported local bindings exist and mark them as closed over.
1988 StencilModuleMetadata& moduleMetadata =
1989 *this->compilationState_.moduleMetadata;
1990 for (auto entry : moduleMetadata.localExportEntries) {
1991 DeclaredNamePtr p = modulepc.varScope().lookupDeclaredName(entry.localName);
1992 if (!p) {
1993 UniqueChars str = this->parserAtoms().toPrintableString(entry.localName);
1994 if (!str) {
1995 ReportOutOfMemory(this->fc_);
1996 return errorResult();
1997 }
1998
1999 errorNoOffset(JSMSG_MISSING_EXPORT, str.get());
2000 return errorResult();
2001 }
2002
2003 p->value()->setClosedOver();
2004 }
2005
2006 // Reserve an environment slot for a "*namespace*" psuedo-binding and mark as
2007 // closed-over. We do not know until module linking if this will be used.
2008 if (!noteDeclaredName(
2009 TaggedParserAtomIndex::WellKnown::star_namespace_star_(),
2010 DeclarationKind::Const, pos())) {
2011 return errorResult();
2012 }
2013 modulepc.varScope()
2014 .lookupDeclaredName(
2015 TaggedParserAtomIndex::WellKnown::star_namespace_star_())
2016 ->value()
2017 ->setClosedOver();
2018
2019 if (options().deoptimizeModuleGlobalVars) {
2020 for (BindingIter bi = modulepc.varScope().bindings(pc_); bi; bi++) {
2021 bi.setClosedOver();
2022 }
2023 }
2024
2025 if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
2026 return errorResult();
2027 }
2028
2029 ParseNode* node = stmtList;
2030 // Don't constant-fold inside "use asm" code, as this could create a parse
2031 // tree that doesn't type-check as asm.js.
2032 if (!pc_->useAsmOrInsideUseAsm()) {
2033 if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
2034 &handler_)) {
2035 return errorResult();
2036 }
2037 }
2038 stmtList = &node->as<ListNode>();
2039
2040 if (!this->setSourceMapInfo()) {
2041 return errorResult();
2042 }
2043
2044 // Private names not lexically defined must trigger a syntax error.
2045 if (!checkForUndefinedPrivateFields()) {
2046 return errorResult();
2047 }
2048
2049 if (!propagateFreeNamesAndMarkClosedOverBindings(modulepc.varScope())) {
2050 return errorResult();
2051 }
2052
2053 Maybe<ModuleScope::ParserData*> bindings =
2054 newModuleScopeData(modulepc.varScope());
2055 if (!bindings) {
2056 return errorResult();
2057 }
2058
2059 modulesc->bindings = *bindings;
2060 return moduleNode;
2061}
2062
2063template <typename Unit>
2064SyntaxParseHandler::ModuleNodeResult
2065Parser<SyntaxParseHandler, Unit>::moduleBody(ModuleSharedContext* modulesc) {
2066 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2066); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 2066; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
2067 return errorResult();
2068}
2069
2070template <class ParseHandler>
2071typename ParseHandler::NameNodeResult
2072PerHandlerParser<ParseHandler>::newInternalDotName(TaggedParserAtomIndex name) {
2073 NameNodeType nameNode;
2074 MOZ_TRY_VAR(nameNode, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nameNode) = mozTryVarTempResult_.unwrap()
; } while (0)
;
2075 if (!noteUsedName(name)) {
2076 return errorResult();
2077 }
2078 return nameNode;
2079}
2080
2081template <class ParseHandler>
2082typename ParseHandler::NameNodeResult
2083PerHandlerParser<ParseHandler>::newThisName() {
2084 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_this_());
2085}
2086
2087template <class ParseHandler>
2088typename ParseHandler::NameNodeResult
2089PerHandlerParser<ParseHandler>::newNewTargetName() {
2090 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_newTarget_());
2091}
2092
2093template <class ParseHandler>
2094typename ParseHandler::NameNodeResult
2095PerHandlerParser<ParseHandler>::newDotGeneratorName() {
2096 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_generator_());
2097}
2098
2099template <class ParseHandler>
2100bool PerHandlerParser<ParseHandler>::finishFunctionScopes(
2101 bool isStandaloneFunction) {
2102 FunctionBox* funbox = pc_->functionBox();
2103
2104 if (funbox->hasParameterExprs) {
2105 if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->functionScope())) {
2106 return false;
2107 }
2108
2109 // Functions with parameter expressions utilize the FunctionScope for vars
2110 // generated by sloppy-direct-evals, as well as arguments (which are
2111 // lexicals bindings). If the function body has var bindings (or has a
2112 // sloppy-direct-eval that might), then an extra VarScope must be created
2113 // for them.
2114 if (VarScopeHasBindings(pc_) ||
2115 funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings()) {
2116 funbox->setFunctionHasExtraBodyVarScope();
2117 }
2118 }
2119
2120 // See: JSFunction::needsCallObject()
2121 if (FunctionScopeHasClosedOverBindings(pc_) ||
2122 funbox->needsCallObjectRegardlessOfBindings()) {
2123 funbox->setNeedsFunctionEnvironmentObjects();
2124 }
2125
2126 if (funbox->isNamedLambda() && !isStandaloneFunction) {
2127 if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->namedLambdaScope())) {
2128 return false;
2129 }
2130
2131 // See: JSFunction::needsNamedLambdaEnvironment()
2132 if (LexicalScopeHasClosedOverBindings(pc_, pc_->namedLambdaScope())) {
2133 funbox->setNeedsFunctionEnvironmentObjects();
2134 }
2135 }
2136
2137 return true;
2138}
2139
2140template <>
2141bool PerHandlerParser<FullParseHandler>::finishFunction(
2142 bool isStandaloneFunction /* = false */) {
2143 if (!finishFunctionScopes(isStandaloneFunction)) {
2144 return false;
2145 }
2146
2147 FunctionBox* funbox = pc_->functionBox();
2148 ScriptStencil& script = funbox->functionStencil();
2149
2150 if (funbox->isInterpreted()) {
2151 // BCE will need to generate bytecode for this.
2152 funbox->emitBytecode = true;
2153 this->compilationState_.nonLazyFunctionCount++;
2154 }
2155
2156 bool hasParameterExprs = funbox->hasParameterExprs;
2157
2158 if (hasParameterExprs) {
2159 Maybe<VarScope::ParserData*> bindings = newVarScopeData(pc_->varScope());
2160 if (!bindings) {
2161 return false;
2162 }
2163 funbox->setExtraVarScopeBindings(*bindings);
2164
2165 MOZ_ASSERT(bool(*bindings) == VarScopeHasBindings(pc_))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bool(*bindings) == VarScopeHasBindings(pc_))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(bool(*bindings) == VarScopeHasBindings(pc_)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("bool(*bindings) == VarScopeHasBindings(pc_)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2165); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == VarScopeHasBindings(pc_)"
")"); do { *((volatile int*)__null) = 2165; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2166 MOZ_ASSERT_IF(!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings(),do { if (!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings
()) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(bool(*bindings) == funbox->functionHasExtraBodyVarScope
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bool(*bindings) == funbox->functionHasExtraBodyVarScope
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2167); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
")"); do { *((volatile int*)__null) = 2167; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2167 bool(*bindings) == funbox->functionHasExtraBodyVarScope())do { if (!funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings
()) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(bool(*bindings) == funbox->functionHasExtraBodyVarScope
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bool(*bindings) == funbox->functionHasExtraBodyVarScope
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2167); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
")"); do { *((volatile int*)__null) = 2167; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2168 }
2169
2170 {
2171 Maybe<FunctionScope::ParserData*> bindings =
2172 newFunctionScopeData(pc_->functionScope(), hasParameterExprs);
2173 if (!bindings) {
2174 return false;
2175 }
2176 funbox->setFunctionScopeBindings(*bindings);
2177 }
2178
2179 if (funbox->isNamedLambda() && !isStandaloneFunction) {
2180 Maybe<LexicalScope::ParserData*> bindings =
2181 newLexicalScopeData(pc_->namedLambdaScope());
2182 if (!bindings) {
2183 return false;
2184 }
2185 funbox->setNamedLambdaBindings(*bindings);
2186 }
2187
2188 funbox->finishScriptFlags();
2189 funbox->copyFunctionFields(script);
2190
2191 if (this->compilationState_.isInitialStencil()) {
2192 ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
2193 funbox->copyFunctionExtraFields(scriptExtra);
2194 funbox->copyScriptExtraFields(scriptExtra);
2195 }
2196
2197 return true;
2198}
2199
2200template <>
2201bool PerHandlerParser<SyntaxParseHandler>::finishFunction(
2202 bool isStandaloneFunction /* = false */) {
2203 // The BaseScript for a lazily parsed function needs to know its set of
2204 // free variables and inner functions so that when it is fully parsed, we
2205 // can skip over any already syntax parsed inner functions and still
2206 // retain correct scope information.
2207
2208 if (!finishFunctionScopes(isStandaloneFunction)) {
2209 return false;
2210 }
2211
2212 FunctionBox* funbox = pc_->functionBox();
2213 ScriptStencil& script = funbox->functionStencil();
2214
2215 funbox->finishScriptFlags();
2216 funbox->copyFunctionFields(script);
2217
2218 ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
2219 funbox->copyFunctionExtraFields(scriptExtra);
2220 funbox->copyScriptExtraFields(scriptExtra);
2221
2222 // Elide nullptr sentinels from end of binding list. These are inserted for
2223 // each scope regardless of if any bindings are actually closed over.
2224 {
2225 AtomVector& closedOver = pc_->closedOverBindingsForLazy();
2226 while (!closedOver.empty() && !closedOver.back()) {
2227 closedOver.popBack();
2228 }
2229 }
2230
2231 // Check if we will overflow the `ngcthings` field later.
2232 mozilla::CheckedUint32 ngcthings =
2233 mozilla::CheckedUint32(pc_->innerFunctionIndexesForLazy.length()) +
2234 mozilla::CheckedUint32(pc_->closedOverBindingsForLazy().length());
2235 if (!ngcthings.isValid()) {
2236 ReportAllocationOverflow(fc_);
2237 return false;
2238 }
2239
2240 // If there are no script-things, we can return early without allocating.
2241 if (ngcthings.value() == 0) {
2242 MOZ_ASSERT(!script.hasGCThings())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!script.hasGCThings())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!script.hasGCThings()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("!script.hasGCThings()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2242); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!script.hasGCThings()"
")"); do { *((volatile int*)__null) = 2242; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2243 return true;
2244 }
2245
2246 TaggedScriptThingIndex* cursor = nullptr;
2247 if (!this->compilationState_.allocateGCThingsUninitialized(
2248 fc_, funbox->index(), ngcthings.value(), &cursor)) {
2249 return false;
2250 }
2251
2252 // Copy inner-function and closed-over-binding info for the stencil. The order
2253 // is important here. We emit functions first, followed by the bindings info.
2254 // The bindings list uses nullptr as delimiter to separates the bindings per
2255 // scope.
2256 //
2257 // See: FullParseHandler::nextLazyInnerFunction(),
2258 // FullParseHandler::nextLazyClosedOverBinding()
2259 for (const ScriptIndex& index : pc_->innerFunctionIndexesForLazy) {
2260 void* raw = &(*cursor++);
2261 new (raw) TaggedScriptThingIndex(index);
2262 }
2263 for (auto binding : pc_->closedOverBindingsForLazy()) {
2264 void* raw = &(*cursor++);
2265 if (binding) {
2266 this->parserAtoms().markUsedByStencil(binding, ParserAtom::Atomize::Yes);
2267 new (raw) TaggedScriptThingIndex(binding);
2268 } else {
2269 new (raw) TaggedScriptThingIndex();
2270 }
2271 }
2272
2273 return true;
2274}
2275
2276static YieldHandling GetYieldHandling(GeneratorKind generatorKind) {
2277 if (generatorKind == GeneratorKind::NotGenerator) {
2278 return YieldIsName;
2279 }
2280 return YieldIsKeyword;
2281}
2282
2283static AwaitHandling GetAwaitHandling(FunctionAsyncKind asyncKind) {
2284 if (asyncKind == FunctionAsyncKind::SyncFunction) {
2285 return AwaitIsName;
2286 }
2287 return AwaitIsKeyword;
2288}
2289
2290static FunctionFlags InitialFunctionFlags(FunctionSyntaxKind kind,
2291 GeneratorKind generatorKind,
2292 FunctionAsyncKind asyncKind,
2293 bool isSelfHosting) {
2294 FunctionFlags flags = {};
2295
2296 switch (kind) {
2297 case FunctionSyntaxKind::Expression:
2298 flags = (generatorKind == GeneratorKind::NotGenerator &&
2299 asyncKind == FunctionAsyncKind::SyncFunction
2300 ? FunctionFlags::INTERPRETED_LAMBDA
2301 : FunctionFlags::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC);
2302 break;
2303 case FunctionSyntaxKind::Arrow:
2304 flags = FunctionFlags::INTERPRETED_LAMBDA_ARROW;
2305 break;
2306 case FunctionSyntaxKind::Method:
2307 case FunctionSyntaxKind::FieldInitializer:
2308 case FunctionSyntaxKind::StaticClassBlock:
2309 flags = FunctionFlags::INTERPRETED_METHOD;
2310 break;
2311 case FunctionSyntaxKind::ClassConstructor:
2312 case FunctionSyntaxKind::DerivedClassConstructor:
2313 flags = FunctionFlags::INTERPRETED_CLASS_CTOR;
2314 break;
2315 case FunctionSyntaxKind::Getter:
2316 flags = FunctionFlags::INTERPRETED_GETTER;
2317 break;
2318 case FunctionSyntaxKind::Setter:
2319 flags = FunctionFlags::INTERPRETED_SETTER;
2320 break;
2321 default:
2322 MOZ_ASSERT(kind == FunctionSyntaxKind::Statement)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == FunctionSyntaxKind::Statement)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(kind == FunctionSyntaxKind::Statement))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("kind == FunctionSyntaxKind::Statement"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2322); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == FunctionSyntaxKind::Statement"
")"); do { *((volatile int*)__null) = 2322; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2323 flags = (generatorKind == GeneratorKind::NotGenerator &&
2324 asyncKind == FunctionAsyncKind::SyncFunction
2325 ? FunctionFlags::INTERPRETED_NORMAL
2326 : FunctionFlags::INTERPRETED_GENERATOR_OR_ASYNC);
2327 }
2328
2329 if (isSelfHosting) {
2330 flags.setIsSelfHostedBuiltin();
2331 }
2332
2333 return flags;
2334}
2335
2336template <typename Unit>
2337FullParseHandler::FunctionNodeResult
2338Parser<FullParseHandler, Unit>::standaloneFunction(
2339 const Maybe<uint32_t>& parameterListEnd, FunctionSyntaxKind syntaxKind,
2340 GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
2341 Directives inheritedDirectives, Directives* newDirectives) {
2342 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2342); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 2342; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2343 // Skip prelude.
2344 TokenKind tt;
2345 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2346 return errorResult();
2347 }
2348 if (asyncKind == FunctionAsyncKind::AsyncFunction) {
2349 MOZ_ASSERT(tt == TokenKind::Async)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::Async)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::Async))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("tt == TokenKind::Async"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2349); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Async"
")"); do { *((volatile int*)__null) = 2349; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2350 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2351 return errorResult();
2352 }
2353 }
2354 MOZ_ASSERT(tt == TokenKind::Function)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::Function)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::Function)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("tt == TokenKind::Function"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2354); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Function"
")"); do { *((volatile int*)__null) = 2354; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2355
2356 if (!tokenStream.getToken(&tt)) {
2357 return errorResult();
2358 }
2359 if (generatorKind == GeneratorKind::Generator) {
2360 MOZ_ASSERT(tt == TokenKind::Mul)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::Mul)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::Mul))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("tt == TokenKind::Mul"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2360); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Mul"
")"); do { *((volatile int*)__null) = 2360; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2361 if (!tokenStream.getToken(&tt)) {
2362 return errorResult();
2363 }
2364 }
2365
2366 // Skip function name, if present.
2367 TaggedParserAtomIndex explicitName;
2368 if (TokenKindIsPossibleIdentifierName(tt)) {
2369 explicitName = anyChars.currentName();
2370 } else {
2371 anyChars.ungetToken();
2372 }
2373
2374 FunctionNodeType funNode;
2375 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
2376
2377 ParamsBodyNodeType argsbody;
2378 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(pos()))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(pos(
))); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
2379 funNode->setBody(argsbody);
2380
2381 bool isSelfHosting = options().selfHostingMode;
2382 FunctionFlags flags =
2383 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
2384 FunctionBox* funbox =
2385 newFunctionBox(funNode, explicitName, flags, /* toStringStart = */ 0,
2386 inheritedDirectives, generatorKind, asyncKind);
2387 if (!funbox) {
2388 return errorResult();
2389 }
2390
2391 // Function is not syntactically part of another script.
2392 MOZ_ASSERT(funbox->index() == CompilationStencil::TopLevelIndex)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->index() == CompilationStencil::TopLevelIndex
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(funbox->index() == CompilationStencil::TopLevelIndex
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"funbox->index() == CompilationStencil::TopLevelIndex", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2392); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->index() == CompilationStencil::TopLevelIndex"
")"); do { *((volatile int*)__null) = 2392; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2393
2394 funbox->initStandalone(this->compilationState_.scopeContext, syntaxKind);
2395
2396 SourceParseContext funpc(this, funbox, newDirectives);
2397 if (!funpc.init()) {
2398 return errorResult();
2399 }
2400
2401 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
2402 AwaitHandling awaitHandling = GetAwaitHandling(asyncKind);
2403 AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(this,
2404 awaitHandling);
2405 if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
2406 syntaxKind, parameterListEnd,
2407 /* isStandaloneFunction = */ true)) {
2408 return errorResult();
2409 }
2410
2411 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2412 return errorResult();
2413 }
2414 if (tt != TokenKind::Eof) {
2415 error(JSMSG_GARBAGE_AFTER_INPUT, "function body", TokenKindToDesc(tt));
2416 return errorResult();
2417 }
2418
2419 if (!CheckParseTree(this->fc_, alloc_, funNode)) {
2420 return errorResult();
2421 }
2422
2423 ParseNode* node = funNode;
2424 // Don't constant-fold inside "use asm" code, as this could create a parse
2425 // tree that doesn't type-check as asm.js.
2426 if (!pc_->useAsmOrInsideUseAsm()) {
2427 if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
2428 &handler_)) {
2429 return errorResult();
2430 }
2431 }
2432 funNode = &node->as<FunctionNode>();
2433
2434 if (!checkForUndefinedPrivateFields(nullptr)) {
2435 return errorResult();
2436 }
2437
2438 if (!this->setSourceMapInfo()) {
2439 return errorResult();
2440 }
2441
2442 return funNode;
2443}
2444
2445template <class ParseHandler, typename Unit>
2446typename ParseHandler::LexicalScopeNodeResult
2447GeneralParser<ParseHandler, Unit>::functionBody(InHandling inHandling,
2448 YieldHandling yieldHandling,
2449 FunctionSyntaxKind kind,
2450 FunctionBodyType type) {
2451 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2451); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 2451; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2452
2453#ifdef DEBUG1
2454 uint32_t startYieldOffset = pc_->lastYieldOffset;
2455#endif
2456
2457 Node body;
2458 if (type == StatementListBody) {
2459 bool inheritedStrict = pc_->sc()->strict();
2460 MOZ_TRY_VAR(body, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
2461
2462 // When we transitioned from non-strict to strict mode, we need to
2463 // validate that all parameter names are valid strict mode names.
2464 if (!inheritedStrict && pc_->sc()->strict()) {
2465 MOZ_ASSERT(pc_->sc()->hasExplicitUseStrict(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2467; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2466 "strict mode should only change when a 'use strict' directive "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2467; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2467 "is present")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2467); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2467; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
2468 if (!hasValidSimpleStrictParameterNames()) {
2469 // Request that this function be reparsed as strict to report
2470 // the invalid parameter name at the correct source location.
2471 pc_->newDirectives->setStrict();
2472 return errorResult();
2473 }
2474 }
2475 } else {
2476 MOZ_ASSERT(type == ExpressionBody)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(type == ExpressionBody)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(type == ExpressionBody))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("type == ExpressionBody"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2476); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == ExpressionBody"
")"); do { *((volatile int*)__null) = 2476; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2477
2478 // Async functions are implemented as generators, and generators are
2479 // assumed to be statement lists, to prepend initial `yield`.
2480 ListNodeType stmtList = null();
2481 if (pc_->isAsync()) {
2482 MOZ_TRY_VAR(stmtList, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
2483 }
2484
2485 Node kid;
2486 MOZ_TRY_VAR(kid,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
2487 assignExpr(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
2488
2489 MOZ_TRY_VAR(body, handler_.newExpressionBody(kid))do { auto mozTryVarTempResult_ = (handler_.newExpressionBody(
kid)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr())
, 0))) { return mozTryVarTempResult_.propagateErr(); } (body)
= mozTryVarTempResult_.unwrap(); } while (0)
;
2490
2491 if (pc_->isAsync()) {
2492 handler_.addStatementToList(stmtList, body);
2493 body = stmtList;
2494 }
2495 }
2496
2497 MOZ_ASSERT_IF(!pc_->isGenerator() && !pc_->isAsync(),do { if (!pc_->isGenerator() && !pc_->isAsync()
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(pc_->lastYieldOffset == startYieldOffset)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->lastYieldOffset == startYieldOffset))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("pc_->lastYieldOffset == startYieldOffset"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2498); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->lastYieldOffset == startYieldOffset"
")"); do { *((volatile int*)__null) = 2498; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2498 pc_->lastYieldOffset == startYieldOffset)do { if (!pc_->isGenerator() && !pc_->isAsync()
) { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(pc_->lastYieldOffset == startYieldOffset)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->lastYieldOffset == startYieldOffset))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("pc_->lastYieldOffset == startYieldOffset"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2498); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->lastYieldOffset == startYieldOffset"
")"); do { *((volatile int*)__null) = 2498; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2499 MOZ_ASSERT_IF(pc_->isGenerator(), kind != FunctionSyntaxKind::Arrow)do { if (pc_->isGenerator()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(kind != FunctionSyntaxKind
::Arrow)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind != FunctionSyntaxKind::Arrow))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("kind != FunctionSyntaxKind::Arrow"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind != FunctionSyntaxKind::Arrow"
")"); do { *((volatile int*)__null) = 2499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2500 MOZ_ASSERT_IF(pc_->isGenerator(), type == StatementListBody)do { if (pc_->isGenerator()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(type == StatementListBody
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == StatementListBody))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("type == StatementListBody", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2500); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == StatementListBody"
")"); do { *((volatile int*)__null) = 2500; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2501
2502 if (pc_->needsDotGeneratorName()) {
2503 MOZ_ASSERT_IF(!pc_->isAsync(), type == StatementListBody)do { if (!pc_->isAsync()) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(type == StatementListBody
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(type == StatementListBody))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("type == StatementListBody", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2503); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == StatementListBody"
")"); do { *((volatile int*)__null) = 2503; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2504 if (!pc_->declareDotGeneratorName()) {
2505 return errorResult();
2506 }
2507 if (pc_->isGenerator()) {
2508 NameNodeType generator;
2509 MOZ_TRY_VAR(generator, newDotGeneratorName())do { auto mozTryVarTempResult_ = (newDotGeneratorName()); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (generator) = mozTryVarTempResult_
.unwrap(); } while (0)
;
2510 if (!handler_.prependInitialYield(handler_.asListNode(body), generator)) {
2511 return errorResult();
2512 }
2513 }
2514 }
2515
2516 if (pc_->numberOfArgumentsNames > 0 || kind == FunctionSyntaxKind::Arrow) {
2517 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2517); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 2517; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2518 pc_->sc()->setIneligibleForArgumentsLength();
2519 }
2520
2521 // Declare the 'arguments', 'this', and 'new.target' bindings if necessary
2522 // before finishing up the scope so these special bindings get marked as
2523 // closed over if necessary. Arrow functions don't have these bindings.
2524 if (kind != FunctionSyntaxKind::Arrow) {
2525 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
2526 if (!pc_->declareFunctionArgumentsObject(usedNames_,
2527 canSkipLazyClosedOverBindings)) {
2528 return errorResult();
2529 }
2530 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
2531 return errorResult();
2532 }
2533 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
2534 return errorResult();
2535 }
2536 }
2537
2538 return finishLexicalScope(pc_->varScope(), body, ScopeKind::FunctionLexical);
2539}
2540
2541template <class ParseHandler, typename Unit>
2542bool GeneralParser<ParseHandler, Unit>::matchOrInsertSemicolon(
2543 Modifier modifier /* = TokenStream::SlashIsRegExp */) {
2544 TokenKind tt = TokenKind::Eof;
2545 if (!tokenStream.peekTokenSameLine(&tt, modifier)) {
2546 return false;
2547 }
2548 if (tt != TokenKind::Eof && tt != TokenKind::Eol && tt != TokenKind::Semi &&
2549 tt != TokenKind::RightCurly) {
2550 /*
2551 * When current token is `await` and it's outside of async function,
2552 * it's possibly intended to be an await expression.
2553 *
2554 * await f();
2555 * ^
2556 * |
2557 * tried to insert semicolon here
2558 *
2559 * Detect this situation and throw an understandable error. Otherwise
2560 * we'd throw a confusing "unexpected token: (unexpected token)" error.
2561 */
2562 if (!pc_->isAsync() && anyChars.currentToken().type == TokenKind::Await) {
2563 error(JSMSG_AWAIT_OUTSIDE_ASYNC_OR_MODULE);
2564 return false;
2565 }
2566 if (!yieldExpressionsSupported() &&
2567 anyChars.currentToken().type == TokenKind::Yield) {
2568 error(JSMSG_YIELD_OUTSIDE_GENERATOR);
2569 return false;
2570 }
2571
2572#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
2573 if (options().explicitResourceManagement() &&
2574 !this->pc_->isUsingSyntaxAllowed() &&
2575 anyChars.currentToken().type == TokenKind::Using) {
2576 error(JSMSG_USING_OUTSIDE_BLOCK_OR_MODULE);
2577 return false;
2578 }
2579#endif
2580
2581 /* Advance the scanner for proper error location reporting. */
2582 tokenStream.consumeKnownToken(tt, modifier);
2583 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(tt));
2584 return false;
2585 }
2586 bool matched;
2587 return tokenStream.matchToken(&matched, TokenKind::Semi, modifier);
2588}
2589
2590bool ParserBase::leaveInnerFunction(ParseContext* outerpc) {
2591 MOZ_ASSERT(pc_ != outerpc)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_ != outerpc)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_ != outerpc))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("pc_ != outerpc"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2591); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_ != outerpc"
")"); do { *((volatile int*)__null) = 2591; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2592
2593 MOZ_ASSERT_IF(outerpc->isFunctionBox(),do { if (outerpc->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(outerpc->functionBox
()->index() < pc_->functionBox()->index())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(outerpc->functionBox()->index() < pc_->functionBox
()->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("outerpc->functionBox()->index() < pc_->functionBox()->index()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2594); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outerpc->functionBox()->index() < pc_->functionBox()->index()"
")"); do { *((volatile int*)__null) = 2594; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2594 outerpc->functionBox()->index() < pc_->functionBox()->index())do { if (outerpc->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(outerpc->functionBox
()->index() < pc_->functionBox()->index())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(outerpc->functionBox()->index() < pc_->functionBox
()->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("outerpc->functionBox()->index() < pc_->functionBox()->index()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2594); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outerpc->functionBox()->index() < pc_->functionBox()->index()"
")"); do { *((volatile int*)__null) = 2594; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2595
2596 // If the current function allows super.property but cannot have a home
2597 // object, i.e., it is an arrow function, we need to propagate the flag to
2598 // the outer ParseContext.
2599 if (pc_->superScopeNeedsHomeObject()) {
2600 if (!pc_->isArrowFunction()) {
2601 MOZ_ASSERT(pc_->functionBox()->needsHomeObject())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->functionBox()->needsHomeObject())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->functionBox()->needsHomeObject()))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("pc_->functionBox()->needsHomeObject()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2601); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->needsHomeObject()"
")"); do { *((volatile int*)__null) = 2601; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2602 } else {
2603 outerpc->setSuperScopeNeedsHomeObject();
2604 }
2605 }
2606
2607 // Lazy functions inner to another lazy function need to be remembered by
2608 // the inner function so that if the outer function is eventually parsed
2609 // we do not need any further parsing or processing of the inner function.
2610 //
2611 // Append the inner function index here unconditionally; the vector is only
2612 // used if the Parser using outerpc is a syntax parsing. See
2613 // GeneralParser<SyntaxParseHandler>::finishFunction.
2614 if (!outerpc->innerFunctionIndexesForLazy.append(
2615 pc_->functionBox()->index())) {
2616 return false;
2617 }
2618
2619 PropagateTransitiveParseFlags(pc_->functionBox(), outerpc->sc());
2620
2621 return true;
2622}
2623
2624TaggedParserAtomIndex ParserBase::prefixAccessorName(
2625 PropertyType propType, TaggedParserAtomIndex propAtom) {
2626 StringBuilder prefixed(fc_);
2627 if (propType == PropertyType::Setter) {
2628 if (!prefixed.append("set ")) {
2629 return TaggedParserAtomIndex::null();
2630 }
2631 } else {
2632 if (!prefixed.append("get ")) {
2633 return TaggedParserAtomIndex::null();
2634 }
2635 }
2636 if (!prefixed.append(this->parserAtoms(), propAtom)) {
2637 return TaggedParserAtomIndex::null();
2638 }
2639 return prefixed.finishParserAtom(this->parserAtoms(), fc_);
2640}
2641
2642template <class ParseHandler, typename Unit>
2643void GeneralParser<ParseHandler, Unit>::setFunctionStartAtPosition(
2644 FunctionBox* funbox, TokenPos pos) const {
2645 uint32_t startLine;
2646 JS::LimitedColumnNumberOneOrigin startColumn;
2647 tokenStream.computeLineAndColumn(pos.begin, &startLine, &startColumn);
2648
2649 // NOTE: `Debugger::CallData::findScripts` relies on sourceStart and
2650 // lineno/column referring to the same location.
2651 funbox->setStart(pos.begin, startLine, startColumn);
2652}
2653
2654template <class ParseHandler, typename Unit>
2655void GeneralParser<ParseHandler, Unit>::setFunctionStartAtCurrentToken(
2656 FunctionBox* funbox) const {
2657 setFunctionStartAtPosition(funbox, anyChars.currentToken().pos);
2658}
2659
2660template <class ParseHandler, typename Unit>
2661bool GeneralParser<ParseHandler, Unit>::functionArguments(
2662 YieldHandling yieldHandling, FunctionSyntaxKind kind,
2663 FunctionNodeType funNode) {
2664 FunctionBox* funbox = pc_->functionBox();
2665
2666 // Modifier for the following tokens.
2667 // TokenStream::SlashIsDiv for the following cases:
2668 // async a => 1
2669 // ^
2670 //
2671 // (a) => 1
2672 // ^
2673 //
2674 // async (a) => 1
2675 // ^
2676 //
2677 // function f(a) {}
2678 // ^
2679 //
2680 // TokenStream::SlashIsRegExp for the following case:
2681 // a => 1
2682 // ^
2683 Modifier firstTokenModifier =
2684 kind != FunctionSyntaxKind::Arrow || funbox->isAsync()
2685 ? TokenStream::SlashIsDiv
2686 : TokenStream::SlashIsRegExp;
2687 TokenKind tt;
2688 if (!tokenStream.getToken(&tt, firstTokenModifier)) {
2689 return false;
2690 }
2691
2692 if (kind == FunctionSyntaxKind::Arrow && TokenKindIsPossibleIdentifier(tt)) {
2693 // Record the start of function source (for FunctionToString).
2694 setFunctionStartAtCurrentToken(funbox);
2695
2696 ParamsBodyNodeType argsbody;
2697 MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newParamsBody(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2698 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
2699
2700 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
2701 if (!name) {
2702 return false;
2703 }
2704
2705 constexpr bool disallowDuplicateParams = true;
2706 bool duplicatedParam = false;
2707 if (!notePositionalFormalParameter(funNode, name, pos().begin,
2708 disallowDuplicateParams,
2709 &duplicatedParam)) {
2710 return false;
2711 }
2712 MOZ_ASSERT(!duplicatedParam)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!duplicatedParam)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!duplicatedParam))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!duplicatedParam"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2712); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!duplicatedParam"
")"); do { *((volatile int*)__null) = 2712; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2713 MOZ_ASSERT(pc_->positionalFormalParameterNames().length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->positionalFormalParameterNames().length() ==
1)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->positionalFormalParameterNames().length() ==
1))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->positionalFormalParameterNames().length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2713); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->positionalFormalParameterNames().length() == 1"
")"); do { *((volatile int*)__null) = 2713; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2714
2715 funbox->setLength(1);
2716 funbox->setArgCount(1);
2717 return true;
2718 }
2719
2720 if (tt != TokenKind::LeftParen) {
2721 error(kind == FunctionSyntaxKind::Arrow ? JSMSG_BAD_ARROW_ARGS
2722 : JSMSG_PAREN_BEFORE_FORMAL);
2723 return false;
2724 }
2725
2726 // Record the start of function source (for FunctionToString).
2727 setFunctionStartAtCurrentToken(funbox);
2728
2729 ParamsBodyNodeType argsbody;
2730 MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newParamsBody(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2731 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
2732
2733 bool matched;
2734 if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
2735 TokenStream::SlashIsRegExp)) {
2736 return false;
2737 }
2738 if (!matched) {
2739 bool hasRest = false;
2740 bool hasDefault = false;
2741 bool duplicatedParam = false;
2742 bool disallowDuplicateParams =
2743 kind == FunctionSyntaxKind::Arrow ||
2744 kind == FunctionSyntaxKind::Method ||
2745 kind == FunctionSyntaxKind::FieldInitializer ||
2746 kind == FunctionSyntaxKind::ClassConstructor;
2747 AtomVector& positionalFormals = pc_->positionalFormalParameterNames();
2748
2749 if (kind == FunctionSyntaxKind::Getter) {
2750 error(JSMSG_ACCESSOR_WRONG_ARGS, "getter", "no", "s");
2751 return false;
2752 }
2753
2754 while (true) {
2755 if (hasRest) {
2756 error(JSMSG_PARAMETER_AFTER_REST);
2757 return false;
2758 }
2759
2760 TokenKind tt;
2761 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2762 return false;
2763 }
2764
2765 if (tt == TokenKind::TripleDot) {
2766 if (kind == FunctionSyntaxKind::Setter) {
2767 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2768 return false;
2769 }
2770
2771 disallowDuplicateParams = true;
2772 if (duplicatedParam) {
2773 // Has duplicated args before the rest parameter.
2774 error(JSMSG_BAD_DUP_ARGS);
2775 return false;
2776 }
2777
2778 hasRest = true;
2779 funbox->setHasRest();
2780
2781 if (!tokenStream.getToken(&tt)) {
2782 return false;
2783 }
2784
2785 if (!TokenKindIsPossibleIdentifier(tt) &&
2786 tt != TokenKind::LeftBracket && tt != TokenKind::LeftCurly) {
2787 error(JSMSG_NO_REST_NAME);
2788 return false;
2789 }
2790 }
2791
2792 switch (tt) {
2793 case TokenKind::LeftBracket:
2794 case TokenKind::LeftCurly: {
2795 disallowDuplicateParams = true;
2796 if (duplicatedParam) {
2797 // Has duplicated args before the destructuring parameter.
2798 error(JSMSG_BAD_DUP_ARGS);
2799 return false;
2800 }
2801
2802 funbox->hasDestructuringArgs = true;
2803
2804 Node destruct;
2805 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2806 destruct,do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2807 destructuringDeclarationWithoutYieldOrAwait(do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2808 DeclarationKind::FormalParameter, yieldHandling, tt),do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2809 false)do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
;
2810
2811 if (!noteDestructuredPositionalFormalParameter(funNode, destruct)) {
2812 return false;
2813 }
2814
2815 break;
2816 }
2817
2818 default: {
2819 if (!TokenKindIsPossibleIdentifier(tt)) {
2820 error(JSMSG_MISSING_FORMAL);
2821 return false;
2822 }
2823
2824 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
2825 if (!name) {
2826 return false;
2827 }
2828
2829 if (!notePositionalFormalParameter(funNode, name, pos().begin,
2830 disallowDuplicateParams,
2831 &duplicatedParam)) {
2832 return false;
2833 }
2834 if (duplicatedParam) {
2835 funbox->hasDuplicateParameters = true;
2836 }
2837
2838 break;
2839 }
2840 }
2841
2842 if (positionalFormals.length() >= ARGNO_LIMIT) {
2843 error(JSMSG_TOO_MANY_FUN_ARGS);
2844 return false;
2845 }
2846
2847 bool matched;
2848 if (!tokenStream.matchToken(&matched, TokenKind::Assign,
2849 TokenStream::SlashIsRegExp)) {
2850 return false;
2851 }
2852 if (matched) {
2853 if (hasRest) {
2854 error(JSMSG_REST_WITH_DEFAULT);
2855 return false;
2856 }
2857 disallowDuplicateParams = true;
2858 if (duplicatedParam) {
2859 error(JSMSG_BAD_DUP_ARGS);
2860 return false;
2861 }
2862
2863 if (!hasDefault) {
2864 hasDefault = true;
2865
2866 // The Function.length property is the number of formals
2867 // before the first default argument.
2868 funbox->setLength(positionalFormals.length() - 1);
2869 }
2870 funbox->hasParameterExprs = true;
2871
2872 Node def_expr;
2873 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (assignExprWithoutYieldOrAwait
(yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (def_expr) = parserTryVarTempResult_
.unwrap(); } while (0)
2874 def_expr, assignExprWithoutYieldOrAwait(yieldHandling), false)do { auto parserTryVarTempResult_ = (assignExprWithoutYieldOrAwait
(yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (def_expr) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2875 if (!handler_.setLastFunctionFormalParameterDefault(funNode,
2876 def_expr)) {
2877 return false;
2878 }
2879 }
2880
2881 // Setter syntax uniquely requires exactly one argument.
2882 if (kind == FunctionSyntaxKind::Setter) {
2883 break;
2884 }
2885
2886 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
2887 TokenStream::SlashIsRegExp)) {
2888 return false;
2889 }
2890 if (!matched) {
2891 break;
2892 }
2893
2894 if (!hasRest) {
2895 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
2896 return false;
2897 }
2898 if (tt == TokenKind::RightParen) {
2899 break;
2900 }
2901 }
2902 }
2903
2904 TokenKind tt;
2905 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2906 return false;
2907 }
2908 if (tt != TokenKind::RightParen) {
2909 if (kind == FunctionSyntaxKind::Setter) {
2910 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2911 return false;
2912 }
2913
2914 error(JSMSG_PAREN_AFTER_FORMAL);
2915 return false;
2916 }
2917
2918 if (!hasDefault) {
2919 funbox->setLength(positionalFormals.length() - hasRest);
2920 }
2921
2922 funbox->setArgCount(positionalFormals.length());
2923 } else if (kind == FunctionSyntaxKind::Setter) {
2924 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2925 return false;
2926 }
2927
2928 return true;
2929}
2930
2931template <typename Unit>
2932bool Parser<FullParseHandler, Unit>::skipLazyInnerFunction(
2933 FunctionNode* funNode, uint32_t toStringStart, bool tryAnnexB) {
2934 // When a lazily-parsed function is called, we only fully parse (and emit)
2935 // that function, not any of its nested children. The initial syntax-only
2936 // parse recorded the free variables of nested functions and their extents,
2937 // so we can skip over them after accounting for their free variables.
2938
2939 MOZ_ASSERT(pc_->isOutermostOfCurrentCompile())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isOutermostOfCurrentCompile())>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(pc_->isOutermostOfCurrentCompile()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->isOutermostOfCurrentCompile()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2939); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isOutermostOfCurrentCompile()"
")"); do { *((volatile int*)__null) = 2939; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2940 handler_.nextLazyInnerFunction();
2941 const ScriptStencil& cachedData = handler_.cachedScriptData();
2942 const ScriptStencilExtra& cachedExtra = handler_.cachedScriptExtra();
2943 MOZ_ASSERT(toStringStart == cachedExtra.extent.toStringStart)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(toStringStart == cachedExtra.extent.toStringStart)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(toStringStart == cachedExtra.extent.toStringStart)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("toStringStart == cachedExtra.extent.toStringStart"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2943); AnnotateMozCrashReason("MOZ_ASSERT" "(" "toStringStart == cachedExtra.extent.toStringStart"
")"); do { *((volatile int*)__null) = 2943; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2944
2945 FunctionBox* funbox = newFunctionBox(funNode, cachedData, cachedExtra);
2946 if (!funbox) {
2947 return false;
2948 }
2949
2950 ScriptStencil& script = funbox->functionStencil();
2951 funbox->copyFunctionFields(script);
2952
2953 // If the inner lazy function is class constructor, connect it to the class
2954 // statement/expression we are parsing.
2955 if (funbox->isClassConstructor()) {
2956 auto classStmt =
2957 pc_->template findInnermostStatement<ParseContext::ClassStatement>();
2958 MOZ_ASSERT(!classStmt->constructorBox)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!classStmt->constructorBox)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!classStmt->constructorBox
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!classStmt->constructorBox", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2958); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!classStmt->constructorBox"
")"); do { *((volatile int*)__null) = 2958; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2959 classStmt->constructorBox = funbox;
2960 }
2961
2962 MOZ_ASSERT_IF(pc_->isFunctionBox(),do { if (pc_->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(pc_->functionBox
()->index() < funbox->index())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->functionBox()->index
() < funbox->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->functionBox()->index() < funbox->index()",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->index() < funbox->index()"
")"); do { *((volatile int*)__null) = 2963; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2963 pc_->functionBox()->index() < funbox->index())do { if (pc_->isFunctionBox()) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(pc_->functionBox
()->index() < funbox->index())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->functionBox()->index
() < funbox->index()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->functionBox()->index() < funbox->index()",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2963); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->index() < funbox->index()"
")"); do { *((volatile int*)__null) = 2963; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2964
2965 PropagateTransitiveParseFlags(funbox, pc_->sc());
2966
2967 if (!tokenStream.advance(funbox->extent().sourceEnd)) {
2968 return false;
2969 }
2970
2971 // Append possible Annex B function box only upon successfully parsing.
2972 if (tryAnnexB &&
2973 !pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
2974 return false;
2975 }
2976
2977 return true;
2978}
2979
2980template <typename Unit>
2981bool Parser<SyntaxParseHandler, Unit>::skipLazyInnerFunction(
2982 FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
2983 MOZ_CRASH("Cannot skip lazy inner functions when syntax parsing")do { do { } while (false); MOZ_ReportCrash("" "Cannot skip lazy inner functions when syntax parsing"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2983); AnnotateMozCrashReason("MOZ_CRASH(" "Cannot skip lazy inner functions when syntax parsing"
")"); do { *((volatile int*)__null) = 2983; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
2984}
2985
2986template <class ParseHandler, typename Unit>
2987bool GeneralParser<ParseHandler, Unit>::skipLazyInnerFunction(
2988 FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
2989 return asFinalParser()->skipLazyInnerFunction(funNode, toStringStart,
2990 tryAnnexB);
2991}
2992
2993template <class ParseHandler, typename Unit>
2994bool GeneralParser<ParseHandler, Unit>::addExprAndGetNextTemplStrToken(
2995 YieldHandling yieldHandling, ListNodeType nodeList, TokenKind* ttp) {
2996 Node pn;
2997 MOZ_TRY_VAR_OR_RETURN(pn, expr(InAllowed, yieldHandling, TripledotProhibited),do { auto parserTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (pn) = parserTryVarTempResult_
.unwrap(); } while (0)
2998 false)do { auto parserTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (pn) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2999 handler_.addList(nodeList, pn);
3000
3001 TokenKind tt;
3002 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
3003 return false;
3004 }
3005 if (tt != TokenKind::RightCurly) {
3006 error(JSMSG_TEMPLSTR_UNTERM_EXPR);
3007 return false;
3008 }
3009
3010 return tokenStream.getTemplateToken(ttp);
3011}
3012
3013template <class ParseHandler, typename Unit>
3014bool GeneralParser<ParseHandler, Unit>::taggedTemplate(
3015 YieldHandling yieldHandling, ListNodeType tagArgsList, TokenKind tt) {
3016 CallSiteNodeType callSiteObjNode;
3017 MOZ_TRY_VAR_OR_RETURN(callSiteObjNode,do { auto parserTryVarTempResult_ = (handler_.newCallSiteObject
(pos().begin)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (callSiteObjNode) = parserTryVarTempResult_
.unwrap(); } while (0)
3018 handler_.newCallSiteObject(pos().begin), false)do { auto parserTryVarTempResult_ = (handler_.newCallSiteObject
(pos().begin)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (callSiteObjNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3019 handler_.addList(tagArgsList, callSiteObjNode);
3020
3021 pc_->sc()->setHasCallSiteObj();
3022
3023 while (true) {
3024 if (!appendToCallSiteObj(callSiteObjNode)) {
3025 return false;
3026 }
3027 if (tt != TokenKind::TemplateHead) {
3028 break;
3029 }
3030
3031 if (!addExprAndGetNextTemplStrToken(yieldHandling, tagArgsList, &tt)) {
3032 return false;
3033 }
3034 }
3035 handler_.setEndPosition(tagArgsList, callSiteObjNode);
3036 return true;
3037}
3038
3039template <class ParseHandler, typename Unit>
3040typename ParseHandler::ListNodeResult
3041GeneralParser<ParseHandler, Unit>::templateLiteral(
3042 YieldHandling yieldHandling) {
3043 NameNodeType literal;
3044 MOZ_TRY_VAR(literal, noSubstitutionUntaggedTemplate())do { auto mozTryVarTempResult_ = (noSubstitutionUntaggedTemplate
()); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
3045
3046 ListNodeType nodeList;
3047 MOZ_TRY_VAR(nodeList,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::TemplateStringListExpr, literal)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nodeList) = mozTryVarTempResult_.unwrap()
; } while (0)
3048 handler_.newList(ParseNodeKind::TemplateStringListExpr, literal))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::TemplateStringListExpr, literal)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nodeList) = mozTryVarTempResult_.unwrap()
; } while (0)
;
3049
3050 TokenKind tt;
3051 do {
3052 if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt)) {
3053 return errorResult();
3054 }
3055
3056 MOZ_TRY_VAR(literal, noSubstitutionUntaggedTemplate())do { auto mozTryVarTempResult_ = (noSubstitutionUntaggedTemplate
()); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
3057
3058 handler_.addList(nodeList, literal);
3059 } while (tt == TokenKind::TemplateHead);
3060 return nodeList;
3061}
3062
3063template <class ParseHandler, typename Unit>
3064typename ParseHandler::FunctionNodeResult
3065GeneralParser<ParseHandler, Unit>::functionDefinition(
3066 FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
3067 YieldHandling yieldHandling, TaggedParserAtomIndex funName,
3068 FunctionSyntaxKind kind, GeneratorKind generatorKind,
3069 FunctionAsyncKind asyncKind, bool tryAnnexB /* = false */) {
3070 MOZ_ASSERT_IF(kind == FunctionSyntaxKind::Statement, funName)do { if (kind == FunctionSyntaxKind::Statement) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(funName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(funName))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3070); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funName" ")"
); do { *((volatile int*)__null) = 3070; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3071
3072 // If we see any inner function, note it on our current context. The bytecode
3073 // emitter may eliminate the function later, but we use a conservative
3074 // definition for consistency between lazy and full parsing.
3075 pc_->sc()->setHasInnerFunctions();
3076
3077 // When fully parsing a lazy script, we do not fully reparse its inner
3078 // functions, which are also lazy. Instead, their free variables and source
3079 // extents are recorded and may be skipped.
3080 if (handler_.reuseLazyInnerFunctions()) {
3081 if (!skipLazyInnerFunction(funNode, toStringStart, tryAnnexB)) {
3082 return errorResult();
3083 }
3084
3085 return funNode;
3086 }
3087
3088 bool isSelfHosting = options().selfHostingMode;
3089 FunctionFlags flags =
3090 InitialFunctionFlags(kind, generatorKind, asyncKind, isSelfHosting);
3091
3092 // Self-hosted functions with special function names require extended slots
3093 // for various purposes.
3094 bool forceExtended =
3095 isSelfHosting && funName &&
3096 this->parserAtoms().isExtendedUnclonedSelfHostedFunctionName(funName);
3097 if (forceExtended) {
3098 flags.setIsExtended();
3099 }
3100
3101 // Speculatively parse using the directives of the parent parsing context.
3102 // If a directive is encountered (e.g., "use strict") that changes how the
3103 // function should have been parsed, we backup and reparse with the new set
3104 // of directives.
3105 Directives directives(pc_);
3106 Directives newDirectives = directives;
3107
3108 Position start(tokenStream);
3109 auto startObj = this->compilationState_.getPosition();
3110
3111 // Parse the inner function. The following is a loop as we may attempt to
3112 // reparse a function due to failed syntax parsing and encountering new
3113 // "use foo" directives.
3114 while (true) {
3115 if (trySyntaxParseInnerFunction(&funNode, funName, flags, toStringStart,
3116 inHandling, yieldHandling, kind,
3117 generatorKind, asyncKind, tryAnnexB,
3118 directives, &newDirectives)) {
3119 break;
3120 }
3121
3122 // Return on error.
3123 if (anyChars.hadError() || directives == newDirectives) {
3124 return errorResult();
3125 }
3126
3127 // Assignment must be monotonic to prevent infinitely attempting to
3128 // reparse.
3129 MOZ_ASSERT_IF(directives.strict(), newDirectives.strict())do { if (directives.strict()) { do { static_assert( mozilla::
detail::AssertionConditionType<decltype(newDirectives.strict
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(newDirectives.strict()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("newDirectives.strict()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newDirectives.strict()"
")"); do { *((volatile int*)__null) = 3129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3130 MOZ_ASSERT_IF(directives.asmJS(), newDirectives.asmJS())do { if (directives.asmJS()) { do { static_assert( mozilla::detail
::AssertionConditionType<decltype(newDirectives.asmJS())>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(newDirectives.asmJS()))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("newDirectives.asmJS()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newDirectives.asmJS()"
")"); do { *((volatile int*)__null) = 3130; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3131 directives = newDirectives;
3132
3133 // Rewind to retry parsing with new directives applied.
3134 tokenStream.rewind(start);
3135 this->compilationState_.rewind(startObj);
3136
3137 // functionFormalParametersAndBody may have already set body before failing.
3138 handler_.setFunctionFormalParametersAndBody(funNode, null());
3139 }
3140
3141 return funNode;
3142}
3143
3144template <typename Unit>
3145bool Parser<FullParseHandler, Unit>::advancePastSyntaxParsedFunction(
3146 SyntaxParser* syntaxParser) {
3147 MOZ_ASSERT(getSyntaxParser() == syntaxParser)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(getSyntaxParser() == syntaxParser)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(getSyntaxParser() == syntaxParser
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"getSyntaxParser() == syntaxParser", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3147); AnnotateMozCrashReason("MOZ_ASSERT" "(" "getSyntaxParser() == syntaxParser"
")"); do { *((volatile int*)__null) = 3147; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3148
3149 // Advance this parser over tokens processed by the syntax parser.
3150 Position currentSyntaxPosition(syntaxParser->tokenStream);
3151 if (!tokenStream.fastForward(currentSyntaxPosition, syntaxParser->anyChars)) {
3152 return false;
3153 }
3154
3155 anyChars.adoptState(syntaxParser->anyChars);
3156 tokenStream.adoptState(syntaxParser->tokenStream);
3157 return true;
3158}
3159
3160template <typename Unit>
3161bool Parser<FullParseHandler, Unit>::trySyntaxParseInnerFunction(
3162 FunctionNode** funNode, TaggedParserAtomIndex explicitName,
3163 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3164 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3165 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3166 Directives inheritedDirectives, Directives* newDirectives) {
3167 // Try a syntax parse for this inner function.
3168 do {
3169 // If we're assuming this function is an IIFE, always perform a full
3170 // parse to avoid the overhead of a lazy syntax-only parse. Although
3171 // the prediction may be incorrect, IIFEs are common enough that it
3172 // pays off for lots of code.
3173 if ((*funNode)->isLikelyIIFE() &&
3174 generatorKind == GeneratorKind::NotGenerator &&
3175 asyncKind == FunctionAsyncKind::SyncFunction) {
3176 break;
3177 }
3178
3179 SyntaxParser* syntaxParser = getSyntaxParser();
3180 if (!syntaxParser) {
3181 break;
3182 }
3183
3184 UsedNameTracker::RewindToken token = usedNames_.getRewindToken();
3185 auto statePosition = this->compilationState_.getPosition();
3186
3187 // Move the syntax parser to the current position in the stream. In the
3188 // common case this seeks forward, but it'll also seek backward *at least*
3189 // when arrow functions appear inside arrow function argument defaults
3190 // (because we rewind to reparse arrow functions once we're certain they're
3191 // arrow functions):
3192 //
3193 // var x = (y = z => 2) => q;
3194 // // ^ we first seek to here to syntax-parse this function
3195 // // ^ then we seek back to here to syntax-parse the outer function
3196 Position currentPosition(tokenStream);
3197 if (!syntaxParser->tokenStream.seekTo(currentPosition, anyChars)) {
3198 return false;
3199 }
3200
3201 // Make a FunctionBox before we enter the syntax parser, because |pn|
3202 // still expects a FunctionBox to be attached to it during BCE, and
3203 // the syntax parser cannot attach one to it.
3204 FunctionBox* funbox =
3205 newFunctionBox(*funNode, explicitName, flags, toStringStart,
3206 inheritedDirectives, generatorKind, asyncKind);
3207 if (!funbox) {
3208 return false;
3209 }
3210 funbox->initWithEnclosingParseContext(pc_, kind);
3211
3212 auto syntaxNodeResult = syntaxParser->innerFunctionForFunctionBox(
3213 SyntaxParseHandler::Node::NodeGeneric, pc_, funbox, inHandling,
3214 yieldHandling, kind, newDirectives);
3215 if (syntaxNodeResult.isErr()) {
3216 if (syntaxParser->hadAbortedSyntaxParse()) {
3217 // Try again with a full parse. UsedNameTracker needs to be
3218 // rewound to just before we tried the syntax parse for
3219 // correctness.
3220 syntaxParser->clearAbortedSyntaxParse();
3221 usedNames_.rewind(token);
3222 this->compilationState_.rewind(statePosition);
3223 MOZ_ASSERT(!fc_->hadErrors())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!fc_->hadErrors())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!fc_->hadErrors()))), 0))
) { do { } while (false); MOZ_ReportAssertionFailure("!fc_->hadErrors()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3223); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!fc_->hadErrors()"
")"); do { *((volatile int*)__null) = 3223; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3224 break;
3225 }
3226 return false;
3227 }
3228
3229 if (!advancePastSyntaxParsedFunction(syntaxParser)) {
3230 return false;
3231 }
3232
3233 // Update the end position of the parse node.
3234 (*funNode)->pn_pos.end = anyChars.currentToken().pos.end;
3235
3236 // Append possible Annex B function box only upon successfully parsing.
3237 if (tryAnnexB) {
3238 if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
3239 return false;
3240 }
3241 }
3242
3243 return true;
3244 } while (false);
3245
3246 // We failed to do a syntax parse above, so do the full parse.
3247 FunctionNodeType innerFunc;
3248 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3249 innerFunc,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3250 innerFunction(*funNode, pc_, explicitName, flags, toStringStart,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3251 inHandling, yieldHandling, kind, generatorKind, asyncKind,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3252 tryAnnexB, inheritedDirectives, newDirectives),do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3253 false)do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3254
3255 *funNode = innerFunc;
3256 return true;
3257}
3258
3259template <typename Unit>
3260bool Parser<SyntaxParseHandler, Unit>::trySyntaxParseInnerFunction(
3261 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
3262 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3263 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3264 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3265 Directives inheritedDirectives, Directives* newDirectives) {
3266 // This is already a syntax parser, so just parse the inner function.
3267 FunctionNodeType innerFunc;
3268 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3269 innerFunc,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3270 innerFunction(*funNode, pc_, explicitName, flags, toStringStart,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3271 inHandling, yieldHandling, kind, generatorKind, asyncKind,do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3272 tryAnnexB, inheritedDirectives, newDirectives),do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
3273 false)do { auto parserTryVarTempResult_ = (innerFunction(*funNode, pc_
, explicitName, flags, toStringStart, inHandling, yieldHandling
, kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives
, newDirectives)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (innerFunc) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3274
3275 *funNode = innerFunc;
3276 return true;
3277}
3278
3279template <class ParseHandler, typename Unit>
3280inline bool GeneralParser<ParseHandler, Unit>::trySyntaxParseInnerFunction(
3281 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
3282 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3283 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3284 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3285 Directives inheritedDirectives, Directives* newDirectives) {
3286 return asFinalParser()->trySyntaxParseInnerFunction(
3287 funNode, explicitName, flags, toStringStart, inHandling, yieldHandling,
3288 kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives,
3289 newDirectives);
3290}
3291
3292template <class ParseHandler, typename Unit>
3293typename ParseHandler::FunctionNodeResult
3294GeneralParser<ParseHandler, Unit>::innerFunctionForFunctionBox(
3295 FunctionNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
3296 InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
3297 Directives* newDirectives) {
3298 // Note that it is possible for outerpc != this->pc_, as we may be
3299 // attempting to syntax parse an inner function from an outer full
3300 // parser. In that case, outerpc is a SourceParseContext from the full parser
3301 // instead of the current top of the stack of the syntax parser.
3302
3303 // Push a new ParseContext.
3304 SourceParseContext funpc(this, funbox, newDirectives);
3305 if (!funpc.init()) {
3306 return errorResult();
3307 }
3308
3309 if (!functionFormalParametersAndBody(inHandling, yieldHandling, &funNode,
3310 kind)) {
3311 return errorResult();
3312 }
3313
3314 if (!leaveInnerFunction(outerpc)) {
3315 return errorResult();
3316 }
3317
3318 return funNode;
3319}
3320
3321template <class ParseHandler, typename Unit>
3322typename ParseHandler::FunctionNodeResult
3323GeneralParser<ParseHandler, Unit>::innerFunction(
3324 FunctionNodeType funNode, ParseContext* outerpc,
3325 TaggedParserAtomIndex explicitName, FunctionFlags flags,
3326 uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
3327 FunctionSyntaxKind kind, GeneratorKind generatorKind,
3328 FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
3329 Directives* newDirectives) {
3330 // Note that it is possible for outerpc != this->pc_, as we may be
3331 // attempting to syntax parse an inner function from an outer full
3332 // parser. In that case, outerpc is a SourceParseContext from the full parser
3333 // instead of the current top of the stack of the syntax parser.
3334
3335 FunctionBox* funbox =
3336 newFunctionBox(funNode, explicitName, flags, toStringStart,
3337 inheritedDirectives, generatorKind, asyncKind);
3338 if (!funbox) {
3339 return errorResult();
3340 }
3341 funbox->initWithEnclosingParseContext(outerpc, kind);
3342
3343 FunctionNodeType innerFunc;
3344 MOZ_TRY_VAR(innerFunc,do { auto mozTryVarTempResult_ = (innerFunctionForFunctionBox
(funNode, outerpc, funbox, inHandling, yieldHandling, kind, newDirectives
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerFunc
) = mozTryVarTempResult_.unwrap(); } while (0)
3345 innerFunctionForFunctionBox(funNode, outerpc, funbox, inHandling,do { auto mozTryVarTempResult_ = (innerFunctionForFunctionBox
(funNode, outerpc, funbox, inHandling, yieldHandling, kind, newDirectives
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerFunc
) = mozTryVarTempResult_.unwrap(); } while (0)
3346 yieldHandling, kind, newDirectives))do { auto mozTryVarTempResult_ = (innerFunctionForFunctionBox
(funNode, outerpc, funbox, inHandling, yieldHandling, kind, newDirectives
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerFunc
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3347
3348 // Append possible Annex B function box only upon successfully parsing.
3349 if (tryAnnexB) {
3350 if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
3351 return errorResult();
3352 }
3353 }
3354
3355 return innerFunc;
3356}
3357
3358template <class ParseHandler, typename Unit>
3359bool GeneralParser<ParseHandler, Unit>::appendToCallSiteObj(
3360 CallSiteNodeType callSiteObj) {
3361 Node cookedNode;
3362 MOZ_TRY_VAR_OR_RETURN(cookedNode, noSubstitutionTaggedTemplate(), false)do { auto parserTryVarTempResult_ = (noSubstitutionTaggedTemplate
()); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()
), 0))) { return (false); } (cookedNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3363
3364 auto atom = tokenStream.getRawTemplateStringAtom();
3365 if (!atom) {
3366 return false;
3367 }
3368 NameNodeType rawNode;
3369 MOZ_TRY_VAR_OR_RETURN(rawNode, handler_.newTemplateStringLiteral(atom, pos()),do { auto parserTryVarTempResult_ = (handler_.newTemplateStringLiteral
(atom, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (rawNode) = parserTryVarTempResult_
.unwrap(); } while (0)
3370 false)do { auto parserTryVarTempResult_ = (handler_.newTemplateStringLiteral
(atom, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (rawNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3371
3372 handler_.addToCallSiteObject(callSiteObj, rawNode, cookedNode);
3373 return true;
3374}
3375
3376template <typename Unit>
3377FullParseHandler::FunctionNodeResult
3378Parser<FullParseHandler, Unit>::standaloneLazyFunction(
3379 CompilationInput& input, uint32_t toStringStart, bool strict,
3380 GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
3381 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 3381; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3382
3383 FunctionSyntaxKind syntaxKind = input.functionSyntaxKind();
3384 FunctionNodeType funNode;
3385 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3386
3387 TaggedParserAtomIndex displayAtom =
3388 this->getCompilationState().previousParseCache.displayAtom();
3389
3390 Directives directives(strict);
3391 FunctionBox* funbox =
3392 newFunctionBox(funNode, displayAtom, input.functionFlags(), toStringStart,
3393 directives, generatorKind, asyncKind);
3394 if (!funbox) {
3395 return errorResult();
3396 }
3397 const ScriptStencilExtra& funExtra =
3398 this->getCompilationState().previousParseCache.funExtra();
3399 funbox->initFromLazyFunction(
3400 funExtra, this->getCompilationState().scopeContext, syntaxKind);
3401 if (funbox->useMemberInitializers()) {
3402 funbox->setMemberInitializers(funExtra.memberInitializers());
3403 }
3404
3405 Directives newDirectives = directives;
3406 SourceParseContext funpc(this, funbox, &newDirectives);
3407 if (!funpc.init()) {
3408 return errorResult();
3409 }
3410
3411 // Our tokenStream has no current token, so funNode's position is garbage.
3412 // Substitute the position of the first token in our source. If the
3413 // function is a not-async arrow, use TokenStream::SlashIsRegExp to keep
3414 // verifyConsistentModifier from complaining (we will use
3415 // TokenStream::SlashIsRegExp in functionArguments).
3416 Modifier modifier = (input.functionFlags().isArrow() &&
3417 asyncKind == FunctionAsyncKind::SyncFunction)
3418 ? TokenStream::SlashIsRegExp
3419 : TokenStream::SlashIsDiv;
3420 if (!tokenStream.peekTokenPos(&funNode->pn_pos, modifier)) {
3421 return errorResult();
3422 }
3423
3424 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
3425
3426 if (funbox->isSyntheticFunction()) {
3427 // Currently default class constructors are the only synthetic function that
3428 // supports delazification.
3429 MOZ_ASSERT(funbox->isClassConstructor())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isClassConstructor())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isClassConstructor
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isClassConstructor()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3429); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isClassConstructor()"
")"); do { *((volatile int*)__null) = 3429; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3430 MOZ_ASSERT(funbox->extent().toStringStart == funbox->extent().sourceStart)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->extent().toStringStart == funbox->extent
().sourceStart)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(funbox->extent().toStringStart
== funbox->extent().sourceStart))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("funbox->extent().toStringStart == funbox->extent().sourceStart"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3430); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->extent().toStringStart == funbox->extent().sourceStart"
")"); do { *((volatile int*)__null) = 3430; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3431
3432 HasHeritage hasHeritage = funbox->isDerivedClassConstructor()
3433 ? HasHeritage::Yes
3434 : HasHeritage::No;
3435 TokenPos synthesizedBodyPos(funbox->extent().toStringStart,
3436 funbox->extent().toStringEnd);
3437
3438 // Reset pos() to the `class` keyword for predictable results.
3439 tokenStream.consumeKnownToken(TokenKind::Class);
3440
3441 if (!this->synthesizeConstructorBody(synthesizedBodyPos, hasHeritage,
3442 funNode, funbox)) {
3443 return errorResult();
3444 }
3445 } else {
3446 if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
3447 syntaxKind)) {
3448 MOZ_ASSERT(directives == newDirectives)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(directives == newDirectives)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(directives == newDirectives)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("directives == newDirectives"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "directives == newDirectives"
")"); do { *((volatile int*)__null) = 3448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3449 return errorResult();
3450 }
3451 }
3452
3453 if (!CheckParseTree(this->fc_, alloc_, funNode)) {
3454 return errorResult();
3455 }
3456
3457 ParseNode* node = funNode;
3458 // Don't constant-fold inside "use asm" code, as this could create a parse
3459 // tree that doesn't type-check as asm.js.
3460 if (!pc_->useAsmOrInsideUseAsm()) {
3461 if (!FoldConstants(this->fc_, this->parserAtoms(), this->bigInts(), &node,
3462 &handler_)) {
3463 return errorResult();
3464 }
3465 }
3466 funNode = &node->as<FunctionNode>();
3467
3468 return funNode;
3469}
3470
3471void ParserBase::setFunctionEndFromCurrentToken(FunctionBox* funbox) const {
3472 if (compilationState_.isInitialStencil()) {
3473 MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type != TokenKind::Eof)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type != TokenKind::Eof))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type != TokenKind::Eof"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3473); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type != TokenKind::Eof"
")"); do { *((volatile int*)__null) = 3473; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3474 MOZ_ASSERT(anyChars.currentToken().type < TokenKind::Limit)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type < TokenKind::Limit)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type < TokenKind::Limit))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type < TokenKind::Limit"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3474); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type < TokenKind::Limit"
")"); do { *((volatile int*)__null) = 3474; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3475 funbox->setEnd(anyChars.currentToken().pos.end);
3476 } else {
3477 // If we're delazifying an arrow function with expression body and
3478 // the expression is also a function, we arrive here immediately after
3479 // skipping the function by Parser::skipLazyInnerFunction.
3480 //
3481 // a => b => c
3482 // ^
3483 // |
3484 // we're here
3485 //
3486 // In that case, the current token's type field is either Limit or
3487 // poisoned.
3488 // We shouldn't read the value if it's poisoned.
3489 // See TokenStreamSpecific<Unit, AnyCharsAccess>::advance and
3490 // mfbt/MemoryChecking.h for more details.
3491 //
3492 // Also, in delazification, the FunctionBox should already have the
3493 // correct extent, and we shouldn't overwrite it here.
3494 // See ScriptStencil variant of PerHandlerParser::newFunctionBox.
3495#if !defined(MOZ_ASAN) && !defined(MOZ_MSAN) && !defined(MOZ_VALGRIND)
3496 MOZ_ASSERT(anyChars.currentToken().type != TokenKind::Eof)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type != TokenKind::Eof)>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type != TokenKind::Eof))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type != TokenKind::Eof"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3496); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type != TokenKind::Eof"
")"); do { *((volatile int*)__null) = 3496; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3497#endif
3498 MOZ_ASSERT(funbox->extent().sourceEnd == anyChars.currentToken().pos.end)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->extent().sourceEnd == anyChars.currentToken
().pos.end)>::isValid, "invalid assertion condition"); if (
(__builtin_expect(!!(!(!!(funbox->extent().sourceEnd == anyChars
.currentToken().pos.end))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->extent().sourceEnd == anyChars.currentToken().pos.end"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3498); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->extent().sourceEnd == anyChars.currentToken().pos.end"
")"); do { *((volatile int*)__null) = 3498; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3499 }
3500}
3501
3502template <class ParseHandler, typename Unit>
3503bool GeneralParser<ParseHandler, Unit>::functionFormalParametersAndBody(
3504 InHandling inHandling, YieldHandling yieldHandling,
3505 FunctionNodeType* funNode, FunctionSyntaxKind kind,
3506 const Maybe<uint32_t>& parameterListEnd /* = Nothing() */,
3507 bool isStandaloneFunction /* = false */) {
3508 // Given a properly initialized parse context, try to parse an actual
3509 // function without concern for conversion to strict mode, use of lazy
3510 // parsing and such.
3511
3512 FunctionBox* funbox = pc_->functionBox();
3513
3514 if (kind == FunctionSyntaxKind::ClassConstructor ||
3515 kind == FunctionSyntaxKind::DerivedClassConstructor) {
3516 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
3517 return false;
3518 }
3519#ifdef ENABLE_DECORATORS
3520 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
3521 dot_instanceExtraInitializers_())) {
3522 return false;
3523 }
3524#endif
3525 }
3526
3527 // See below for an explanation why arrow function parameters and arrow
3528 // function bodies are parsed with different yield/await settings.
3529 {
3530 AwaitHandling awaitHandling =
3531 kind == FunctionSyntaxKind::StaticClassBlock ? AwaitIsDisallowed
3532 : (funbox->isAsync() ||
3533 (kind == FunctionSyntaxKind::Arrow && awaitIsKeyword()))
3534 ? AwaitIsKeyword
3535 : AwaitIsName;
3536 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this, awaitHandling);
3537 AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(
3538 this, funbox->isAsync());
3539 if (!functionArguments(yieldHandling, kind, *funNode)) {
3540 return false;
3541 }
3542 }
3543
3544 Maybe<ParseContext::VarScope> varScope;
3545 if (funbox->hasParameterExprs) {
3546 varScope.emplace(this);
3547 if (!varScope->init(pc_)) {
3548 return false;
3549 }
3550 } else {
3551 pc_->functionScope().useAsVarScope(pc_);
3552 }
3553
3554 if (kind == FunctionSyntaxKind::Arrow) {
3555 TokenKind tt;
3556 if (!tokenStream.peekTokenSameLine(&tt)) {
3557 return false;
3558 }
3559
3560 if (tt == TokenKind::Eol) {
3561 error(JSMSG_UNEXPECTED_TOKEN,
3562 "'=>' on the same line after an argument list",
3563 TokenKindToDesc(tt));
3564 return false;
3565 }
3566 if (tt != TokenKind::Arrow) {
3567 error(JSMSG_BAD_ARROW_ARGS);
3568 return false;
3569 }
3570 tokenStream.consumeKnownToken(TokenKind::Arrow);
3571 }
3572
3573 // When parsing something for new Function() we have to make sure to
3574 // only treat a certain part of the source as a parameter list.
3575 if (parameterListEnd.isSome() && parameterListEnd.value() != pos().begin) {
3576 error(JSMSG_UNEXPECTED_PARAMLIST_END);
3577 return false;
3578 }
3579
3580 // Parse the function body.
3581 FunctionBodyType bodyType = StatementListBody;
3582 TokenKind tt;
3583 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
3584 return false;
3585 }
3586 uint32_t openedPos = 0;
3587 if (tt != TokenKind::LeftCurly) {
3588 if (kind != FunctionSyntaxKind::Arrow) {
3589 error(JSMSG_CURLY_BEFORE_BODY);
3590 return false;
3591 }
3592
3593 anyChars.ungetToken();
3594 bodyType = ExpressionBody;
3595 funbox->setHasExprBody();
3596 } else {
3597 openedPos = pos().begin;
3598 }
3599
3600 // Arrow function parameters inherit yieldHandling from the enclosing
3601 // context, but the arrow body doesn't. E.g. in |(a = yield) => yield|,
3602 // |yield| in the parameters is either a name or keyword, depending on
3603 // whether the arrow function is enclosed in a generator function or not.
3604 // Whereas the |yield| in the function body is always parsed as a name.
3605 // The same goes when parsing |await| in arrow functions.
3606 YieldHandling bodyYieldHandling = GetYieldHandling(pc_->generatorKind());
3607 AwaitHandling bodyAwaitHandling = GetAwaitHandling(pc_->asyncKind());
3608 bool inheritedStrict = pc_->sc()->strict();
3609 LexicalScopeNodeType body;
3610 {
3611 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this,
3612 bodyAwaitHandling);
3613 AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(this,
3614 false);
3615 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
3616 body, functionBody(inHandling, bodyYieldHandling, kind, bodyType),do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
3617 false)do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
;
3618 }
3619
3620 // Revalidate the function name when we transitioned to strict mode.
3621 if ((kind == FunctionSyntaxKind::Statement ||
3622 kind == FunctionSyntaxKind::Expression) &&
3623 funbox->explicitName() && !inheritedStrict && pc_->sc()->strict()) {
3624 MOZ_ASSERT(pc_->sc()->hasExplicitUseStrict(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3626); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3626; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
3625 "strict mode should only change when a 'use strict' directive "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3626); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3626; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
3626 "is present")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->sc()->hasExplicitUseStrict())>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(pc_->sc()->hasExplicitUseStrict()))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->sc()->hasExplicitUseStrict()"
" (" "strict mode should only change when a 'use strict' directive "
"is present" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3626); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3626; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
3627
3628 auto propertyName = funbox->explicitName();
3629 YieldHandling nameYieldHandling;
3630 if (kind == FunctionSyntaxKind::Expression) {
3631 // Named lambda has binding inside it.
3632 nameYieldHandling = bodyYieldHandling;
3633 } else {
3634 // Otherwise YieldHandling cannot be checked at this point
3635 // because of different context.
3636 // It should already be checked before this point.
3637 nameYieldHandling = YieldIsName;
3638 }
3639
3640 // We already use the correct await-handling at this point, therefore
3641 // we don't need call AutoAwaitIsKeyword here.
3642
3643 uint32_t nameOffset = handler_.getFunctionNameOffset(*funNode, anyChars);
3644 if (!checkBindingIdentifier(propertyName, nameOffset, nameYieldHandling)) {
3645 return false;
3646 }
3647 }
3648
3649 if (bodyType == StatementListBody) {
3650 // Cannot use mustMatchToken here because of internal compiler error on
3651 // gcc 6.4.0, with linux 64 SM hazard build.
3652 TokenKind actual;
3653 if (!tokenStream.getToken(&actual, TokenStream::SlashIsRegExp)) {
3654 return false;
3655 }
3656 if (actual != TokenKind::RightCurly) {
3657 reportMissingClosing(JSMSG_CURLY_AFTER_BODY, JSMSG_CURLY_OPENED,
3658 openedPos);
3659 return false;
3660 }
3661
3662 setFunctionEndFromCurrentToken(funbox);
3663 } else {
3664 MOZ_ASSERT(kind == FunctionSyntaxKind::Arrow)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == FunctionSyntaxKind::Arrow)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == FunctionSyntaxKind::
Arrow))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == FunctionSyntaxKind::Arrow", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3664); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == FunctionSyntaxKind::Arrow"
")"); do { *((volatile int*)__null) = 3664; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3665
3666 if (anyChars.hadError()) {
3667 return false;
3668 }
3669
3670 setFunctionEndFromCurrentToken(funbox);
3671
3672 if (kind == FunctionSyntaxKind::Statement) {
3673 if (!matchOrInsertSemicolon()) {
3674 return false;
3675 }
3676 }
3677 }
3678
3679 if (IsMethodDefinitionKind(kind) && pc_->superScopeNeedsHomeObject()) {
3680 funbox->setNeedsHomeObject();
3681 }
3682
3683 if (!finishFunction(isStandaloneFunction)) {
3684 return false;
3685 }
3686
3687 handler_.setEndPosition(body, pos().begin);
3688 handler_.setEndPosition(*funNode, pos().end);
3689 handler_.setFunctionBody(*funNode, body);
3690
3691 return true;
3692}
3693
3694template <class ParseHandler, typename Unit>
3695typename ParseHandler::FunctionNodeResult
3696GeneralParser<ParseHandler, Unit>::functionStmt(uint32_t toStringStart,
3697 YieldHandling yieldHandling,
3698 DefaultHandling defaultHandling,
3699 FunctionAsyncKind asyncKind) {
3700 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3700); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 3700; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3701
3702 // In sloppy mode, Annex B.3.2 allows labelled function declarations.
3703 // Otherwise it's a parse error.
3704 ParseContext::Statement* declaredInStmt = pc_->innermostStatement();
3705 if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
3706 MOZ_ASSERT(!pc_->sc()->strict(),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!pc_->sc()->strict())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!pc_->sc()->strict()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!pc_->sc()->strict()"
" (" "labeled functions shouldn't be parsed in strict mode" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3707); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc_->sc()->strict()"
") (" "labeled functions shouldn't be parsed in strict mode"
")"); do { *((volatile int*)__null) = 3707; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3707 "labeled functions shouldn't be parsed in strict mode")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!pc_->sc()->strict())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!pc_->sc()->strict()))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!pc_->sc()->strict()"
" (" "labeled functions shouldn't be parsed in strict mode" ")"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3707); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc_->sc()->strict()"
") (" "labeled functions shouldn't be parsed in strict mode"
")"); do { *((volatile int*)__null) = 3707; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3708
3709 // Find the innermost non-label statement. Report an error if it's
3710 // unbraced: functions can't appear in it. Otherwise the statement
3711 // (or its absence) determines the scope the function's bound in.
3712 while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
3713 declaredInStmt = declaredInStmt->enclosing();
3714 }
3715
3716 if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
3717 error(JSMSG_SLOPPY_FUNCTION_LABEL);
3718 return errorResult();
3719 }
3720 }
3721
3722 TokenKind tt;
3723 if (!tokenStream.getToken(&tt)) {
3724 return errorResult();
3725 }
3726
3727 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
3728 if (tt == TokenKind::Mul) {
3729 generatorKind = GeneratorKind::Generator;
3730 if (!tokenStream.getToken(&tt)) {
3731 return errorResult();
3732 }
3733 }
3734
3735 TaggedParserAtomIndex name;
3736 if (TokenKindIsPossibleIdentifier(tt)) {
3737 name = bindingIdentifier(yieldHandling);
3738 if (!name) {
3739 return errorResult();
3740 }
3741 } else if (defaultHandling == AllowDefaultName) {
3742 name = TaggedParserAtomIndex::WellKnown::default_();
3743 anyChars.ungetToken();
3744 } else {
3745 /* Unnamed function expressions are forbidden in statement context. */
3746 error(JSMSG_UNNAMED_FUNCTION_STMT);
3747 return errorResult();
3748 }
3749
3750 // Note the declared name and check for early errors.
3751 DeclarationKind kind;
3752 if (declaredInStmt) {
3753 MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(declaredInStmt->kind() != StatementKind::Label)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(declaredInStmt->kind() != StatementKind::Label)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("declaredInStmt->kind() != StatementKind::Label"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3753); AnnotateMozCrashReason("MOZ_ASSERT" "(" "declaredInStmt->kind() != StatementKind::Label"
")"); do { *((volatile int*)__null) = 3753; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3754 MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(StatementKindIsBraced(declaredInStmt->kind()))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(StatementKindIsBraced(declaredInStmt->kind())))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("StatementKindIsBraced(declaredInStmt->kind())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3754); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StatementKindIsBraced(declaredInStmt->kind())"
")"); do { *((volatile int*)__null) = 3754; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3755
3756 kind =
3757 (!pc_->sc()->strict() && generatorKind == GeneratorKind::NotGenerator &&
3758 asyncKind == FunctionAsyncKind::SyncFunction)
3759 ? DeclarationKind::SloppyLexicalFunction
3760 : DeclarationKind::LexicalFunction;
3761 } else {
3762 kind = pc_->atModuleLevel() ? DeclarationKind::ModuleBodyLevelFunction
3763 : DeclarationKind::BodyLevelFunction;
3764 }
3765
3766 if (!noteDeclaredName(name, kind, pos())) {
3767 return errorResult();
3768 }
3769
3770 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
3771 FunctionNodeType funNode;
3772 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3773
3774 // Under sloppy mode, try Annex B.3.3 semantics. If making an additional
3775 // 'var' binding of the same name does not throw an early error, do so.
3776 // This 'var' binding would be assigned the function object when its
3777 // declaration is reached, not at the start of the block.
3778 //
3779 // This semantics is implemented upon Scope exit in
3780 // Scope::propagateAndMarkAnnexBFunctionBoxes.
3781 bool tryAnnexB = kind == DeclarationKind::SloppyLexicalFunction;
3782
3783 YieldHandling newYieldHandling = GetYieldHandling(generatorKind);
3784 return functionDefinition(funNode, toStringStart, InAllowed, newYieldHandling,
3785 name, syntaxKind, generatorKind, asyncKind,
3786 tryAnnexB);
3787}
3788
3789template <class ParseHandler, typename Unit>
3790typename ParseHandler::FunctionNodeResult
3791GeneralParser<ParseHandler, Unit>::functionExpr(uint32_t toStringStart,
3792 InvokedPrediction invoked,
3793 FunctionAsyncKind asyncKind) {
3794 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3794); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 3794; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3795
3796 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(
3797 this, GetAwaitHandling(asyncKind));
3798 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
3799 TokenKind tt;
3800 if (!tokenStream.getToken(&tt)) {
3801 return errorResult();
3802 }
3803
3804 if (tt == TokenKind::Mul) {
3805 generatorKind = GeneratorKind::Generator;
3806 if (!tokenStream.getToken(&tt)) {
3807 return errorResult();
3808 }
3809 }
3810
3811 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
3812
3813 TaggedParserAtomIndex name;
3814 if (TokenKindIsPossibleIdentifier(tt)) {
3815 name = bindingIdentifier(yieldHandling);
3816 if (!name) {
3817 return errorResult();
3818 }
3819 } else {
3820 anyChars.ungetToken();
3821 }
3822
3823 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Expression;
3824 FunctionNodeType funNode;
3825 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3826
3827 if (invoked) {
3828 funNode = handler_.setLikelyIIFE(funNode);
3829 }
3830
3831 return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
3832 name, syntaxKind, generatorKind, asyncKind);
3833}
3834
3835/*
3836 * Return true if this node, known to be an unparenthesized string literal
3837 * that never contain escape sequences, could be the string of a directive in a
3838 * Directive Prologue. Directive strings never contain escape sequences or line
3839 * continuations.
3840 */
3841static inline bool IsUseStrictDirective(const TokenPos& pos,
3842 TaggedParserAtomIndex atom) {
3843 // the length of "use strict", including quotation.
3844 static constexpr size_t useStrictLength = 12;
3845 return atom == TaggedParserAtomIndex::WellKnown::use_strict_() &&
3846 pos.begin + useStrictLength == pos.end;
3847}
3848static inline bool IsUseAsmDirective(const TokenPos& pos,
3849 TaggedParserAtomIndex atom) {
3850 // the length of "use asm", including quotation.
3851 static constexpr size_t useAsmLength = 9;
3852 return atom == TaggedParserAtomIndex::WellKnown::use_asm_() &&
3853 pos.begin + useAsmLength == pos.end;
3854}
3855
3856template <typename Unit>
3857bool Parser<SyntaxParseHandler, Unit>::asmJS(ListNodeType list) {
3858 // While asm.js could technically be validated and compiled during syntax
3859 // parsing, we have no guarantee that some later JS wouldn't abort the
3860 // syntax parse and cause us to re-parse (and re-compile) the asm.js module.
3861 // For simplicity, unconditionally abort the syntax parse when "use asm" is
3862 // encountered so that asm.js is always validated/compiled exactly once
3863 // during a full parse.
3864 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3864); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 3864; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
3865 return false;
3866}
3867
3868template <typename Unit>
3869bool Parser<FullParseHandler, Unit>::asmJS(ListNodeType list) {
3870 // Disable syntax parsing in anything nested inside the asm.js module.
3871 disableSyntaxParser();
3872
3873 // We should be encountering the "use asm" directive for the first time; if
3874 // the directive is already, we must have failed asm.js validation and we're
3875 // reparsing. In that case, don't try to validate again. A non-null
3876 // newDirectives means we're not in a normal function.
3877 if (!pc_->newDirectives || pc_->newDirectives->asmJS()) {
3878 return true;
3879 }
3880
3881 // If there is no ScriptSource, then we are doing a non-compiling parse and
3882 // so we shouldn't (and can't, without a ScriptSource) compile.
3883 if (ss == nullptr) {
3884 return true;
3885 }
3886
3887 pc_->functionBox()->useAsm = true;
3888
3889 // Attempt to validate and compile this asm.js module. On success, the
3890 // tokenStream has been advanced to the closing }. On failure, the
3891 // tokenStream is in an indeterminate state and we must reparse the
3892 // function from the beginning. Reparsing is triggered by marking that a
3893 // new directive has been encountered and returning 'false'.
3894 bool validated;
3895 if (!CompileAsmJS(this->fc_, this->parserAtoms(), *this, list, &validated)) {
3896 return false;
3897 }
3898 if (!validated) {
3899 pc_->newDirectives->setAsmJS();
3900 return false;
3901 }
3902
3903 return true;
3904}
3905
3906template <class ParseHandler, typename Unit>
3907inline bool GeneralParser<ParseHandler, Unit>::asmJS(ListNodeType list) {
3908 return asFinalParser()->asmJS(list);
3909}
3910
3911/*
3912 * Recognize Directive Prologue members and directives. Assuming |pn| is a
3913 * candidate for membership in a directive prologue, recognize directives and
3914 * set |pc_|'s flags accordingly. If |pn| is indeed part of a prologue, set its
3915 * |prologue| flag.
3916 *
3917 * Note that the following is a strict mode function:
3918 *
3919 * function foo() {
3920 * "blah" // inserted semi colon
3921 * "blurgh"
3922 * "use\x20loose"
3923 * "use strict"
3924 * }
3925 *
3926 * That is, even though "use\x20loose" can never be a directive, now or in the
3927 * future (because of the hex escape), the Directive Prologue extends through it
3928 * to the "use strict" statement, which is indeed a directive.
3929 */
3930template <class ParseHandler, typename Unit>
3931bool GeneralParser<ParseHandler, Unit>::maybeParseDirective(
3932 ListNodeType list, Node possibleDirective, bool* cont) {
3933 TokenPos directivePos;
3934 TaggedParserAtomIndex directive =
3935 handler_.isStringExprStatement(possibleDirective, &directivePos);
3936
3937 *cont = !!directive;
3938 if (!*cont) {
3939 return true;
3940 }
3941
3942 if (IsUseStrictDirective(directivePos, directive)) {
3943 // Functions with non-simple parameter lists (destructuring,
3944 // default or rest parameters) must not contain a "use strict"
3945 // directive.
3946 if (pc_->isFunctionBox()) {
3947 FunctionBox* funbox = pc_->functionBox();
3948 if (!funbox->hasSimpleParameterList()) {
3949 const char* parameterKind = funbox->hasDestructuringArgs
3950 ? "destructuring"
3951 : funbox->hasParameterExprs ? "default"
3952 : "rest";
3953 errorAt(directivePos.begin, JSMSG_STRICT_NON_SIMPLE_PARAMS,
3954 parameterKind);
3955 return false;
3956 }
3957 }
3958
3959 // We're going to be in strict mode. Note that this scope explicitly
3960 // had "use strict";
3961 pc_->sc()->setExplicitUseStrict();
3962 if (!pc_->sc()->strict()) {
3963 // Some strict mode violations can appear before a Use Strict Directive
3964 // is applied. (See the |DeprecatedContent| enum initializers.) These
3965 // violations can manifest in two ways.
3966 //
3967 // First, the violation can appear *before* the Use Strict Directive.
3968 // Numeric literals (and therefore octal literals) can only precede a
3969 // Use Strict Directive if this function's parameter list is not simple,
3970 // but we reported an error for non-simple parameter lists above, so
3971 // octal literals present no issue. But octal escapes and \8 and \9 can
3972 // appear in the directive prologue before a Use Strict Directive:
3973 //
3974 // function f()
3975 // {
3976 // "hell\157 world"; // octal escape
3977 // "\8"; "\9"; // NonOctalDecimalEscape
3978 // "use strict"; // retroactively makes all the above errors
3979 // }
3980 //
3981 // Second, the violation can appear *after* the Use Strict Directive but
3982 // *before* the directive is recognized as terminated. This only
3983 // happens when a directive is terminated by ASI, and the next token
3984 // contains a violation:
3985 //
3986 // function a()
3987 // {
3988 // "use strict" // ASI
3989 // 0755;
3990 // }
3991 // function b()
3992 // {
3993 // "use strict" // ASI
3994 // "hell\157 world";
3995 // }
3996 // function c()
3997 // {
3998 // "use strict" // ASI
3999 // "\8";
4000 // }
4001 //
4002 // We note such violations when tokenizing. Then, if a violation has
4003 // been observed at the time a "use strict" is applied, we report the
4004 // error.
4005 switch (anyChars.sawDeprecatedContent()) {
4006 case DeprecatedContent::None:
4007 break;
4008 case DeprecatedContent::OctalLiteral:
4009 error(JSMSG_DEPRECATED_OCTAL_LITERAL);
4010 return false;
4011 case DeprecatedContent::OctalEscape:
4012 error(JSMSG_DEPRECATED_OCTAL_ESCAPE);
4013 return false;
4014 case DeprecatedContent::EightOrNineEscape:
4015 error(JSMSG_DEPRECATED_EIGHT_OR_NINE_ESCAPE);
4016 return false;
4017 }
4018
4019 pc_->sc()->setStrictScript();
4020 }
4021 } else if (IsUseAsmDirective(directivePos, directive)) {
4022 if (pc_->isFunctionBox()) {
4023 return asmJS(list);
4024 }
4025 return warningAt(directivePos.begin, JSMSG_USE_ASM_DIRECTIVE_FAIL);
4026 }
4027 return true;
4028}
4029
4030template <class ParseHandler, typename Unit>
4031typename ParseHandler::ListNodeResult
4032GeneralParser<ParseHandler, Unit>::statementList(YieldHandling yieldHandling) {
4033 AutoCheckRecursionLimit recursion(this->fc_);
4034 if (!recursion.check(this->fc_)) {
4035 return errorResult();
4036 }
4037
4038 ListNodeType stmtList;
4039 MOZ_TRY_VAR(stmtList, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
4040
4041 bool canHaveDirectives = pc_->atBodyLevel();
4042 if (canHaveDirectives) {
4043 // Clear flags for deprecated content that might have been seen in an
4044 // enclosing context.
4045 anyChars.clearSawDeprecatedContent();
4046 }
4047
4048 bool canHaveHashbangComment = pc_->atTopLevel();
4049 if (canHaveHashbangComment) {
4050 tokenStream.consumeOptionalHashbangComment();
4051 }
4052
4053 bool afterReturn = false;
4054 bool warnedAboutStatementsAfterReturn = false;
4055 uint32_t statementBegin = 0;
4056 for (;;) {
4057 TokenKind tt = TokenKind::Eof;
4058 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
4059 if (anyChars.isEOF()) {
4060 isUnexpectedEOF_ = true;
4061 }
4062 return errorResult();
4063 }
4064 if (tt == TokenKind::Eof || tt == TokenKind::RightCurly) {
4065 TokenPos pos;
4066 if (!tokenStream.peekTokenPos(&pos, TokenStream::SlashIsRegExp)) {
4067 return errorResult();
4068 }
4069 handler_.setListEndPosition(stmtList, pos);
4070 break;
4071 }
4072 if (afterReturn) {
4073 if (!tokenStream.peekOffset(&statementBegin,
4074 TokenStream::SlashIsRegExp)) {
4075 return errorResult();
4076 }
4077 }
4078 auto nextResult = statementListItem(yieldHandling, canHaveDirectives);
4079 if (nextResult.isErr()) {
4080 if (anyChars.isEOF()) {
4081 isUnexpectedEOF_ = true;
4082 }
4083 return errorResult();
4084 }
4085 Node next = nextResult.unwrap();
4086 if (!warnedAboutStatementsAfterReturn) {
4087 if (afterReturn) {
4088 if (!handler_.isStatementPermittedAfterReturnStatement(next)) {
4089 if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
4090 return errorResult();
4091 }
4092
4093 warnedAboutStatementsAfterReturn = true;
4094 }
4095 } else if (handler_.isReturnStatement(next)) {
4096 afterReturn = true;
4097 }
4098 }
4099
4100 if (canHaveDirectives) {
4101 if (!maybeParseDirective(stmtList, next, &canHaveDirectives)) {
4102 return errorResult();
4103 }
4104 }
4105
4106 handler_.addStatementToList(stmtList, next);
4107 }
4108
4109 return stmtList;
4110}
4111
4112template <class ParseHandler, typename Unit>
4113typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::condition(
4114 InHandling inHandling, YieldHandling yieldHandling) {
4115 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_COND)) {
4116 return errorResult();
4117 }
4118
4119 Node pn;
4120 MOZ_TRY_VAR(pn, exprInParens(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (exprInParens(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (pn) = mozTryVarTempResult_.unwrap(); } while (0)
;
4121
4122 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_COND)) {
4123 return errorResult();
4124 }
4125
4126 return pn;
4127}
4128
4129template <class ParseHandler, typename Unit>
4130bool GeneralParser<ParseHandler, Unit>::matchLabel(
4131 YieldHandling yieldHandling, TaggedParserAtomIndex* labelOut) {
4132 MOZ_ASSERT(labelOut != nullptr)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(labelOut != nullptr)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(labelOut != nullptr))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("labelOut != nullptr"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4132); AnnotateMozCrashReason("MOZ_ASSERT" "(" "labelOut != nullptr"
")"); do { *((volatile int*)__null) = 4132; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4133 TokenKind tt = TokenKind::Eof;
4134 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
4135 return false;
4136 }
4137
4138 if (TokenKindIsPossibleIdentifier(tt)) {
4139 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
4140
4141 *labelOut = labelIdentifier(yieldHandling);
4142 if (!*labelOut) {
4143 return false;
4144 }
4145 } else {
4146 *labelOut = TaggedParserAtomIndex::null();
4147 }
4148 return true;
4149}
4150
4151template <class ParseHandler, typename Unit>
4152GeneralParser<ParseHandler, Unit>::PossibleError::PossibleError(
4153 GeneralParser<ParseHandler, Unit>& parser)
4154 : parser_(parser) {}
4155
4156template <class ParseHandler, typename Unit>
4157typename GeneralParser<ParseHandler, Unit>::PossibleError::Error&
4158GeneralParser<ParseHandler, Unit>::PossibleError::error(ErrorKind kind) {
4159 if (kind == ErrorKind::Expression) {
4160 return exprError_;
4161 }
4162 if (kind == ErrorKind::Destructuring) {
4163 return destructuringError_;
4164 }
4165 MOZ_ASSERT(kind == ErrorKind::DestructuringWarning)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ErrorKind::DestructuringWarning)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(kind == ErrorKind::DestructuringWarning))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("kind == ErrorKind::DestructuringWarning"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4165); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ErrorKind::DestructuringWarning"
")"); do { *((volatile int*)__null) = 4165; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4166 return destructuringWarning_;
4167}
4168
4169template <class ParseHandler, typename Unit>
4170void GeneralParser<ParseHandler, Unit>::PossibleError::setResolved(
4171 ErrorKind kind) {
4172 error(kind).state_ = ErrorState::None;
4173}
4174
4175template <class ParseHandler, typename Unit>
4176bool GeneralParser<ParseHandler, Unit>::PossibleError::hasError(
4177 ErrorKind kind) {
4178 return error(kind).state_ == ErrorState::Pending;
4179}
4180
4181template <class ParseHandler, typename Unit>
4182bool GeneralParser<ParseHandler,
4183 Unit>::PossibleError::hasPendingDestructuringError() {
4184 return hasError(ErrorKind::Destructuring);
4185}
4186
4187template <class ParseHandler, typename Unit>
4188void GeneralParser<ParseHandler, Unit>::PossibleError::setPending(
4189 ErrorKind kind, const TokenPos& pos, unsigned errorNumber) {
4190 // Don't overwrite a previously recorded error.
4191 if (hasError(kind)) {
4192 return;
4193 }
4194
4195 // If we report an error later, we'll do it from the position where we set
4196 // the state to pending.
4197 Error& err = error(kind);
4198 err.offset_ = pos.begin;
4199 err.errorNumber_ = errorNumber;
4200 err.state_ = ErrorState::Pending;
4201}
4202
4203template <class ParseHandler, typename Unit>
4204void GeneralParser<ParseHandler, Unit>::PossibleError::
4205 setPendingDestructuringErrorAt(const TokenPos& pos, unsigned errorNumber) {
4206 setPending(ErrorKind::Destructuring, pos, errorNumber);
4207}
4208
4209template <class ParseHandler, typename Unit>
4210void GeneralParser<ParseHandler, Unit>::PossibleError::
4211 setPendingDestructuringWarningAt(const TokenPos& pos,
4212 unsigned errorNumber) {
4213 setPending(ErrorKind::DestructuringWarning, pos, errorNumber);
4214}
4215
4216template <class ParseHandler, typename Unit>
4217void GeneralParser<ParseHandler, Unit>::PossibleError::
4218 setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber) {
4219 setPending(ErrorKind::Expression, pos, errorNumber);
4220}
4221
4222template <class ParseHandler, typename Unit>
4223bool GeneralParser<ParseHandler, Unit>::PossibleError::checkForError(
4224 ErrorKind kind) {
4225 if (!hasError(kind)) {
4226 return true;
4227 }
4228
4229 Error& err = error(kind);
4230 parser_.errorAt(err.offset_, err.errorNumber_);
4231 return false;
4232}
4233
4234template <class ParseHandler, typename Unit>
4235bool GeneralParser<ParseHandler,
4236 Unit>::PossibleError::checkForDestructuringErrorOrWarning() {
4237 // Clear pending expression error, because we're definitely not in an
4238 // expression context.
4239 setResolved(ErrorKind::Expression);
4240
4241 // Report any pending destructuring error.
4242 return checkForError(ErrorKind::Destructuring);
4243}
4244
4245template <class ParseHandler, typename Unit>
4246bool GeneralParser<ParseHandler,
4247 Unit>::PossibleError::checkForExpressionError() {
4248 // Clear pending destructuring error, because we're definitely not
4249 // in a destructuring context.
4250 setResolved(ErrorKind::Destructuring);
4251 setResolved(ErrorKind::DestructuringWarning);
4252
4253 // Report any pending expression error.
4254 return checkForError(ErrorKind::Expression);
4255}
4256
4257template <class ParseHandler, typename Unit>
4258void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorTo(
4259 ErrorKind kind, PossibleError* other) {
4260 if (hasError(kind) && !other->hasError(kind)) {
4261 Error& err = error(kind);
4262 Error& otherErr = other->error(kind);
4263 otherErr.offset_ = err.offset_;
4264 otherErr.errorNumber_ = err.errorNumber_;
4265 otherErr.state_ = err.state_;
4266 }
4267}
4268
4269template <class ParseHandler, typename Unit>
4270void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorsTo(
4271 PossibleError* other) {
4272 MOZ_ASSERT(other)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(other)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(other))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("other", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4272); AnnotateMozCrashReason("MOZ_ASSERT" "(" "other" ")")
; do { *((volatile int*)__null) = 4272; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4273 MOZ_ASSERT(this != other)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(this != other)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(this != other))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("this != other",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4273); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this != other"
")"); do { *((volatile int*)__null) = 4273; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4274 MOZ_ASSERT(&parser_ == &other->parser_,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(&parser_ == &other->parser_)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(&parser_ == &other->parser_))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("&parser_ == &other->parser_"
" (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4276
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
4275 "Can't transfer fields to an instance which belongs to a "do { static_assert( mozilla::detail::AssertionConditionType<
decltype(&parser_ == &other->parser_)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(&parser_ == &other->parser_))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("&parser_ == &other->parser_"
" (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4276
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
4276 "different parser")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(&parser_ == &other->parser_)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(&parser_ == &other->parser_))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("&parser_ == &other->parser_"
" (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4276); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4276
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
4277
4278 transferErrorTo(ErrorKind::Destructuring, other);
4279 transferErrorTo(ErrorKind::Expression, other);
4280}
4281
4282template <class ParseHandler, typename Unit>
4283typename ParseHandler::BinaryNodeResult
4284GeneralParser<ParseHandler, Unit>::bindingInitializer(
4285 Node lhs, DeclarationKind kind, YieldHandling yieldHandling) {
4286 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assign))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Assign)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Assign)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4286); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assign)"
")"); do { *((volatile int*)__null) = 4286; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4287
4288 if (kind == DeclarationKind::FormalParameter) {
4289 pc_->functionBox()->hasParameterExprs = true;
4290 }
4291
4292 Node rhs;
4293 MOZ_TRY_VAR(rhs, assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
4294
4295 BinaryNodeType assign;
4296 MOZ_TRY_VAR(assign,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assign) = mozTryVarTempResult_.unwrap(); } while (0)
4297 handler_.newAssignment(ParseNodeKind::AssignExpr, lhs, rhs))do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assign) = mozTryVarTempResult_.unwrap(); } while (0)
;
4298
4299 return assign;
4300}
4301
4302template <class ParseHandler, typename Unit>
4303typename ParseHandler::NameNodeResult
4304GeneralParser<ParseHandler, Unit>::bindingIdentifier(
4305 DeclarationKind kind, YieldHandling yieldHandling) {
4306 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
4307 if (!name) {
4308 return errorResult();
4309 }
4310
4311 NameNodeType binding;
4312 MOZ_TRY_VAR(binding, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (binding) = mozTryVarTempResult_.unwrap();
} while (0)
;
4313 if (!noteDeclaredName(name, kind, pos())) {
4314 return errorResult();
4315 }
4316
4317 return binding;
4318}
4319
4320template <class ParseHandler, typename Unit>
4321typename ParseHandler::NodeResult
4322GeneralParser<ParseHandler, Unit>::bindingIdentifierOrPattern(
4323 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4324 if (tt == TokenKind::LeftBracket) {
4325 return arrayBindingPattern(kind, yieldHandling);
4326 }
4327
4328 if (tt == TokenKind::LeftCurly) {
4329 return objectBindingPattern(kind, yieldHandling);
4330 }
4331
4332 if (!TokenKindIsPossibleIdentifierName(tt)) {
4333 error(JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
4334 return errorResult();
4335 }
4336
4337 return bindingIdentifier(kind, yieldHandling);
4338}
4339
4340template <class ParseHandler, typename Unit>
4341typename ParseHandler::ListNodeResult
4342GeneralParser<ParseHandler, Unit>::objectBindingPattern(
4343 DeclarationKind kind, YieldHandling yieldHandling) {
4344 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4344); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4344; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4345
4346 AutoCheckRecursionLimit recursion(this->fc_);
4347 if (!recursion.check(this->fc_)) {
4348 return errorResult();
4349 }
4350
4351 uint32_t begin = pos().begin;
4352 ListNodeType literal;
4353 MOZ_TRY_VAR(literal, handler_.newObjectLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newObjectLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4354
4355 Maybe<DeclarationKind> declKind = Some(kind);
4356 TaggedParserAtomIndex propAtom;
4357 for (;;) {
4358 TokenKind tt;
4359 if (!tokenStream.peekToken(&tt)) {
4360 return errorResult();
4361 }
4362 if (tt == TokenKind::RightCurly) {
4363 break;
4364 }
4365
4366 if (tt == TokenKind::TripleDot) {
4367 tokenStream.consumeKnownToken(TokenKind::TripleDot);
4368 uint32_t begin = pos().begin;
4369
4370 TokenKind tt;
4371 if (!tokenStream.getToken(&tt)) {
4372 return errorResult();
4373 }
4374
4375 if (!TokenKindIsPossibleIdentifierName(tt)) {
4376 error(JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
4377 return errorResult();
4378 }
4379
4380 NameNodeType inner;
4381 MOZ_TRY_VAR(inner, bindingIdentifier(kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(kind, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (inner) =
mozTryVarTempResult_.unwrap(); } while (0)
;
4382
4383 if (!handler_.addSpreadProperty(literal, begin, inner)) {
4384 return errorResult();
4385 }
4386 } else {
4387 TokenPos namePos = anyChars.nextToken().pos;
4388
4389 PropertyType propType;
4390 Node propName;
4391 MOZ_TRY_VAR(propName, propertyOrMethodName(do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInPattern, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
4392 yieldHandling, PropertyNameInPattern, declKind,do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInPattern, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
4393 literal, &propType, &propAtom))do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInPattern, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
4394
4395 if (propType == PropertyType::Normal) {
4396 // Handle e.g., |var {p: x} = o| and |var {p: x=0} = o|.
4397
4398 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
4399 return errorResult();
4400 }
4401
4402 Node binding;
4403 MOZ_TRY_VAR(binding,do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (binding) = mozTryVarTempResult_.unwrap(); } while (0)
4404 bindingIdentifierOrPattern(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (binding) = mozTryVarTempResult_.unwrap(); } while (0)
;
4405
4406 bool hasInitializer;
4407 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
4408 TokenStream::SlashIsRegExp)) {
4409 return errorResult();
4410 }
4411
4412 Node bindingExpr;
4413 if (hasInitializer) {
4414 MOZ_TRY_VAR(bindingExpr,do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
4415 bindingInitializer(binding, kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
4416 } else {
4417 bindingExpr = binding;
4418 }
4419
4420 if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
4421 return errorResult();
4422 }
4423 } else if (propType == PropertyType::Shorthand) {
4424 // Handle e.g., |var {x, y} = o| as destructuring shorthand
4425 // for |var {x: x, y: y} = o|.
4426 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(tt))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(TokenKindIsPossibleIdentifierName(tt)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifierName(tt)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4426); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(tt)"
")"); do { *((volatile int*)__null) = 4426; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4427
4428 NameNodeType binding;
4429 MOZ_TRY_VAR(binding, bindingIdentifier(kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(kind, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4430
4431 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
4432 binding)) {
4433 return errorResult();
4434 }
4435 } else if (propType == PropertyType::CoverInitializedName) {
4436 // Handle e.g., |var {x=1, y=2} = o| as destructuring
4437 // shorthand with default values.
4438 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(tt))>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(TokenKindIsPossibleIdentifierName(tt)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifierName(tt)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4438); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(tt)"
")"); do { *((volatile int*)__null) = 4438; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4439
4440 NameNodeType binding;
4441 MOZ_TRY_VAR(binding, bindingIdentifier(kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(kind, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4442
4443 tokenStream.consumeKnownToken(TokenKind::Assign);
4444
4445 BinaryNodeType bindingExpr;
4446 MOZ_TRY_VAR(bindingExpr,do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
4447 bindingInitializer(binding, kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (bindingExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
4448
4449 if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
4450 return errorResult();
4451 }
4452 } else {
4453 errorAt(namePos.begin, JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
4454 return errorResult();
4455 }
4456 }
4457
4458 bool matched;
4459 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
4460 TokenStream::SlashIsInvalid)) {
4461 return errorResult();
4462 }
4463 if (!matched) {
4464 break;
4465 }
4466 if (tt == TokenKind::TripleDot) {
4467 error(JSMSG_REST_WITH_COMMA);
4468 return errorResult();
4469 }
4470 }
4471
4472 if (!mustMatchToken(TokenKind::RightCurly, [this, begin](TokenKind actual) {
4473 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST, JSMSG_CURLY_OPENED,
4474 begin);
4475 })) {
4476 return errorResult();
4477 }
4478
4479 handler_.setEndPosition(literal, pos().end);
4480 return literal;
4481}
4482
4483template <class ParseHandler, typename Unit>
4484typename ParseHandler::ListNodeResult
4485GeneralParser<ParseHandler, Unit>::arrayBindingPattern(
4486 DeclarationKind kind, YieldHandling yieldHandling) {
4487 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4487); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 4487; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4488
4489 AutoCheckRecursionLimit recursion(this->fc_);
4490 if (!recursion.check(this->fc_)) {
4491 return errorResult();
4492 }
4493
4494 uint32_t begin = pos().begin;
4495 ListNodeType literal;
4496 MOZ_TRY_VAR(literal, handler_.newArrayLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newArrayLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4497
4498 uint32_t index = 0;
4499 for (;; index++) {
4500 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
4501 error(JSMSG_ARRAY_INIT_TOO_BIG);
4502 return errorResult();
4503 }
4504
4505 TokenKind tt;
4506 if (!tokenStream.getToken(&tt)) {
4507 return errorResult();
4508 }
4509
4510 if (tt == TokenKind::RightBracket) {
4511 anyChars.ungetToken();
4512 break;
4513 }
4514
4515 if (tt == TokenKind::Comma) {
4516 if (!handler_.addElision(literal, pos())) {
4517 return errorResult();
4518 }
4519 } else if (tt == TokenKind::TripleDot) {
4520 uint32_t begin = pos().begin;
4521
4522 TokenKind tt;
4523 if (!tokenStream.getToken(&tt)) {
4524 return errorResult();
4525 }
4526
4527 Node inner;
4528 MOZ_TRY_VAR(inner, bindingIdentifierOrPattern(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
;
4529
4530 if (!handler_.addSpreadElement(literal, begin, inner)) {
4531 return errorResult();
4532 }
4533 } else {
4534 Node binding;
4535 MOZ_TRY_VAR(binding, bindingIdentifierOrPattern(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (bindingIdentifierOrPattern(
kind, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (binding) = mozTryVarTempResult_.unwrap(); } while (0)
;
4536
4537 bool hasInitializer;
4538 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
4539 TokenStream::SlashIsRegExp)) {
4540 return errorResult();
4541 }
4542
4543 Node element;
4544 if (hasInitializer) {
4545 MOZ_TRY_VAR(element, bindingInitializer(binding, kind, yieldHandling))do { auto mozTryVarTempResult_ = (bindingInitializer(binding,
kind, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (element) = mozTryVarTempResult_.unwrap(); } while (0)
;
4546 } else {
4547 element = binding;
4548 }
4549
4550 handler_.addArrayElement(literal, element);
4551 }
4552
4553 if (tt != TokenKind::Comma) {
4554 // If we didn't already match TokenKind::Comma in above case.
4555 bool matched;
4556 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
4557 TokenStream::SlashIsRegExp)) {
4558 return errorResult();
4559 }
4560 if (!matched) {
4561 break;
4562 }
4563
4564 if (tt == TokenKind::TripleDot) {
4565 error(JSMSG_REST_WITH_COMMA);
4566 return errorResult();
4567 }
4568 }
4569 }
4570
4571 if (!mustMatchToken(TokenKind::RightBracket, [this, begin](TokenKind actual) {
4572 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
4573 JSMSG_BRACKET_OPENED, begin);
4574 })) {
4575 return errorResult();
4576 }
4577
4578 handler_.setEndPosition(literal, pos().end);
4579 return literal;
4580}
4581
4582template <class ParseHandler, typename Unit>
4583typename ParseHandler::NodeResult
4584GeneralParser<ParseHandler, Unit>::destructuringDeclaration(
4585 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4586 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4586); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 4586; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4587 MOZ_ASSERT(tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly",
"/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4587); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly"
")"); do { *((volatile int*)__null) = 4587; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4588
4589 if (tt == TokenKind::LeftBracket) {
4590 return arrayBindingPattern(kind, yieldHandling);
4591 }
4592 return objectBindingPattern(kind, yieldHandling);
4593}
4594
4595template <class ParseHandler, typename Unit>
4596typename ParseHandler::NodeResult
4597GeneralParser<ParseHandler, Unit>::destructuringDeclarationWithoutYieldOrAwait(
4598 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4599 uint32_t startYieldOffset = pc_->lastYieldOffset;
4600 uint32_t startAwaitOffset = pc_->lastAwaitOffset;
4601
4602 Node res;
4603 MOZ_TRY_VAR(res, destructuringDeclaration(kind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (destructuringDeclaration(kind
, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (res) = mozTryVarTempResult_.unwrap(); } while (0)
;
4604
4605 if (pc_->lastYieldOffset != startYieldOffset) {
4606 errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
4607 return errorResult();
4608 }
4609 if (pc_->lastAwaitOffset != startAwaitOffset) {
4610 errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
4611 return errorResult();
4612 }
4613 return res;
4614}
4615
4616template <class ParseHandler, typename Unit>
4617typename ParseHandler::LexicalScopeNodeResult
4618GeneralParser<ParseHandler, Unit>::blockStatement(YieldHandling yieldHandling,
4619 unsigned errorNumber) {
4620 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4620); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4620; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4621 uint32_t openedPos = pos().begin;
4622
4623 ParseContext::Statement stmt(pc_, StatementKind::Block);
4624 ParseContext::Scope scope(this);
4625 if (!scope.init(pc_)) {
4626 return errorResult();
4627 }
4628
4629 ListNodeType list;
4630 MOZ_TRY_VAR(list, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (list) = mozTryVarTempResult_
.unwrap(); } while (0)
;
4631
4632 if (!mustMatchToken(TokenKind::RightCurly, [this, errorNumber,
4633 openedPos](TokenKind actual) {
4634 this->reportMissingClosing(errorNumber, JSMSG_CURLY_OPENED, openedPos);
4635 })) {
4636 return errorResult();
4637 }
4638
4639 return finishLexicalScope(scope, list);
4640}
4641
4642template <class ParseHandler, typename Unit>
4643typename ParseHandler::NodeResult
4644GeneralParser<ParseHandler, Unit>::expressionAfterForInOrOf(
4645 ParseNodeKind forHeadKind, YieldHandling yieldHandling) {
4646 MOZ_ASSERT(forHeadKind == ParseNodeKind::ForIn ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(forHeadKind == ParseNodeKind::ForIn || forHeadKind ==
ParseNodeKind::ForOf)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(forHeadKind == ParseNodeKind
::ForIn || forHeadKind == ParseNodeKind::ForOf))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4647); AnnotateMozCrashReason("MOZ_ASSERT" "(" "forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 4647; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4647 forHeadKind == ParseNodeKind::ForOf)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(forHeadKind == ParseNodeKind::ForIn || forHeadKind ==
ParseNodeKind::ForOf)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(forHeadKind == ParseNodeKind
::ForIn || forHeadKind == ParseNodeKind::ForOf))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4647); AnnotateMozCrashReason("MOZ_ASSERT" "(" "forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 4647; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4648 if (forHeadKind == ParseNodeKind::ForOf) {
4649 return assignExpr(InAllowed, yieldHandling, TripledotProhibited);
4650 }
4651
4652 return expr(InAllowed, yieldHandling, TripledotProhibited);
4653}
4654
4655template <class ParseHandler, typename Unit>
4656typename ParseHandler::NodeResult
4657GeneralParser<ParseHandler, Unit>::declarationPattern(
4658 DeclarationKind declKind, TokenKind tt, bool initialDeclaration,
4659 YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
4660 Node* forInOrOfExpression) {
4661 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket) ||
anyChars.isCurrentTokenType(TokenKind::LeftCurly))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars
.isCurrentTokenType(TokenKind::LeftCurly)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4662); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4662; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4662 anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket) ||
anyChars.isCurrentTokenType(TokenKind::LeftCurly))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars
.isCurrentTokenType(TokenKind::LeftCurly)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4662); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4662; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4663
4664 Node pattern;
4665 MOZ_TRY_VAR(pattern, destructuringDeclaration(declKind, yieldHandling, tt))do { auto mozTryVarTempResult_ = (destructuringDeclaration(declKind
, yieldHandling, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (pattern) = mozTryVarTempResult_.unwrap(); } while (0)
;
4666
4667 if (initialDeclaration && forHeadKind) {
4668 bool isForIn, isForOf;
4669 if (!matchInOrOf(&isForIn, &isForOf)) {
4670 return errorResult();
4671 }
4672
4673 if (isForIn) {
4674 *forHeadKind = ParseNodeKind::ForIn;
4675 } else if (isForOf) {
4676 *forHeadKind = ParseNodeKind::ForOf;
4677 } else {
4678 *forHeadKind = ParseNodeKind::ForHead;
4679 }
4680
4681 if (*forHeadKind != ParseNodeKind::ForHead) {
4682 MOZ_TRY_VAR(*forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4683 expressionAfterForInOrOf(*forHeadKind, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4684
4685 return pattern;
4686 }
4687 }
4688
4689 if (!mustMatchToken(TokenKind::Assign, JSMSG_BAD_DESTRUCT_DECL)) {
4690 return errorResult();
4691 }
4692
4693 Node init;
4694 MOZ_TRY_VAR(init, assignExpr(forHeadKind ? InProhibited : InAllowed,do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (init) = mozTryVarTempResult_.unwrap(); } while
(0)
4695 yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (init) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4696
4697 return handler_.newAssignment(ParseNodeKind::AssignExpr, pattern, init);
4698}
4699
4700template <class ParseHandler, typename Unit>
4701typename ParseHandler::AssignmentNodeResult
4702GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
4703 NameNodeType binding, DeclarationKind declKind, bool initialDeclaration,
4704 YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
4705 Node* forInOrOfExpression) {
4706 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assign))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assign))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Assign)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Assign)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4706); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assign)"
")"); do { *((volatile int*)__null) = 4706; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4707
4708 uint32_t initializerOffset;
4709 if (!tokenStream.peekOffset(&initializerOffset, TokenStream::SlashIsRegExp)) {
4710 return errorResult();
4711 }
4712
4713 Node initializer;
4714 MOZ_TRY_VAR(initializer, assignExpr(forHeadKind ? InProhibited : InAllowed,do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializer) = mozTryVarTempResult_.unwrap
(); } while (0)
4715 yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(forHeadKind ? InProhibited
: InAllowed, yieldHandling, TripledotProhibited)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializer) = mozTryVarTempResult_.unwrap
(); } while (0)
;
4716
4717 if (forHeadKind && initialDeclaration) {
4718 bool isForIn, isForOf;
4719 if (!matchInOrOf(&isForIn, &isForOf)) {
4720 return errorResult();
4721 }
4722
4723 // An initialized declaration can't appear in a for-of:
4724 //
4725 // for (var/let/const x = ... of ...); // BAD
4726 if (isForOf) {
4727 errorAt(initializerOffset, JSMSG_OF_AFTER_FOR_LOOP_DECL);
4728 return errorResult();
4729 }
4730
4731 if (isForIn) {
4732 // Lexical declarations in for-in loops can't be initialized:
4733 //
4734 // for (let/const x = ... in ...); // BAD
4735 if (DeclarationKindIsLexical(declKind)) {
4736 errorAt(initializerOffset, JSMSG_IN_AFTER_LEXICAL_FOR_DECL);
4737 return errorResult();
4738 }
4739
4740 // This leaves only initialized for-in |var| declarations. ES6
4741 // forbids these; later ES un-forbids in non-strict mode code.
4742 *forHeadKind = ParseNodeKind::ForIn;
4743 if (!strictModeErrorAt(initializerOffset,
4744 JSMSG_INVALID_FOR_IN_DECL_WITH_INIT)) {
4745 return errorResult();
4746 }
4747
4748 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4749 *forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4750 expressionAfterForInOrOf(ParseNodeKind::ForIn, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4751 } else {
4752 *forHeadKind = ParseNodeKind::ForHead;
4753 }
4754 }
4755
4756 return handler_.finishInitializerAssignment(binding, initializer);
4757}
4758
4759template <class ParseHandler, typename Unit>
4760typename ParseHandler::NodeResult
4761GeneralParser<ParseHandler, Unit>::declarationName(DeclarationKind declKind,
4762 TokenKind tt,
4763 bool initialDeclaration,
4764 YieldHandling yieldHandling,
4765 ParseNodeKind* forHeadKind,
4766 Node* forInOrOfExpression) {
4767 // Anything other than possible identifier is an error.
4768 if (!TokenKindIsPossibleIdentifier(tt)) {
4769 error(JSMSG_NO_VARIABLE_NAME, TokenKindToDesc(tt));
4770 return errorResult();
4771 }
4772
4773 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
4774 if (!name) {
4775 return errorResult();
4776 }
4777
4778 NameNodeType binding;
4779 MOZ_TRY_VAR(binding, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (binding) = mozTryVarTempResult_.unwrap();
} while (0)
;
4780
4781 TokenPos namePos = pos();
4782
4783 // The '=' context after a variable name in a declaration is an opportunity
4784 // for ASI, and thus for the next token to start an ExpressionStatement:
4785 //
4786 // var foo // VariableDeclaration
4787 // /bar/g; // ExpressionStatement
4788 //
4789 // Therefore get the token here with SlashIsRegExp.
4790 bool matched;
4791 if (!tokenStream.matchToken(&matched, TokenKind::Assign,
4792 TokenStream::SlashIsRegExp)) {
4793 return errorResult();
4794 }
4795
4796 Node declaration;
4797 if (matched) {
4798 MOZ_TRY_VAR(declaration,do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
4799 initializerInNameDeclaration(binding, declKind,do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
4800 initialDeclaration, yieldHandling,do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
4801 forHeadKind, forInOrOfExpression))do { auto mozTryVarTempResult_ = (initializerInNameDeclaration
(binding, declKind, initialDeclaration, yieldHandling, forHeadKind
, forInOrOfExpression)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (declaration) = mozTryVarTempResult_.unwrap(); } while (0)
;
4802 } else {
4803 declaration = binding;
4804
4805 if (initialDeclaration && forHeadKind) {
4806 bool isForIn, isForOf;
4807 if (!matchInOrOf(&isForIn, &isForOf)) {
4808 return errorResult();
4809 }
4810
4811 if (isForIn) {
4812 *forHeadKind = ParseNodeKind::ForIn;
4813#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
4814 if (declKind == DeclarationKind::Using ||
4815 declKind == DeclarationKind::AwaitUsing) {
4816 errorAt(namePos.begin, JSMSG_NO_IN_WITH_USING);
4817 return errorResult();
4818 }
4819#endif
4820 } else if (isForOf) {
4821 *forHeadKind = ParseNodeKind::ForOf;
4822 } else {
4823 *forHeadKind = ParseNodeKind::ForHead;
4824 }
4825 }
4826
4827 if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
4828 MOZ_TRY_VAR(*forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4829 expressionAfterForInOrOf(*forHeadKind, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4830 } else {
4831 // Normal const declarations, and const declarations in for(;;)
4832 // heads, must be initialized.
4833 if (declKind == DeclarationKind::Const) {
4834 errorAt(namePos.begin, JSMSG_BAD_CONST_DECL);
4835 return errorResult();
4836 }
4837#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
4838 if (declKind == DeclarationKind::Using ||
4839 declKind == DeclarationKind::AwaitUsing) {
4840 errorAt(namePos.begin, JSMSG_BAD_USING_DECL);
4841 return errorResult();
4842 }
4843#endif
4844 }
4845 }
4846
4847 // Note the declared name after knowing whether or not we are in a for-of
4848 // loop, due to special early error semantics in Annex B.3.5.
4849 if (!noteDeclaredName(name, declKind, namePos)) {
4850 return errorResult();
4851 }
4852
4853 return declaration;
4854}
4855
4856template <class ParseHandler, typename Unit>
4857typename ParseHandler::DeclarationListNodeResult
4858GeneralParser<ParseHandler, Unit>::declarationList(
4859 YieldHandling yieldHandling, ParseNodeKind kind,
4860 ParseNodeKind* forHeadKind /* = nullptr */,
4861 Node* forInOrOfExpression /* = nullptr */) {
4862 MOZ_ASSERT(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4863 kind == ParseNodeKind::ConstDecldo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4864#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENTdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4865 || kind == ParseNodeKind::UsingDecl ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4866 kind == ParseNodeKind::AwaitUsingDecldo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4867#endifdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4868 )do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl ifdef 1 || kind
== ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDecl
endif))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4868); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDeclifdef 1 || kind == ParseNodeKind::UsingDecl || kind == ParseNodeKind::AwaitUsingDeclendif"
")"); do { *((volatile int*)__null) = 4868; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4869
4870 DeclarationKind declKind;
4871 switch (kind) {
4872 case ParseNodeKind::VarStmt:
4873 declKind = DeclarationKind::Var;
4874 break;
4875 case ParseNodeKind::ConstDecl:
4876 declKind = DeclarationKind::Const;
4877 break;
4878 case ParseNodeKind::LetDecl:
4879 declKind = DeclarationKind::Let;
4880 break;
4881#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
4882 case ParseNodeKind::UsingDecl:
4883 declKind = DeclarationKind::Using;
4884 break;
4885 case ParseNodeKind::AwaitUsingDecl:
4886 declKind = DeclarationKind::AwaitUsing;
4887 break;
4888#endif
4889 default:
4890 MOZ_CRASH("Unknown declaration kind")do { do { } while (false); MOZ_ReportCrash("" "Unknown declaration kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4890); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown declaration kind"
")"); do { *((volatile int*)__null) = 4890; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4891 }
4892
4893 DeclarationListNodeType decl;
4894 MOZ_TRY_VAR(decl, handler_.newDeclarationList(kind, pos()))do { auto mozTryVarTempResult_ = (handler_.newDeclarationList
(kind, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decl) = mozTryVarTempResult_.unwrap(); } while (0)
;
4895
4896 bool moreDeclarations;
4897 bool initialDeclaration = true;
4898 do {
4899 MOZ_ASSERT_IF(!initialDeclaration && forHeadKind,do { if (!initialDeclaration && forHeadKind) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(*forHeadKind
== ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*forHeadKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("*forHeadKind == ParseNodeKind::ForHead", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*forHeadKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 4900; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
4900 *forHeadKind == ParseNodeKind::ForHead)do { if (!initialDeclaration && forHeadKind) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(*forHeadKind
== ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(*forHeadKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("*forHeadKind == ParseNodeKind::ForHead", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4900); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*forHeadKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 4900; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4901
4902 TokenKind tt;
4903 if (!tokenStream.getToken(&tt)) {
4904 return errorResult();
4905 }
4906
4907 Node binding;
4908 if (tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly) {
4909 MOZ_TRY_VAR(binding, declarationPattern(declKind, tt, initialDeclaration,do { auto mozTryVarTempResult_ = (declarationPattern(declKind
, tt, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4910 yieldHandling, forHeadKind,do { auto mozTryVarTempResult_ = (declarationPattern(declKind
, tt, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4911 forInOrOfExpression))do { auto mozTryVarTempResult_ = (declarationPattern(declKind
, tt, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4912 } else {
4913 MOZ_TRY_VAR(binding, declarationName(declKind, tt, initialDeclaration,do { auto mozTryVarTempResult_ = (declarationName(declKind, tt
, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4914 yieldHandling, forHeadKind,do { auto mozTryVarTempResult_ = (declarationName(declKind, tt
, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
4915 forInOrOfExpression))do { auto mozTryVarTempResult_ = (declarationName(declKind, tt
, initialDeclaration, yieldHandling, forHeadKind, forInOrOfExpression
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (binding)
= mozTryVarTempResult_.unwrap(); } while (0)
;
4916 }
4917
4918 handler_.addList(decl, binding);
4919
4920 // If we have a for-in/of loop, the above call matches the entirety
4921 // of the loop head (up to the closing parenthesis).
4922 if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
4923 break;
4924 }
4925
4926 initialDeclaration = false;
4927
4928 if (!tokenStream.matchToken(&moreDeclarations, TokenKind::Comma,
4929 TokenStream::SlashIsRegExp)) {
4930 return errorResult();
4931 }
4932 } while (moreDeclarations);
4933
4934 return decl;
4935}
4936
4937template <class ParseHandler, typename Unit>
4938typename ParseHandler::DeclarationListNodeResult
4939GeneralParser<ParseHandler, Unit>::lexicalDeclaration(
4940 YieldHandling yieldHandling, DeclarationKind kind) {
4941 MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Letdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4942#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENTdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4943 || kind == DeclarationKind::Using ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4944 kind == DeclarationKind::AwaitUsingdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4945#endifdo { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4946 )do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let ifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind
::AwaitUsing endif)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == DeclarationKind::Const
|| kind == DeclarationKind::Let ifdef 1 || kind == DeclarationKind
::Using || kind == DeclarationKind::AwaitUsing endif))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4946); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Letifdef 1 || kind == DeclarationKind::Using || kind == DeclarationKind::AwaitUsingendif"
")"); do { *((volatile int*)__null) = 4946; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4947
4948 if (options().selfHostingMode) {
4949 error(JSMSG_SELFHOSTED_LEXICAL);
4950 return errorResult();
4951 }
4952
4953 /*
4954 * Parse body-level lets without a new block object. ES6 specs
4955 * that an execution environment's initial lexical environment
4956 * is the VariableEnvironment, i.e., body-level lets are in
4957 * the same environment record as vars.
4958 *
4959 * However, they cannot be parsed exactly as vars, as ES6
4960 * requires that uninitialized lets throw ReferenceError on use.
4961 *
4962 * See 8.1.1.1.6 and the note in 13.2.1.
4963 */
4964 DeclarationListNodeType decl;
4965 ParseNodeKind pnk;
4966 switch (kind) {
4967 case DeclarationKind::Const:
4968 pnk = ParseNodeKind::ConstDecl;
4969 break;
4970#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
4971 case DeclarationKind::Using:
4972 pnk = ParseNodeKind::UsingDecl;
4973 break;
4974 case DeclarationKind::AwaitUsing:
4975 pnk = ParseNodeKind::AwaitUsingDecl;
4976 break;
4977#endif
4978 case DeclarationKind::Let:
4979 pnk = ParseNodeKind::LetDecl;
4980 break;
4981 default:
4982 MOZ_CRASH("unexpected node kind")do { do { } while (false); MOZ_ReportCrash("" "unexpected node kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4982); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected node kind"
")"); do { *((volatile int*)__null) = 4982; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4983 }
4984 MOZ_TRY_VAR(decl, declarationList(yieldHandling, pnk))do { auto mozTryVarTempResult_ = (declarationList(yieldHandling
, pnk)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr(
)), 0))) { return mozTryVarTempResult_.propagateErr(); } (decl
) = mozTryVarTempResult_.unwrap(); } while (0)
;
4985 if (!matchOrInsertSemicolon()) {
4986 return errorResult();
4987 }
4988
4989 return decl;
4990}
4991
4992template <class ParseHandler, typename Unit>
4993typename ParseHandler::NameNodeResult
4994GeneralParser<ParseHandler, Unit>::moduleExportName() {
4995 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::String)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::String)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::String)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.currentToken().type == TokenKind::String"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4995); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::String"
")"); do { *((volatile int*)__null) = 4995; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4996 TaggedParserAtomIndex name = anyChars.currentToken().atom();
4997 if (!this->parserAtoms().isModuleExportName(name)) {
4998 error(JSMSG_UNPAIRED_SURROGATE_EXPORT);
4999 return errorResult();
5000 }
5001 return handler_.newStringLiteral(name, pos());
5002}
5003
5004template <class ParseHandler, typename Unit>
5005bool GeneralParser<ParseHandler, Unit>::withClause(ListNodeType attributesSet) {
5006 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Assert) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars
.isCurrentTokenType(TokenKind::With))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::
With)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5007); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 5007; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5007 anyChars.isCurrentTokenType(TokenKind::With))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars
.isCurrentTokenType(TokenKind::With))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::
With)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5007); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 5007; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5008
5009 if (!options().importAttributes()) {
5010 error(JSMSG_IMPORT_ASSERTIONS_NOT_SUPPORTED);
5011 return false;
5012 }
5013
5014 if (!abortIfSyntaxParser()) {
5015 return false;
5016 }
5017
5018 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_AFTER_ASSERT)) {
5019 return false;
5020 }
5021
5022 // Handle the form |... assert {}|
5023 TokenKind token;
5024 if (!tokenStream.getToken(&token)) {
5025 return false;
5026 }
5027 if (token == TokenKind::RightCurly) {
5028 return true;
5029 }
5030
5031 js::HashSet<TaggedParserAtomIndex, TaggedParserAtomIndexHasher,
5032 js::SystemAllocPolicy>
5033 usedAssertionKeys;
5034
5035 for (;;) {
5036 TaggedParserAtomIndex keyName;
5037 if (TokenKindIsPossibleIdentifierName(token)) {
5038 keyName = anyChars.currentName();
5039 } else if (token == TokenKind::String) {
5040 keyName = anyChars.currentToken().atom();
5041 } else {
5042 error(JSMSG_ASSERT_KEY_EXPECTED);
5043 return false;
5044 }
5045
5046 auto p = usedAssertionKeys.lookupForAdd(keyName);
5047 if (p) {
5048 UniqueChars str = this->parserAtoms().toPrintableString(keyName);
5049 if (!str) {
5050 ReportOutOfMemory(this->fc_);
5051 return false;
5052 }
5053 error(JSMSG_DUPLICATE_ASSERT_KEY, str.get());
5054 return false;
5055 }
5056 if (!usedAssertionKeys.add(p, keyName)) {
5057 ReportOutOfMemory(this->fc_);
5058 return false;
5059 }
5060
5061 NameNodeType keyNode;
5062 MOZ_TRY_VAR_OR_RETURN(keyNode, newName(keyName), false)do { auto parserTryVarTempResult_ = (newName(keyName)); if ((
__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) { return
(false); } (keyNode) = parserTryVarTempResult_.unwrap(); } while
(0)
;
5063
5064 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_ASSERT_KEY)) {
5065 return false;
5066 }
5067 if (!mustMatchToken(TokenKind::String, JSMSG_ASSERT_STRING_LITERAL)) {
5068 return false;
5069 }
5070
5071 NameNodeType valueNode;
5072 MOZ_TRY_VAR_OR_RETURN(valueNode, stringLiteral(), false)do { auto parserTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(valueNode) = parserTryVarTempResult_.unwrap(); } while (0)
;
5073
5074 BinaryNodeType importAttributeNode;
5075 MOZ_TRY_VAR_OR_RETURN(importAttributeNode,do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
5076 handler_.newImportAttribute(keyNode, valueNode),do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
5077 false)do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5078
5079 handler_.addList(attributesSet, importAttributeNode);
5080
5081 if (!tokenStream.getToken(&token)) {
5082 return false;
5083 }
5084 if (token == TokenKind::Comma) {
5085 if (!tokenStream.getToken(&token)) {
5086 return false;
5087 }
5088 }
5089 if (token == TokenKind::RightCurly) {
5090 break;
5091 }
5092 }
5093
5094 return true;
5095}
5096
5097template <class ParseHandler, typename Unit>
5098bool GeneralParser<ParseHandler, Unit>::namedImports(
5099 ListNodeType importSpecSet) {
5100 if (!abortIfSyntaxParser()) {
5101 return false;
5102 }
5103
5104 while (true) {
5105 // Handle the forms |import {} from 'a'| and
5106 // |import { ..., } from 'a'| (where ... is non empty), by
5107 // escaping the loop early if the next token is }.
5108 TokenKind tt;
5109 if (!tokenStream.getToken(&tt)) {
5110 return false;
5111 }
5112
5113 if (tt == TokenKind::RightCurly) {
5114 break;
5115 }
5116
5117 TaggedParserAtomIndex importName;
5118 NameNodeType importNameNode = null();
5119 if (TokenKindIsPossibleIdentifierName(tt)) {
5120 importName = anyChars.currentName();
5121 MOZ_TRY_VAR_OR_RETURN(importNameNode, newName(importName), false)do { auto parserTryVarTempResult_ = (newName(importName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (importNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5122 } else if (tt == TokenKind::String) {
5123 MOZ_TRY_VAR_OR_RETURN(importNameNode, moduleExportName(), false)do { auto parserTryVarTempResult_ = (moduleExportName()); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (importNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5124 } else {
5125 error(JSMSG_NO_IMPORT_NAME);
5126 return false;
5127 }
5128
5129 bool matched;
5130 if (!tokenStream.matchToken(&matched, TokenKind::As)) {
5131 return false;
5132 }
5133
5134 if (matched) {
5135 TokenKind afterAs;
5136 if (!tokenStream.getToken(&afterAs)) {
5137 return false;
5138 }
5139
5140 if (!TokenKindIsPossibleIdentifierName(afterAs)) {
5141 error(JSMSG_NO_BINDING_NAME);
5142 return false;
5143 }
5144 } else {
5145 // String export names can't refer to local bindings.
5146 if (tt == TokenKind::String) {
5147 error(JSMSG_AS_AFTER_STRING);
5148 return false;
5149 }
5150
5151 // Keywords cannot be bound to themselves, so an import name
5152 // that is a keyword is a syntax error if it is not followed
5153 // by the keyword 'as'.
5154 // See the ImportSpecifier production in ES6 section 15.2.2.
5155 MOZ_ASSERT(importName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(importName)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(importName))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("importName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5155); AnnotateMozCrashReason("MOZ_ASSERT" "(" "importName"
")"); do { *((volatile int*)__null) = 5155; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5156 if (IsKeyword(importName)) {
5157 error(JSMSG_AS_AFTER_RESERVED_WORD, ReservedWordToCharZ(importName));
5158 return false;
5159 }
5160 }
5161
5162 TaggedParserAtomIndex bindingAtom = importedBinding();
5163 if (!bindingAtom) {
5164 return false;
5165 }
5166
5167 NameNodeType bindingName;
5168 MOZ_TRY_VAR_OR_RETURN(bindingName, newName(bindingAtom), false)do { auto parserTryVarTempResult_ = (newName(bindingAtom)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (bindingName) = parserTryVarTempResult_.
unwrap(); } while (0)
;
5169 if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
5170 return false;
5171 }
5172
5173 BinaryNodeType importSpec;
5174 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newImportSpec(importNameNode
, bindingName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5175 importSpec, handler_.newImportSpec(importNameNode, bindingName), false)do { auto parserTryVarTempResult_ = (handler_.newImportSpec(importNameNode
, bindingName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5176
5177 handler_.addList(importSpecSet, importSpec);
5178
5179 TokenKind next;
5180 if (!tokenStream.getToken(&next)) {
5181 return false;
5182 }
5183
5184 if (next == TokenKind::RightCurly) {
5185 break;
5186 }
5187
5188 if (next != TokenKind::Comma) {
5189 error(JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
5190 return false;
5191 }
5192 }
5193
5194 return true;
5195}
5196
5197template <class ParseHandler, typename Unit>
5198bool GeneralParser<ParseHandler, Unit>::namespaceImport(
5199 ListNodeType importSpecSet) {
5200 if (!abortIfSyntaxParser()) {
5201 return false;
5202 }
5203
5204 if (!mustMatchToken(TokenKind::As, JSMSG_AS_AFTER_IMPORT_STAR)) {
5205 return false;
5206 }
5207 uint32_t begin = pos().begin;
5208
5209 if (!mustMatchToken(TokenKindIsPossibleIdentifierName,
5210 JSMSG_NO_BINDING_NAME)) {
5211 return false;
5212 }
5213
5214 // Namespace imports are not indirect bindings but lexical
5215 // definitions that hold a module namespace object. They are treated
5216 // as const variables which are initialized during the
5217 // ModuleInstantiate step.
5218 TaggedParserAtomIndex bindingName = importedBinding();
5219 if (!bindingName) {
5220 return false;
5221 }
5222 NameNodeType bindingNameNode;
5223 MOZ_TRY_VAR_OR_RETURN(bindingNameNode, newName(bindingName), false)do { auto parserTryVarTempResult_ = (newName(bindingName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (bindingNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5224 if (!noteDeclaredName(bindingName, DeclarationKind::Const, pos())) {
5225 return false;
5226 }
5227
5228 // The namespace import name is currently required to live on the
5229 // environment.
5230 pc_->varScope().lookupDeclaredName(bindingName)->value()->setClosedOver();
5231
5232 UnaryNodeType importSpec;
5233 MOZ_TRY_VAR_OR_RETURN(importSpec,do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5234 handler_.newImportNamespaceSpec(begin, bindingNameNode),do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5235 false)do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5236
5237 handler_.addList(importSpecSet, importSpec);
5238
5239 return true;
5240}
5241
5242template <class ParseHandler, typename Unit>
5243typename ParseHandler::BinaryNodeResult
5244GeneralParser<ParseHandler, Unit>::importDeclaration() {
5245 if (!abortIfSyntaxParser()) {
5246 return errorResult();
5247 }
5248
5249 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Import))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Import)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Import)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5249); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 5249; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5250
5251 if (!pc_->atModuleLevel()) {
5252 error(JSMSG_IMPORT_DECL_AT_TOP_LEVEL);
5253 return errorResult();
5254 }
5255
5256 uint32_t begin = pos().begin;
5257 TokenKind tt;
5258 if (!tokenStream.getToken(&tt)) {
5259 return errorResult();
5260 }
5261
5262 ListNodeType importSpecSet;
5263 MOZ_TRY_VAR(importSpecSet,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importSpecSet) = mozTryVarTempResult_.unwrap(); } while (
0)
5264 handler_.newList(ParseNodeKind::ImportSpecList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importSpecSet) = mozTryVarTempResult_.unwrap(); } while (
0)
;
5265
5266 if (tt == TokenKind::String) {
5267 // Handle the form |import 'a'| by leaving the list empty. This is
5268 // equivalent to |import {} from 'a'|.
5269 handler_.setEndPosition(importSpecSet, pos().begin);
5270 } else {
5271 if (tt == TokenKind::LeftCurly) {
5272 if (!namedImports(importSpecSet)) {
5273 return errorResult();
5274 }
5275 } else if (tt == TokenKind::Mul) {
5276 if (!namespaceImport(importSpecSet)) {
5277 return errorResult();
5278 }
5279 } else if (TokenKindIsPossibleIdentifierName(tt)) {
5280 // Handle the form |import a from 'b'|, by adding a single import
5281 // specifier to the list, with 'default' as the import name and
5282 // 'a' as the binding name. This is equivalent to
5283 // |import { default as a } from 'b'|.
5284 NameNodeType importName;
5285 MOZ_TRY_VAR(importName,do { auto mozTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::default_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importName) = mozTryVarTempResult_.unwrap(); } while (0)
5286 newName(TaggedParserAtomIndex::WellKnown::default_()))do { auto mozTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::default_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importName) = mozTryVarTempResult_.unwrap(); } while (0)
;
5287
5288 TaggedParserAtomIndex bindingAtom = importedBinding();
5289 if (!bindingAtom) {
5290 return errorResult();
5291 }
5292
5293 NameNodeType bindingName;
5294 MOZ_TRY_VAR(bindingName, newName(bindingAtom))do { auto mozTryVarTempResult_ = (newName(bindingAtom)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (bindingName) = mozTryVarTempResult_
.unwrap(); } while (0)
;
5295
5296 if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
5297 return errorResult();
5298 }
5299
5300 BinaryNodeType importSpec;
5301 MOZ_TRY_VAR(importSpec, handler_.newImportSpec(importName, bindingName))do { auto mozTryVarTempResult_ = (handler_.newImportSpec(importName
, bindingName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importSpec) = mozTryVarTempResult_.unwrap(); } while (0)
;
5302
5303 handler_.addList(importSpecSet, importSpec);
5304
5305 if (!tokenStream.peekToken(&tt)) {
5306 return errorResult();
5307 }
5308
5309 if (tt == TokenKind::Comma) {
5310 tokenStream.consumeKnownToken(tt);
5311 if (!tokenStream.getToken(&tt)) {
5312 return errorResult();
5313 }
5314
5315 if (tt == TokenKind::LeftCurly) {
5316 if (!namedImports(importSpecSet)) {
5317 return errorResult();
5318 }
5319 } else if (tt == TokenKind::Mul) {
5320 if (!namespaceImport(importSpecSet)) {
5321 return errorResult();
5322 }
5323 } else {
5324 error(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT);
5325 return errorResult();
5326 }
5327 }
5328 } else {
5329 error(JSMSG_DECLARATION_AFTER_IMPORT);
5330 return errorResult();
5331 }
5332
5333 if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_IMPORT_CLAUSE)) {
5334 return errorResult();
5335 }
5336
5337 if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
5338 return errorResult();
5339 }
5340 }
5341
5342 NameNodeType moduleSpec;
5343 MOZ_TRY_VAR(moduleSpec, stringLiteral())do { auto mozTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleSpec) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5344
5345 // The `assert` keyword has a [no LineTerminator here] production before it in
5346 // the grammar -- `with` does not. We need to handle this distinction.
5347 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
5348 return errorResult();
5349 }
5350
5351 // `with` may have an EOL prior, so peek the next token and replace
5352 // EOL if the next token is `with`.
5353 if (tt == TokenKind::Eol) {
5354 // Doing a regular peek won't produce Eol, but the actual next token.
5355 TokenKind peekedToken;
5356 if (!tokenStream.peekToken(&peekedToken, TokenStream::SlashIsRegExp)) {
5357 return errorResult();
5358 }
5359
5360 if (peekedToken == TokenKind::With) {
5361 tt = TokenKind::With;
5362 }
5363 }
5364
5365 ListNodeType importAttributeList;
5366 MOZ_TRY_VAR(importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
5367 handler_.newList(ParseNodeKind::ImportAttributeList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
;
5368
5369 if (tt == TokenKind::With) {
5370 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
5371
5372 if (!withClause(importAttributeList)) {
5373 return errorResult();
5374 }
5375 }
5376
5377 if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
5378 return errorResult();
5379 }
5380
5381 BinaryNodeType moduleRequest;
5382 MOZ_TRY_VAR(moduleRequest,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleRequest) = mozTryVarTempResult_.unwrap
(); } while (0)
5383 handler_.newModuleRequest(moduleSpec, importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleRequest) = mozTryVarTempResult_.unwrap
(); } while (0)
5384 TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleRequest) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5385
5386 BinaryNodeType node;
5387 MOZ_TRY_VAR(node, handler_.newImportDeclaration(importSpecSet, moduleRequest,do { auto mozTryVarTempResult_ = (handler_.newImportDeclaration
(importSpecSet, moduleRequest, TokenPos(begin, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (node) = mozTryVarTempResult_
.unwrap(); } while (0)
5388 TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newImportDeclaration
(importSpecSet, moduleRequest, TokenPos(begin, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (node) = mozTryVarTempResult_
.unwrap(); } while (0)
;
5389 if (!processImport(node)) {
5390 return errorResult();
5391 }
5392
5393 return node;
5394}
5395
5396template <class ParseHandler, typename Unit>
5397inline typename ParseHandler::NodeResult
5398GeneralParser<ParseHandler, Unit>::importDeclarationOrImportExpr(
5399 YieldHandling yieldHandling) {
5400 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Import))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Import)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Import)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5400); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 5400; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5401
5402 TokenKind tt;
5403 if (!tokenStream.peekToken(&tt)) {
5404 return errorResult();
5405 }
5406
5407 if (tt == TokenKind::Dot || tt == TokenKind::LeftParen) {
5408 return expressionStatement(yieldHandling);
5409 }
5410
5411 return importDeclaration();
5412}
5413
5414template <typename Unit>
5415bool Parser<FullParseHandler, Unit>::checkExportedName(
5416 TaggedParserAtomIndex exportName) {
5417 switch (pc_->sc()->asModuleContext()->builder.noteExportedName(exportName)) {
5418 case ModuleBuilder::NoteExportedNameResult::Success:
5419 return true;
5420 case ModuleBuilder::NoteExportedNameResult::OutOfMemory:
5421 return false;
5422 case ModuleBuilder::NoteExportedNameResult::AlreadyDeclared:
5423 break;
5424 }
5425
5426 UniqueChars str = this->parserAtoms().toPrintableString(exportName);
5427 if (!str) {
5428 ReportOutOfMemory(this->fc_);
5429 return false;
5430 }
5431
5432 error(JSMSG_DUPLICATE_EXPORT_NAME, str.get());
5433 return false;
5434}
5435
5436template <typename Unit>
5437inline bool Parser<SyntaxParseHandler, Unit>::checkExportedName(
5438 TaggedParserAtomIndex exportName) {
5439 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5439); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5439; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5440 return false;
5441}
5442
5443template <class ParseHandler, typename Unit>
5444inline bool GeneralParser<ParseHandler, Unit>::checkExportedName(
5445 TaggedParserAtomIndex exportName) {
5446 return asFinalParser()->checkExportedName(exportName);
5447}
5448
5449template <typename Unit>
5450bool Parser<FullParseHandler, Unit>::checkExportedNamesForArrayBinding(
5451 ListNode* array) {
5452 MOZ_ASSERT(array->isKind(ParseNodeKind::ArrayExpr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(array->isKind(ParseNodeKind::ArrayExpr))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(array->isKind(ParseNodeKind::ArrayExpr)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("array->isKind(ParseNodeKind::ArrayExpr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5452); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array->isKind(ParseNodeKind::ArrayExpr)"
")"); do { *((volatile int*)__null) = 5452; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5453
5454 for (ParseNode* node : array->contents()) {
5455 if (node->isKind(ParseNodeKind::Elision)) {
5456 continue;
5457 }
5458
5459 ParseNode* binding;
5460 if (node->isKind(ParseNodeKind::Spread)) {
5461 binding = node->as<UnaryNode>().kid();
5462 } else if (node->isKind(ParseNodeKind::AssignExpr)) {
5463 binding = node->as<AssignmentNode>().left();
5464 } else {
5465 binding = node;
5466 }
5467
5468 if (!checkExportedNamesForDeclaration(binding)) {
5469 return false;
5470 }
5471 }
5472
5473 return true;
5474}
5475
5476template <typename Unit>
5477inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForArrayBinding(
5478 ListNodeType array) {
5479 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5479); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5479; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5480 return false;
5481}
5482
5483template <class ParseHandler, typename Unit>
5484inline bool
5485GeneralParser<ParseHandler, Unit>::checkExportedNamesForArrayBinding(
5486 ListNodeType array) {
5487 return asFinalParser()->checkExportedNamesForArrayBinding(array);
5488}
5489
5490template <typename Unit>
5491bool Parser<FullParseHandler, Unit>::checkExportedNamesForObjectBinding(
5492 ListNode* obj) {
5493 MOZ_ASSERT(obj->isKind(ParseNodeKind::ObjectExpr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(obj->isKind(ParseNodeKind::ObjectExpr))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(obj->isKind(ParseNodeKind::ObjectExpr)))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("obj->isKind(ParseNodeKind::ObjectExpr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5493); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->isKind(ParseNodeKind::ObjectExpr)"
")"); do { *((volatile int*)__null) = 5493; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5494
5495 for (ParseNode* node : obj->contents()) {
5496 MOZ_ASSERT(node->isKind(ParseNodeKind::MutateProto) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5497 node->isKind(ParseNodeKind::PropertyDefinition) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5498 node->isKind(ParseNodeKind::Shorthand) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5499 node->isKind(ParseNodeKind::Spread))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
))>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(node->isKind(ParseNodeKind::MutateProto) || node->
isKind(ParseNodeKind::PropertyDefinition) || node->isKind(
ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5499); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5499; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5500
5501 ParseNode* target;
5502 if (node->isKind(ParseNodeKind::Spread)) {
5503 target = node->as<UnaryNode>().kid();
5504 } else {
5505 if (node->isKind(ParseNodeKind::MutateProto)) {
5506 target = node->as<UnaryNode>().kid();
5507 } else {
5508 target = node->as<BinaryNode>().right();
5509 }
5510
5511 if (target->isKind(ParseNodeKind::AssignExpr)) {
5512 target = target->as<AssignmentNode>().left();
5513 }
5514 }
5515
5516 if (!checkExportedNamesForDeclaration(target)) {
5517 return false;
5518 }
5519 }
5520
5521 return true;
5522}
5523
5524template <typename Unit>
5525inline bool Parser<SyntaxParseHandler,
5526 Unit>::checkExportedNamesForObjectBinding(ListNodeType obj) {
5527 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5527); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5527; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5528 return false;
5529}
5530
5531template <class ParseHandler, typename Unit>
5532inline bool
5533GeneralParser<ParseHandler, Unit>::checkExportedNamesForObjectBinding(
5534 ListNodeType obj) {
5535 return asFinalParser()->checkExportedNamesForObjectBinding(obj);
5536}
5537
5538template <typename Unit>
5539bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclaration(
5540 ParseNode* node) {
5541 if (node->isKind(ParseNodeKind::Name)) {
5542 if (!checkExportedName(node->as<NameNode>().atom())) {
5543 return false;
5544 }
5545 } else if (node->isKind(ParseNodeKind::ArrayExpr)) {
5546 if (!checkExportedNamesForArrayBinding(&node->as<ListNode>())) {
5547 return false;
5548 }
5549 } else {
5550 MOZ_ASSERT(node->isKind(ParseNodeKind::ObjectExpr))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(node->isKind(ParseNodeKind::ObjectExpr))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(node->isKind(ParseNodeKind::ObjectExpr)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("node->isKind(ParseNodeKind::ObjectExpr)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5550); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::ObjectExpr)"
")"); do { *((volatile int*)__null) = 5550; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5551 if (!checkExportedNamesForObjectBinding(&node->as<ListNode>())) {
5552 return false;
5553 }
5554 }
5555
5556 return true;
5557}
5558
5559template <typename Unit>
5560inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForDeclaration(
5561 Node node) {
5562 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5562); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5562; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5563 return false;
5564}
5565
5566template <class ParseHandler, typename Unit>
5567inline bool GeneralParser<ParseHandler, Unit>::checkExportedNamesForDeclaration(
5568 Node node) {
5569 return asFinalParser()->checkExportedNamesForDeclaration(node);
5570}
5571
5572template <typename Unit>
5573bool Parser<FullParseHandler, Unit>::checkExportedNamesForDeclarationList(
5574 DeclarationListNodeType node) {
5575 for (ParseNode* binding : node->contents()) {
5576 if (binding->isKind(ParseNodeKind::AssignExpr)) {
5577 binding = binding->as<AssignmentNode>().left();
5578 } else {
5579 MOZ_ASSERT(binding->isKind(ParseNodeKind::Name))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(binding->isKind(ParseNodeKind::Name))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(binding->isKind(ParseNodeKind::Name)))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("binding->isKind(ParseNodeKind::Name)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5579); AnnotateMozCrashReason("MOZ_ASSERT" "(" "binding->isKind(ParseNodeKind::Name)"
")"); do { *((volatile int*)__null) = 5579; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5580 }
5581
5582 if (!checkExportedNamesForDeclaration(binding)) {
5583 return false;
5584 }
5585 }
5586
5587 return true;
5588}
5589
5590template <typename Unit>
5591inline bool
5592Parser<SyntaxParseHandler, Unit>::checkExportedNamesForDeclarationList(
5593 DeclarationListNodeType node) {
5594 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5594); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5594; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5595 return false;
5596}
5597
5598template <class ParseHandler, typename Unit>
5599inline bool
5600GeneralParser<ParseHandler, Unit>::checkExportedNamesForDeclarationList(
5601 DeclarationListNodeType node) {
5602 return asFinalParser()->checkExportedNamesForDeclarationList(node);
5603}
5604
5605template <typename Unit>
5606inline bool Parser<FullParseHandler, Unit>::checkExportedNameForClause(
5607 NameNode* nameNode) {
5608 return checkExportedName(nameNode->atom());
5609}
5610
5611template <typename Unit>
5612inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForClause(
5613 NameNodeType nameNode) {
5614 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5614); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5614; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5615 return false;
5616}
5617
5618template <class ParseHandler, typename Unit>
5619inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForClause(
5620 NameNodeType nameNode) {
5621 return asFinalParser()->checkExportedNameForClause(nameNode);
5622}
5623
5624template <typename Unit>
5625bool Parser<FullParseHandler, Unit>::checkExportedNameForFunction(
5626 FunctionNode* funNode) {
5627 return checkExportedName(funNode->funbox()->explicitName());
5628}
5629
5630template <typename Unit>
5631inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForFunction(
5632 FunctionNodeType funNode) {
5633 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5633); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5633; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5634 return false;
5635}
5636
5637template <class ParseHandler, typename Unit>
5638inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForFunction(
5639 FunctionNodeType funNode) {
5640 return asFinalParser()->checkExportedNameForFunction(funNode);
5641}
5642
5643template <typename Unit>
5644bool Parser<FullParseHandler, Unit>::checkExportedNameForClass(
5645 ClassNode* classNode) {
5646 MOZ_ASSERT(classNode->names())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(classNode->names())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(classNode->names()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("classNode->names()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5646); AnnotateMozCrashReason("MOZ_ASSERT" "(" "classNode->names()"
")"); do { *((volatile int*)__null) = 5646; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5647 return checkExportedName(classNode->names()->innerBinding()->atom());
5648}
5649
5650template <typename Unit>
5651inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNameForClass(
5652 ClassNodeType classNode) {
5653 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5653); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5653; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5654 return false;
5655}
5656
5657template <class ParseHandler, typename Unit>
5658inline bool GeneralParser<ParseHandler, Unit>::checkExportedNameForClass(
5659 ClassNodeType classNode) {
5660 return asFinalParser()->checkExportedNameForClass(classNode);
5661}
5662
5663template <>
5664inline bool PerHandlerParser<FullParseHandler>::processExport(ParseNode* node) {
5665 return pc_->sc()->asModuleContext()->builder.processExport(node);
5666}
5667
5668template <>
5669inline bool PerHandlerParser<SyntaxParseHandler>::processExport(Node node) {
5670 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5670); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5670; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5671 return false;
5672}
5673
5674template <>
5675inline bool PerHandlerParser<FullParseHandler>::processExportFrom(
5676 BinaryNodeType node) {
5677 return pc_->sc()->asModuleContext()->builder.processExportFrom(node);
5678}
5679
5680template <>
5681inline bool PerHandlerParser<SyntaxParseHandler>::processExportFrom(
5682 BinaryNodeType node) {
5683 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5683); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5683; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5684 return false;
5685}
5686
5687template <>
5688inline bool PerHandlerParser<FullParseHandler>::processImport(
5689 BinaryNodeType node) {
5690 return pc_->sc()->asModuleContext()->builder.processImport(node);
5691}
5692
5693template <>
5694inline bool PerHandlerParser<SyntaxParseHandler>::processImport(
5695 BinaryNodeType node) {
5696 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5696); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5696; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5697 return false;
5698}
5699
5700template <class ParseHandler, typename Unit>
5701typename ParseHandler::BinaryNodeResult
5702GeneralParser<ParseHandler, Unit>::exportFrom(uint32_t begin, Node specList) {
5703 if (!abortIfSyntaxParser()) {
5704 return errorResult();
5705 }
5706
5707 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::From))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::From))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::From)))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::From)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5707); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::From)"
")"); do { *((volatile int*)__null) = 5707; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5708
5709 if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
5710 return errorResult();
5711 }
5712
5713 NameNodeType moduleSpec;
5714 MOZ_TRY_VAR(moduleSpec, stringLiteral())do { auto mozTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleSpec) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5715
5716 TokenKind tt;
5717
5718 // The `assert` keyword has a [no LineTerminator here] production before it in
5719 // the grammar -- `with` does not. We need to handle this distinction.
5720 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
5721 return errorResult();
5722 }
5723
5724 // `with` may have an EOL prior, so peek the next token and replace
5725 // EOL if the next token is `with`.
5726 if (tt == TokenKind::Eol) {
5727 // Doing a regular peek won't produce Eol, but the actual next token.
5728 TokenKind peekedToken;
5729 if (!tokenStream.peekToken(&peekedToken, TokenStream::SlashIsRegExp)) {
5730 return errorResult();
5731 }
5732
5733 if (peekedToken == TokenKind::With) {
5734 tt = TokenKind::With;
5735 }
5736 }
5737
5738 uint32_t moduleSpecPos = pos().begin;
5739
5740 ListNodeType importAttributeList;
5741 MOZ_TRY_VAR(importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
5742 handler_.newList(ParseNodeKind::ImportAttributeList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ImportAttributeList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (importAttributeList) = mozTryVarTempResult_.unwrap(); } while
(0)
;
5743 if (tt == TokenKind::With) {
5744 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
5745
5746 if (!withClause(importAttributeList)) {
5747 return errorResult();
5748 }
5749 }
5750
5751 if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
5752 return errorResult();
5753 }
5754
5755 BinaryNodeType moduleRequest;
5756 MOZ_TRY_VAR(moduleRequest,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(moduleSpecPos, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (moduleRequest) = mozTryVarTempResult_
.unwrap(); } while (0)
5757 handler_.newModuleRequest(moduleSpec, importAttributeList,do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(moduleSpecPos, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (moduleRequest) = mozTryVarTempResult_
.unwrap(); } while (0)
5758 TokenPos(moduleSpecPos, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newModuleRequest(moduleSpec
, importAttributeList, TokenPos(moduleSpecPos, pos().end))); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (moduleRequest) = mozTryVarTempResult_
.unwrap(); } while (0)
;
5759
5760 BinaryNodeType node;
5761 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (handler_.newExportFromDeclaration
(begin, specList, moduleRequest)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (node) = mozTryVarTempResult_.unwrap(); } while (0)
5762 node, handler_.newExportFromDeclaration(begin, specList, moduleRequest))do { auto mozTryVarTempResult_ = (handler_.newExportFromDeclaration
(begin, specList, moduleRequest)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (node) = mozTryVarTempResult_.unwrap(); } while (0)
;
5763
5764 if (!processExportFrom(node)) {
5765 return errorResult();
5766 }
5767
5768 return node;
5769}
5770
5771template <class ParseHandler, typename Unit>
5772typename ParseHandler::BinaryNodeResult
5773GeneralParser<ParseHandler, Unit>::exportBatch(uint32_t begin) {
5774 if (!abortIfSyntaxParser()) {
5775 return errorResult();
5776 }
5777
5778 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Mul))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Mul))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Mul)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Mul)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5778); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Mul)"
")"); do { *((volatile int*)__null) = 5778; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5779 uint32_t beginExportSpec = pos().begin;
5780
5781 ListNodeType kid;
5782 MOZ_TRY_VAR(kid, handler_.newList(ParseNodeKind::ExportSpecList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ExportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
5783
5784 bool foundAs;
5785 if (!tokenStream.matchToken(&foundAs, TokenKind::As)) {
5786 return errorResult();
5787 }
5788
5789 if (foundAs) {
5790 TokenKind tt;
5791 if (!tokenStream.getToken(&tt)) {
5792 return errorResult();
5793 }
5794
5795 NameNodeType exportName = null();
5796 if (TokenKindIsPossibleIdentifierName(tt)) {
5797 MOZ_TRY_VAR(exportName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (exportName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5798 } else if (tt == TokenKind::String) {
5799 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5800 } else {
5801 error(JSMSG_NO_EXPORT_NAME);
5802 return errorResult();
5803 }
5804
5805 if (!checkExportedNameForClause(exportName)) {
5806 return errorResult();
5807 }
5808
5809 UnaryNodeType exportSpec;
5810 MOZ_TRY_VAR(exportSpec,do { auto mozTryVarTempResult_ = (handler_.newExportNamespaceSpec
(beginExportSpec, exportName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exportSpec) = mozTryVarTempResult_.unwrap(); } while (0)
5811 handler_.newExportNamespaceSpec(beginExportSpec, exportName))do { auto mozTryVarTempResult_ = (handler_.newExportNamespaceSpec
(beginExportSpec, exportName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exportSpec) = mozTryVarTempResult_.unwrap(); } while (0)
;
5812
5813 handler_.addList(kid, exportSpec);
5814 } else {
5815 // Handle the form |export *| by adding a special export batch
5816 // specifier to the list.
5817 NullaryNodeType exportSpec;
5818 MOZ_TRY_VAR(exportSpec, handler_.newExportBatchSpec(pos()))do { auto mozTryVarTempResult_ = (handler_.newExportBatchSpec
(pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (exportSpec
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5819
5820 handler_.addList(kid, exportSpec);
5821 }
5822
5823 if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_EXPORT_STAR)) {
5824 return errorResult();
5825 }
5826
5827 return exportFrom(begin, kid);
5828}
5829
5830template <typename Unit>
5831bool Parser<FullParseHandler, Unit>::checkLocalExportNames(ListNode* node) {
5832 // ES 2017 draft 15.2.3.1.
5833 for (ParseNode* next : node->contents()) {
5834 ParseNode* name = next->as<BinaryNode>().left();
5835
5836 if (name->isKind(ParseNodeKind::StringExpr)) {
5837 errorAt(name->pn_pos.begin, JSMSG_BAD_LOCAL_STRING_EXPORT);
5838 return false;
5839 }
5840
5841 MOZ_ASSERT(name->isKind(ParseNodeKind::Name))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name->isKind(ParseNodeKind::Name))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(name->isKind(ParseNodeKind
::Name)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("name->isKind(ParseNodeKind::Name)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5841); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name->isKind(ParseNodeKind::Name)"
")"); do { *((volatile int*)__null) = 5841; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5842
5843 TaggedParserAtomIndex ident = name->as<NameNode>().atom();
5844 if (!checkLocalExportName(ident, name->pn_pos.begin)) {
5845 return false;
5846 }
5847 }
5848
5849 return true;
5850}
5851
5852template <typename Unit>
5853bool Parser<SyntaxParseHandler, Unit>::checkLocalExportNames(
5854 ListNodeType node) {
5855 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { do { } while (false); MOZ_ReportCrash("" "!(abortIfSyntaxParser())"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5855); AnnotateMozCrashReason("MOZ_CRASH(" "!(abortIfSyntaxParser())"
")"); do { *((volatile int*)__null) = 5855; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
5856 return false;
5857}
5858
5859template <class ParseHandler, typename Unit>
5860inline bool GeneralParser<ParseHandler, Unit>::checkLocalExportNames(
5861 ListNodeType node) {
5862 return asFinalParser()->checkLocalExportNames(node);
5863}
5864
5865template <class ParseHandler, typename Unit>
5866typename ParseHandler::NodeResult
5867GeneralParser<ParseHandler, Unit>::exportClause(uint32_t begin) {
5868 if (!abortIfSyntaxParser()) {
5869 return errorResult();
5870 }
5871
5872 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5872); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 5872; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5873
5874 ListNodeType kid;
5875 MOZ_TRY_VAR(kid, handler_.newList(ParseNodeKind::ExportSpecList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::ExportSpecList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
5876
5877 TokenKind tt;
5878 while (true) {
5879 // Handle the forms |export {}| and |export { ..., }| (where ... is non
5880 // empty), by escaping the loop early if the next token is }.
5881 if (!tokenStream.getToken(&tt)) {
5882 return errorResult();
5883 }
5884
5885 if (tt == TokenKind::RightCurly) {
5886 break;
5887 }
5888
5889 NameNodeType bindingName = null();
5890 if (TokenKindIsPossibleIdentifierName(tt)) {
5891 MOZ_TRY_VAR(bindingName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (bindingName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5892 } else if (tt == TokenKind::String) {
5893 MOZ_TRY_VAR(bindingName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (bindingName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5894 } else {
5895 error(JSMSG_NO_BINDING_NAME);
5896 return errorResult();
5897 }
5898
5899 bool foundAs;
5900 if (!tokenStream.matchToken(&foundAs, TokenKind::As)) {
5901 return errorResult();
5902 }
5903
5904 NameNodeType exportName = null();
5905 if (foundAs) {
5906 TokenKind tt;
5907 if (!tokenStream.getToken(&tt)) {
5908 return errorResult();
5909 }
5910
5911 if (TokenKindIsPossibleIdentifierName(tt)) {
5912 MOZ_TRY_VAR(exportName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (exportName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5913 } else if (tt == TokenKind::String) {
5914 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5915 } else {
5916 error(JSMSG_NO_EXPORT_NAME);
5917 return errorResult();
5918 }
5919 } else {
5920 if (tt != TokenKind::String) {
5921 MOZ_TRY_VAR(exportName, newName(anyChars.currentName()))do { auto mozTryVarTempResult_ = (newName(anyChars.currentName
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (exportName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
5922 } else {
5923 MOZ_TRY_VAR(exportName, moduleExportName())do { auto mozTryVarTempResult_ = (moduleExportName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (exportName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5924 }
5925 }
5926
5927 if (!checkExportedNameForClause(exportName)) {
5928 return errorResult();
5929 }
5930
5931 BinaryNodeType exportSpec;
5932 MOZ_TRY_VAR(exportSpec, handler_.newExportSpec(bindingName, exportName))do { auto mozTryVarTempResult_ = (handler_.newExportSpec(bindingName
, exportName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exportSpec) = mozTryVarTempResult_.unwrap(); } while (0)
;
5933
5934 handler_.addList(kid, exportSpec);
5935
5936 TokenKind next;
5937 if (!tokenStream.getToken(&next)) {
5938 return errorResult();
5939 }
5940
5941 if (next == TokenKind::RightCurly) {
5942 break;
5943 }
5944
5945 if (next != TokenKind::Comma) {
5946 error(JSMSG_RC_AFTER_EXPORT_SPEC_LIST);
5947 return errorResult();
5948 }
5949 }
5950
5951 // Careful! If |from| follows, even on a new line, it must start a
5952 // FromClause:
5953 //
5954 // export { x }
5955 // from "foo"; // a single ExportDeclaration
5956 //
5957 // But if it doesn't, we might have an ASI opportunity in SlashIsRegExp
5958 // context:
5959 //
5960 // export { x } // ExportDeclaration, terminated by ASI
5961 // fro\u006D // ExpressionStatement, the name "from"
5962 //
5963 // In that case let matchOrInsertSemicolon sort out ASI or any necessary
5964 // error.
5965 bool matched;
5966 if (!tokenStream.matchToken(&matched, TokenKind::From,
5967 TokenStream::SlashIsRegExp)) {
5968 return errorResult();
5969 }
5970
5971 if (matched) {
5972 return exportFrom(begin, kid);
5973 }
5974
5975 if (!matchOrInsertSemicolon()) {
5976 return errorResult();
5977 }
5978
5979 if (!checkLocalExportNames(kid)) {
5980 return errorResult();
5981 }
5982
5983 UnaryNodeType node;
5984 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
5985 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
5986
5987 if (!processExport(node)) {
5988 return errorResult();
5989 }
5990
5991 return node;
5992}
5993
5994template <class ParseHandler, typename Unit>
5995typename ParseHandler::UnaryNodeResult
5996GeneralParser<ParseHandler, Unit>::exportVariableStatement(uint32_t begin) {
5997 if (!abortIfSyntaxParser()) {
5998 return errorResult();
5999 }
6000
6001 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Var))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Var))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Var)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Var)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Var)"
")"); do { *((volatile int*)__null) = 6001; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6002
6003 DeclarationListNodeType kid;
6004 MOZ_TRY_VAR(kid, declarationList(YieldIsName, ParseNodeKind::VarStmt))do { auto mozTryVarTempResult_ = (declarationList(YieldIsName
, ParseNodeKind::VarStmt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
6005 if (!matchOrInsertSemicolon()) {
6006 return errorResult();
6007 }
6008 if (!checkExportedNamesForDeclarationList(kid)) {
6009 return errorResult();
6010 }
6011
6012 UnaryNodeType node;
6013 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6014 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6015
6016 if (!processExport(node)) {
6017 return errorResult();
6018 }
6019
6020 return node;
6021}
6022
6023template <class ParseHandler, typename Unit>
6024typename ParseHandler::UnaryNodeResult
6025GeneralParser<ParseHandler, Unit>::exportFunctionDeclaration(
6026 uint32_t begin, uint32_t toStringStart,
6027 FunctionAsyncKind asyncKind /* = SyncFunction */) {
6028 if (!abortIfSyntaxParser()) {
6029 return errorResult();
6030 }
6031
6032 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6032); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 6032; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6033
6034 Node kid;
6035 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, NameRequired, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
6036 kid, functionStmt(toStringStart, YieldIsName, NameRequired, asyncKind))do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, NameRequired, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6037
6038 if (!checkExportedNameForFunction(handler_.asFunctionNode(kid))) {
6039 return errorResult();
6040 }
6041
6042 UnaryNodeType node;
6043 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6044 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6045
6046 if (!processExport(node)) {
6047 return errorResult();
6048 }
6049
6050 return node;
6051}
6052
6053template <class ParseHandler, typename Unit>
6054typename ParseHandler::UnaryNodeResult
6055GeneralParser<ParseHandler, Unit>::exportClassDeclaration(uint32_t begin) {
6056 if (!abortIfSyntaxParser()) {
6057 return errorResult();
6058 }
6059
6060 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Class))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Class)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6060); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 6060; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6061
6062 ClassNodeType kid;
6063 MOZ_TRY_VAR(kid, classDefinition(YieldIsName, ClassStatement, NameRequired))do { auto mozTryVarTempResult_ = (classDefinition(YieldIsName
, ClassStatement, NameRequired)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
6064
6065 if (!checkExportedNameForClass(kid)) {
6066 return errorResult();
6067 }
6068
6069 UnaryNodeType node;
6070 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6071 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6072
6073 if (!processExport(node)) {
6074 return errorResult();
6075 }
6076
6077 return node;
6078}
6079
6080template <class ParseHandler, typename Unit>
6081typename ParseHandler::UnaryNodeResult
6082GeneralParser<ParseHandler, Unit>::exportLexicalDeclaration(
6083 uint32_t begin, DeclarationKind kind) {
6084 if (!abortIfSyntaxParser()) {
6085 return errorResult();
6086 }
6087
6088 MOZ_ASSERT(kind == DeclarationKind::Const || kind == DeclarationKind::Let)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == DeclarationKind::Const || kind == DeclarationKind
::Let)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(kind == DeclarationKind::Const || kind == DeclarationKind
::Let))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == DeclarationKind::Const || kind == DeclarationKind::Let"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6088); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Let"
")"); do { *((volatile int*)__null) = 6088; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6089 MOZ_ASSERT_IF(kind == DeclarationKind::Const,do { if (kind == DeclarationKind::Const) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(anyChars
.isCurrentTokenType(TokenKind::Const))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Const)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Const)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6090); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Const)"
")"); do { *((volatile int*)__null) = 6090; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6090 anyChars.isCurrentTokenType(TokenKind::Const))do { if (kind == DeclarationKind::Const) { do { static_assert
( mozilla::detail::AssertionConditionType<decltype(anyChars
.isCurrentTokenType(TokenKind::Const))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Const)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Const)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6090); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Const)"
")"); do { *((volatile int*)__null) = 6090; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6091 MOZ_ASSERT_IF(kind == DeclarationKind::Let,do { if (kind == DeclarationKind::Let) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Let))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Let)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Let)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6092); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 6092; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
6092 anyChars.isCurrentTokenType(TokenKind::Let))do { if (kind == DeclarationKind::Let) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Let))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Let)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Let)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6092); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 6092; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6093
6094 DeclarationListNodeType kid;
6095 MOZ_TRY_VAR(kid, lexicalDeclaration(YieldIsName, kind))do { auto mozTryVarTempResult_ = (lexicalDeclaration(YieldIsName
, kind)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (kid
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6096 if (!checkExportedNamesForDeclarationList(kid)) {
6097 return errorResult();
6098 }
6099
6100 UnaryNodeType node;
6101 MOZ_TRY_VAR(node,do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6102 handler_.newExportDeclaration(kid, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDeclaration
(kid, TokenPos(begin, pos().end))); if ((__builtin_expect(!!(
mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6103
6104 if (!processExport(node)) {
6105 return errorResult();
6106 }
6107
6108 return node;
6109}
6110
6111template <class ParseHandler, typename Unit>
6112typename ParseHandler::BinaryNodeResult
6113GeneralParser<ParseHandler, Unit>::exportDefaultFunctionDeclaration(
6114 uint32_t begin, uint32_t toStringStart,
6115 FunctionAsyncKind asyncKind /* = SyncFunction */) {
6116 if (!abortIfSyntaxParser()) {
6117 return errorResult();
6118 }
6119
6120 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Function))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Function))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Function)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Function)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6120); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 6120; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6121
6122 Node kid;
6123 MOZ_TRY_VAR(kid, functionStmt(toStringStart, YieldIsName, AllowDefaultName,do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, AllowDefaultName, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
6124 asyncKind))do { auto mozTryVarTempResult_ = (functionStmt(toStringStart,
YieldIsName, AllowDefaultName, asyncKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6125
6126 BinaryNodeType node;
6127 MOZ_TRY_VAR(node, handler_.newExportDefaultDeclaration(do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6128 kid, null(), TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6129
6130 if (!processExport(node)) {
6131 return errorResult();
6132 }
6133
6134 return node;
6135}
6136
6137template <class ParseHandler, typename Unit>
6138typename ParseHandler::BinaryNodeResult
6139GeneralParser<ParseHandler, Unit>::exportDefaultClassDeclaration(
6140 uint32_t begin) {
6141 if (!abortIfSyntaxParser()) {
6142 return errorResult();
6143 }
6144
6145 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Class))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Class)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6145); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 6145; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6146
6147 ClassNodeType kid;
6148 MOZ_TRY_VAR(kid,do { auto mozTryVarTempResult_ = (classDefinition(YieldIsName
, ClassStatement, AllowDefaultName)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
6149 classDefinition(YieldIsName, ClassStatement, AllowDefaultName))do { auto mozTryVarTempResult_ = (classDefinition(YieldIsName
, ClassStatement, AllowDefaultName)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (kid) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6150
6151 BinaryNodeType node;
6152 MOZ_TRY_VAR(node, handler_.newExportDefaultDeclaration(do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6153 kid, null(), TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, null(), TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6154
6155 if (!processExport(node)) {
6156 return errorResult();
6157 }
6158
6159 return node;
6160}
6161
6162template <class ParseHandler, typename Unit>
6163typename ParseHandler::BinaryNodeResult
6164GeneralParser<ParseHandler, Unit>::exportDefaultAssignExpr(uint32_t begin) {
6165 if (!abortIfSyntaxParser()) {
6166 return errorResult();
6167 }
6168
6169 TaggedParserAtomIndex name = TaggedParserAtomIndex::WellKnown::default_();
6170 NameNodeType nameNode;
6171 MOZ_TRY_VAR(nameNode, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nameNode) = mozTryVarTempResult_.unwrap()
; } while (0)
;
6172 if (!noteDeclaredName(name, DeclarationKind::Const, pos())) {
6173 return errorResult();
6174 }
6175
6176 Node kid;
6177 MOZ_TRY_VAR(kid, assignExpr(InAllowed, YieldIsName, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, YieldIsName
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
6178
6179 if (!matchOrInsertSemicolon()) {
6180 return errorResult();
6181 }
6182
6183 BinaryNodeType node;
6184 MOZ_TRY_VAR(node, handler_.newExportDefaultDeclaration(do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, nameNode, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
6185 kid, nameNode, TokenPos(begin, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newExportDefaultDeclaration
( kid, nameNode, TokenPos(begin, pos().end))); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (node) = mozTryVarTempResult_.unwrap(); } while
(0)
;
6186
6187 if (!processExport(node)) {
6188 return errorResult();
6189 }
6190
6191 return node;
6192}
6193
6194template <class ParseHandler, typename Unit>
6195typename ParseHandler::BinaryNodeResult
6196GeneralParser<ParseHandler, Unit>::exportDefault(uint32_t begin) {
6197 if (!abortIfSyntaxParser()) {
6198 return errorResult();
6199 }
6200
6201 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Default))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Default))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Default)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Default)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6201); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Default)"
")"); do { *((volatile int*)__null) = 6201; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6202
6203 TokenKind tt;
6204 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6205 return errorResult();
6206 }
6207
6208 if (!checkExportedName(TaggedParserAtomIndex::WellKnown::default_())) {
6209 return errorResult();
6210 }
6211
6212 switch (tt) {
6213 case TokenKind::Function:
6214 return exportDefaultFunctionDeclaration(begin, pos().begin);
6215
6216 case TokenKind::Async: {
6217 TokenKind nextSameLine = TokenKind::Eof;
6218 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
6219 return errorResult();
6220 }
6221
6222 if (nextSameLine == TokenKind::Function) {
6223 uint32_t toStringStart = pos().begin;
6224 tokenStream.consumeKnownToken(TokenKind::Function);
6225 return exportDefaultFunctionDeclaration(
6226 begin, toStringStart, FunctionAsyncKind::AsyncFunction);
6227 }
6228
6229 anyChars.ungetToken();
6230 return exportDefaultAssignExpr(begin);
6231 }
6232
6233 case TokenKind::Class:
6234 return exportDefaultClassDeclaration(begin);
6235
6236 default:
6237 anyChars.ungetToken();
6238 return exportDefaultAssignExpr(begin);
6239 }
6240}
6241
6242template <class ParseHandler, typename Unit>
6243typename ParseHandler::NodeResult
6244GeneralParser<ParseHandler, Unit>::exportDeclaration() {
6245 if (!abortIfSyntaxParser()) {
6246 return errorResult();
6247 }
6248
6249 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Export))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Export))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Export)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Export)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6249); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Export)"
")"); do { *((volatile int*)__null) = 6249; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6250
6251 if (!pc_->atModuleLevel()) {
6252 error(JSMSG_EXPORT_DECL_AT_TOP_LEVEL);
6253 return errorResult();
6254 }
6255
6256 uint32_t begin = pos().begin;
6257
6258 TokenKind tt;
6259 if (!tokenStream.getToken(&tt)) {
6260 return errorResult();
6261 }
6262 switch (tt) {
6263 case TokenKind::Mul:
6264 return exportBatch(begin);
6265
6266 case TokenKind::LeftCurly:
6267 return exportClause(begin);
6268
6269 case TokenKind::Var:
6270 return exportVariableStatement(begin);
6271
6272 case TokenKind::Function:
6273 return exportFunctionDeclaration(begin, pos().begin);
6274
6275 case TokenKind::Async: {
6276 TokenKind nextSameLine = TokenKind::Eof;
6277 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
6278 return errorResult();
6279 }
6280
6281 if (nextSameLine == TokenKind::Function) {
6282 uint32_t toStringStart = pos().begin;
6283 tokenStream.consumeKnownToken(TokenKind::Function);
6284 return exportFunctionDeclaration(begin, toStringStart,
6285 FunctionAsyncKind::AsyncFunction);
6286 }
6287
6288 error(JSMSG_DECLARATION_AFTER_EXPORT);
6289 return errorResult();
6290 }
6291
6292 case TokenKind::Class:
6293 return exportClassDeclaration(begin);
6294
6295 case TokenKind::Const:
6296 return exportLexicalDeclaration(begin, DeclarationKind::Const);
6297
6298 case TokenKind::Let:
6299 return exportLexicalDeclaration(begin, DeclarationKind::Let);
6300
6301 case TokenKind::Default:
6302 return exportDefault(begin);
6303
6304 default:
6305 error(JSMSG_DECLARATION_AFTER_EXPORT);
6306 return errorResult();
6307 }
6308}
6309
6310template <class ParseHandler, typename Unit>
6311typename ParseHandler::UnaryNodeResult
6312GeneralParser<ParseHandler, Unit>::expressionStatement(
6313 YieldHandling yieldHandling, InvokedPrediction invoked) {
6314 anyChars.ungetToken();
6315 Node pnexpr;
6316 MOZ_TRY_VAR(pnexpr, expr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited, nullptr, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pnexpr) = mozTryVarTempResult_.unwrap(); }
while (0)
6317 /* possibleError = */ nullptr, invoked))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited, nullptr, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pnexpr) = mozTryVarTempResult_.unwrap(); }
while (0)
;
6318 if (!matchOrInsertSemicolon()) {
6319 return errorResult();
6320 }
6321 return handler_.newExprStatement(pnexpr, pos().end);
6322}
6323
6324template <class ParseHandler, typename Unit>
6325typename ParseHandler::NodeResult
6326GeneralParser<ParseHandler, Unit>::consequentOrAlternative(
6327 YieldHandling yieldHandling) {
6328 TokenKind next;
6329 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
6330 return errorResult();
6331 }
6332
6333 // Annex B.3.4 says that unbraced FunctionDeclarations under if/else in
6334 // non-strict code act as if they were braced: |if (x) function f() {}|
6335 // parses as |if (x) { function f() {} }|.
6336 //
6337 // Careful! FunctionDeclaration doesn't include generators or async
6338 // functions.
6339 if (next == TokenKind::Function) {
6340 tokenStream.consumeKnownToken(next, TokenStream::SlashIsRegExp);
6341
6342 // Parser::statement would handle this, but as this function handles
6343 // every other error case, it seems best to handle this.
6344 if (pc_->sc()->strict()) {
6345 error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
6346 return errorResult();
6347 }
6348
6349 TokenKind maybeStar;
6350 if (!tokenStream.peekToken(&maybeStar)) {
6351 return errorResult();
6352 }
6353
6354 if (maybeStar == TokenKind::Mul) {
6355 error(JSMSG_FORBIDDEN_AS_STATEMENT, "generator declarations");
6356 return errorResult();
6357 }
6358
6359 ParseContext::Statement stmt(pc_, StatementKind::Block);
6360 ParseContext::Scope scope(this);
6361 if (!scope.init(pc_)) {
6362 return errorResult();
6363 }
6364
6365 TokenPos funcPos = pos();
6366 Node fun;
6367 MOZ_TRY_VAR(fun, functionStmt(pos().begin, yieldHandling, NameRequired))do { auto mozTryVarTempResult_ = (functionStmt(pos().begin, yieldHandling
, NameRequired)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fun) = mozTryVarTempResult_.unwrap(); } while (0)
;
6368
6369 ListNodeType block;
6370 MOZ_TRY_VAR(block, handler_.newStatementList(funcPos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(funcPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (block) =
mozTryVarTempResult_.unwrap(); } while (0)
;
6371
6372 handler_.addStatementToList(block, fun);
6373 return finishLexicalScope(scope, block);
6374 }
6375
6376 return statement(yieldHandling);
6377}
6378
6379template <class ParseHandler, typename Unit>
6380typename ParseHandler::TernaryNodeResult
6381GeneralParser<ParseHandler, Unit>::ifStatement(YieldHandling yieldHandling) {
6382 Vector<Node, 4> condList(fc_), thenList(fc_);
6383 Vector<uint32_t, 4> posList(fc_);
6384 Node elseBranch;
6385
6386 ParseContext::Statement stmt(pc_, StatementKind::If);
6387
6388 while (true) {
6389 uint32_t begin = pos().begin;
6390
6391 /* An IF node has three kids: condition, then, and optional else. */
6392 Node cond;
6393 MOZ_TRY_VAR(cond, condition(InAllowed, yieldHandling))do { auto mozTryVarTempResult_ = (condition(InAllowed, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (cond) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6394
6395 TokenKind tt;
6396 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6397 return errorResult();
6398 }
6399
6400 Node thenBranch;
6401 MOZ_TRY_VAR(thenBranch, consequentOrAlternative(yieldHandling))do { auto mozTryVarTempResult_ = (consequentOrAlternative(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (thenBranch
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6402
6403 if (!condList.append(cond) || !thenList.append(thenBranch) ||
6404 !posList.append(begin)) {
6405 return errorResult();
6406 }
6407
6408 bool matched;
6409 if (!tokenStream.matchToken(&matched, TokenKind::Else,
6410 TokenStream::SlashIsRegExp)) {
6411 return errorResult();
6412 }
6413 if (matched) {
6414 if (!tokenStream.matchToken(&matched, TokenKind::If,
6415 TokenStream::SlashIsRegExp)) {
6416 return errorResult();
6417 }
6418 if (matched) {
6419 continue;
6420 }
6421 MOZ_TRY_VAR(elseBranch, consequentOrAlternative(yieldHandling))do { auto mozTryVarTempResult_ = (consequentOrAlternative(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (elseBranch
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6422 } else {
6423 elseBranch = null();
6424 }
6425 break;
6426 }
6427
6428 TernaryNodeType ifNode;
6429 for (int i = condList.length() - 1; i >= 0; i--) {
6430 MOZ_TRY_VAR(ifNode, handler_.newIfStatement(posList[i], condList[i],do { auto mozTryVarTempResult_ = (handler_.newIfStatement(posList
[i], condList[i], thenList[i], elseBranch)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ifNode) = mozTryVarTempResult_.unwrap(); }
while (0)
6431 thenList[i], elseBranch))do { auto mozTryVarTempResult_ = (handler_.newIfStatement(posList
[i], condList[i], thenList[i], elseBranch)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ifNode) = mozTryVarTempResult_.unwrap(); }
while (0)
;
6432 elseBranch = ifNode;
6433 }
6434
6435 return ifNode;
6436}
6437
6438template <class ParseHandler, typename Unit>
6439typename ParseHandler::BinaryNodeResult
6440GeneralParser<ParseHandler, Unit>::doWhileStatement(
6441 YieldHandling yieldHandling) {
6442 uint32_t begin = pos().begin;
6443 ParseContext::Statement stmt(pc_, StatementKind::DoLoop);
6444 Node body;
6445 MOZ_TRY_VAR(body, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6446 if (!mustMatchToken(TokenKind::While, JSMSG_WHILE_AFTER_DO)) {
6447 return errorResult();
6448 }
6449 Node cond;
6450 MOZ_TRY_VAR(cond, condition(InAllowed, yieldHandling))do { auto mozTryVarTempResult_ = (condition(InAllowed, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (cond) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6451
6452 // The semicolon after do-while is even more optional than most
6453 // semicolons in JS. Web compat required this by 2004:
6454 // http://bugzilla.mozilla.org/show_bug.cgi?id=238945
6455 // ES3 and ES5 disagreed, but ES6 conforms to Web reality:
6456 // https://bugs.ecmascript.org/show_bug.cgi?id=157
6457 // To parse |do {} while (true) false| correctly, use SlashIsRegExp.
6458 bool ignored;
6459 if (!tokenStream.matchToken(&ignored, TokenKind::Semi,
6460 TokenStream::SlashIsRegExp)) {
6461 return errorResult();
6462 }
6463 return handler_.newDoWhileStatement(body, cond, TokenPos(begin, pos().end));
6464}
6465
6466template <class ParseHandler, typename Unit>
6467typename ParseHandler::BinaryNodeResult
6468GeneralParser<ParseHandler, Unit>::whileStatement(YieldHandling yieldHandling) {
6469 uint32_t begin = pos().begin;
6470 ParseContext::Statement stmt(pc_, StatementKind::WhileLoop);
6471 Node cond;
6472 MOZ_TRY_VAR(cond, condition(InAllowed, yieldHandling))do { auto mozTryVarTempResult_ = (condition(InAllowed, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (cond) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6473 Node body;
6474 MOZ_TRY_VAR(body, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6475 return handler_.newWhileStatement(begin, cond, body);
6476}
6477
6478template <class ParseHandler, typename Unit>
6479bool GeneralParser<ParseHandler, Unit>::matchInOrOf(bool* isForInp,
6480 bool* isForOfp) {
6481 TokenKind tt;
6482 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6483 return false;
6484 }
6485
6486 *isForInp = tt == TokenKind::In;
6487 *isForOfp = tt == TokenKind::Of;
6488 if (!*isForInp && !*isForOfp) {
6489 anyChars.ungetToken();
6490 }
6491
6492 MOZ_ASSERT_IF(*isForInp || *isForOfp, *isForInp != *isForOfp)do { if (*isForInp || *isForOfp) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(*isForInp != *isForOfp
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(*isForInp != *isForOfp))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("*isForInp != *isForOfp", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6492); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*isForInp != *isForOfp"
")"); do { *((volatile int*)__null) = 6492; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
6493 return true;
6494}
6495
6496template <class ParseHandler, typename Unit>
6497bool GeneralParser<ParseHandler, Unit>::forHeadStart(
6498 YieldHandling yieldHandling, IteratorKind iterKind,
6499 ParseNodeKind* forHeadKind, Node* forInitialPart,
6500 Maybe<ParseContext::Scope>& forLoopLexicalScope,
6501 Node* forInOrOfExpression) {
6502 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftParen))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftParen))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftParen))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftParen)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6502); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftParen)"
")"); do { *((volatile int*)__null) = 6502; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6503
6504 TokenKind tt;
6505 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6506 return false;
6507 }
6508
6509 // Super-duper easy case: |for (;| is a C-style for-loop with no init
6510 // component.
6511 if (tt == TokenKind::Semi) {
6512 *forInitialPart = null();
6513 *forHeadKind = ParseNodeKind::ForHead;
6514 return true;
6515 }
6516
6517 // Parsing after |for (var| is also relatively simple (from this method's
6518 // point of view). No block-related work complicates matters, so delegate
6519 // to Parser::declaration.
6520 if (tt == TokenKind::Var) {
6521 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6522
6523 // Pass null for block object because |var| declarations don't use one.
6524 MOZ_TRY_VAR_OR_RETURN(*forInitialPart,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
6525 declarationList(yieldHandling, ParseNodeKind::VarStmt,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
6526 forHeadKind, forInOrOfExpression),do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
6527 false)do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt, forHeadKind, forInOrOfExpression));
if ((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0
))) { return (false); } (*forInitialPart) = parserTryVarTempResult_
.unwrap(); } while (0)
;
6528 return true;
6529 }
6530
6531 // Otherwise we have a lexical declaration or an expression.
6532
6533 // For-in loop backwards compatibility requires that |let| starting a
6534 // for-loop that's not a (new to ES6) for-of loop, in non-strict mode code,
6535 // parse as an identifier. (|let| in for-of is always a declaration.)
6536 //
6537 // For-of loops can't start with the token sequence "async of", because that
6538 // leads to a shift-reduce conflict when parsing |for (async of => {};;)| or
6539 // |for (async of [])|.
6540 bool parsingLexicalDeclaration = false;
6541 bool letIsIdentifier = false;
6542 bool startsWithForOf = false;
6543
6544 if (tt == TokenKind::Const) {
6545 parsingLexicalDeclaration = true;
6546 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6547 }
6548#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
6549 else if (tt == TokenKind::Await && options().explicitResourceManagement()) {
6550 if (!pc_->isAsync()) {
6551 if (pc_->atModuleTopLevel()) {
6552 if (!options().topLevelAwait) {
6553 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
6554 return false;
6555 }
6556 pc_->sc()->asModuleContext()->setIsAsync();
6557 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6557); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 6557; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6558 }
6559 }
6560 if (pc_->isAsync()) {
6561 // Try finding evidence of a AwaitUsingDeclaration the syntax for which
6562 // would be:
6563 // await [no LineTerminator here] using [no LineTerminator here]
6564 // identifier
6565 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6566
6567 TokenKind nextTok = TokenKind::Eof;
6568 if (!tokenStream.peekTokenSameLine(&nextTok,
6569 TokenStream::SlashIsRegExp)) {
6570 return false;
6571 }
6572
6573 if (nextTok == TokenKind::Using) {
6574 tokenStream.consumeKnownToken(nextTok, TokenStream::SlashIsRegExp);
6575
6576 TokenKind nextTokIdent = TokenKind::Eof;
6577 if (!tokenStream.peekTokenSameLine(&nextTokIdent)) {
6578 return false;
6579 }
6580
6581 if (TokenKindIsPossibleIdentifier(nextTokIdent)) {
6582 parsingLexicalDeclaration = true;
6583 } else {
6584 anyChars.ungetToken(); // put back using token
6585 anyChars.ungetToken(); // put back await token
6586 }
6587 } else {
6588 anyChars.ungetToken(); // put back await token
6589 }
6590 }
6591 } else if (tt == TokenKind::Using && options().explicitResourceManagement()) {
6592 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
6593
6594 // Look ahead to find either a 'of' token or if not identifier
6595 TokenKind nextTok = TokenKind::Eof;
6596 if (!tokenStream.peekTokenSameLine(&nextTok)) {
6597 return false;
6598 }
6599
6600 if (nextTok == TokenKind::Of || !TokenKindIsPossibleIdentifier(nextTok)) {
6601 anyChars.ungetToken(); // we didnt find a valid case of using decl put
6602 // back the token
6603 } else {
6604 parsingLexicalDeclaration = true;
6605 }
6606 }
6607#endif
6608 else if (tt == TokenKind::Let) {
6609 // We could have a {For,Lexical}Declaration, or we could have a
6610 // LeftHandSideExpression with lookahead restrictions so it's not
6611 // ambiguous with the former. Check for a continuation of the former
6612 // to decide which we have.
6613 tokenStream.consumeKnownToken(TokenKind::Let, TokenStream::SlashIsRegExp);
6614
6615 TokenKind next;
6616 if (!tokenStream.peekToken(&next)) {
6617 return false;
6618 }
6619
6620 parsingLexicalDeclaration = nextTokenContinuesLetDeclaration(next);
6621 if (!parsingLexicalDeclaration) {
6622 // If we end up here, we may have `for (let <reserved word> of/in ...`,
6623 // which is not valid.
6624 if (next != TokenKind::In && next != TokenKind::Of &&
6625 TokenKindIsReservedWord(next)) {
6626 tokenStream.consumeKnownToken(next);
6627 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
6628 return false;
6629 }
6630
6631 anyChars.ungetToken();
6632 letIsIdentifier = true;
6633 }
6634 } else if (tt == TokenKind::Async && iterKind == IteratorKind::Sync) {
6635 tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::SlashIsRegExp);
6636
6637 TokenKind next;
6638 if (!tokenStream.peekToken(&next)) {
6639 return false;
6640 }
6641
6642 if (next == TokenKind::Of) {
6643 startsWithForOf = true;
6644 }
6645 anyChars.ungetToken();
6646 }
6647
6648 if (parsingLexicalDeclaration) {
6649 if (options().selfHostingMode) {
6650 error(JSMSG_SELFHOSTED_LEXICAL);
6651 return false;
6652 }
6653
6654 forLoopLexicalScope.emplace(this);
6655 if (!forLoopLexicalScope->init(pc_)) {
6656 return false;
6657 }
6658
6659 // Push a temporary ForLoopLexicalHead Statement that allows for
6660 // lexical declarations, as they are usually allowed only in braced
6661 // statements.
6662 ParseContext::Statement forHeadStmt(pc_, StatementKind::ForLoopLexicalHead);
6663
6664 ParseNodeKind declKind;
6665 switch (tt) {
6666 case TokenKind::Const:
6667 declKind = ParseNodeKind::ConstDecl;
6668 break;
6669#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
6670 case TokenKind::Using:
6671 declKind = ParseNodeKind::UsingDecl;
6672 break;
6673 case TokenKind::Await:
6674 declKind = ParseNodeKind::AwaitUsingDecl;
6675 break;
6676#endif
6677 case TokenKind::Let:
6678 declKind = ParseNodeKind::LetDecl;
6679 break;
6680 default:
6681 MOZ_CRASH("unexpected node kind")do { do { } while (false); MOZ_ReportCrash("" "unexpected node kind"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6681); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected node kind"
")"); do { *((volatile int*)__null) = 6681; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
6682 }
6683
6684 MOZ_TRY_VAR_OR_RETURN(*forInitialPart,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6685 declarationList(yieldHandling, declKind, forHeadKind,do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6686 forInOrOfExpression),do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6687 false)do { auto parserTryVarTempResult_ = (declarationList(yieldHandling
, declKind, forHeadKind, forInOrOfExpression)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
;
6688 return true;
6689 }
6690
6691 uint32_t exprOffset;
6692 if (!tokenStream.peekOffset(&exprOffset, TokenStream::SlashIsRegExp)) {
6693 return false;
6694 }
6695
6696 // Finally, handle for-loops that start with expressions. Pass
6697 // |InProhibited| so that |in| isn't parsed in a RelationalExpression as a
6698 // binary operator. |in| makes it a for-in loop, *not* an |in| expression.
6699 PossibleError possibleError(*this);
6700 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6701 *forInitialPart,do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6702 expr(InProhibited, yieldHandling, TripledotProhibited, &possibleError),do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
6703 false)do { auto parserTryVarTempResult_ = (expr(InProhibited, yieldHandling
, TripledotProhibited, &possibleError)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(*forInitialPart) = parserTryVarTempResult_.unwrap(); } while
(0)
;
6704
6705 bool isForIn, isForOf;
6706 if (!matchInOrOf(&isForIn, &isForOf)) {
6707 return false;
6708 }
6709
6710 // If we don't encounter 'in'/'of', we have a for(;;) loop. We've handled
6711 // the init expression; the caller handles the rest.
6712 if (!isForIn && !isForOf) {
6713 if (!possibleError.checkForExpressionError()) {
6714 return false;
6715 }
6716
6717 *forHeadKind = ParseNodeKind::ForHead;
6718 return true;
6719 }
6720
6721 MOZ_ASSERT(isForIn != isForOf)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isForIn != isForOf)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(isForIn != isForOf))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("isForIn != isForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6721); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isForIn != isForOf"
")"); do { *((volatile int*)__null) = 6721; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6722
6723 // In a for-of loop, 'let' that starts the loop head is a |let| keyword,
6724 // per the [lookahead ≠ let] restriction on the LeftHandSideExpression
6725 // variant of such loops. Expressions that start with |let| can't be used
6726 // here.
6727 //
6728 // var let = {};
6729 // for (let.prop of [1]) // BAD
6730 // break;
6731 //
6732 // See ES6 13.7.
6733 if (isForOf && letIsIdentifier) {
6734 errorAt(exprOffset, JSMSG_BAD_STARTING_FOROF_LHS, "let");
6735 return false;
6736 }
6737
6738 // In a for-of loop, the LeftHandSideExpression isn't allowed to be an
6739 // identifier named "async" per the [lookahead ≠ async of] restriction.
6740 if (isForOf && startsWithForOf) {
6741 errorAt(exprOffset, JSMSG_BAD_STARTING_FOROF_LHS, "async of");
6742 return false;
6743 }
6744
6745 *forHeadKind = isForIn ? ParseNodeKind::ForIn : ParseNodeKind::ForOf;
6746
6747 // Verify the left-hand side expression doesn't have a forbidden form.
6748 if (handler_.isUnparenthesizedDestructuringPattern(*forInitialPart)) {
6749 if (!possibleError.checkForDestructuringErrorOrWarning()) {
6750 return false;
6751 }
6752 } else if (handler_.isName(*forInitialPart)) {
6753 if (const char* chars = nameIsArgumentsOrEval(*forInitialPart)) {
6754 // |chars| is "arguments" or "eval" here.
6755 if (!strictModeErrorAt(exprOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) {
6756 return false;
6757 }
6758 }
6759 } else if (handler_.isArgumentsLength(*forInitialPart)) {
6760 pc_->sc()->setIneligibleForArgumentsLength();
6761 } else if (handler_.isPropertyOrPrivateMemberAccess(*forInitialPart)) {
6762 // Permitted: no additional testing/fixup needed.
6763 } else if (handler_.isFunctionCall(*forInitialPart)) {
6764 if (!strictModeErrorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE)) {
6765 return false;
6766 }
6767 } else {
6768 errorAt(exprOffset, JSMSG_BAD_FOR_LEFTSIDE);
6769 return false;
6770 }
6771
6772 if (!possibleError.checkForExpressionError()) {
6773 return false;
6774 }
6775
6776 // Finally, parse the iterated expression, making the for-loop's closing
6777 // ')' the next token.
6778 MOZ_TRY_VAR_OR_RETURN(*forInOrOfExpression,do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
6779 expressionAfterForInOrOf(*forHeadKind, yieldHandling),do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
6780 false)do { auto parserTryVarTempResult_ = (expressionAfterForInOrOf
(*forHeadKind, yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*forInOrOfExpression) = parserTryVarTempResult_
.unwrap(); } while (0)
;
6781 return true;
6782}
6783
6784template <class ParseHandler, typename Unit>
6785typename ParseHandler::NodeResult
6786GeneralParser<ParseHandler, Unit>::forStatement(YieldHandling yieldHandling) {
6787 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::For))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::For))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::For)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::For)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6787); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::For)"
")"); do { *((volatile int*)__null) = 6787; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6788
6789 uint32_t begin = pos().begin;
6790
6791 ParseContext::Statement stmt(pc_, StatementKind::ForLoop);
6792
6793 IteratorKind iterKind = IteratorKind::Sync;
6794 unsigned iflags = 0;
6795
6796 if (pc_->isAsync() || pc_->sc()->isModuleContext()) {
6797 bool matched;
6798 if (!tokenStream.matchToken(&matched, TokenKind::Await)) {
6799 return errorResult();
6800 }
6801
6802 // If we come across a top level await here, mark the module as async.
6803 if (matched && pc_->sc()->isModuleContext() && !pc_->isAsync()) {
6804 if (!options().topLevelAwait) {
6805 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
6806 return errorResult();
6807 }
6808 pc_->sc()->asModuleContext()->setIsAsync();
6809 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6809); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 6809; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6810 }
6811
6812 if (matched) {
6813 iflags |= JSITER_FORAWAITOF0x80;
6814 iterKind = IteratorKind::Async;
6815 }
6816 }
6817
6818 if (!mustMatchToken(TokenKind::LeftParen, [this](TokenKind actual) {
6819 this->error((actual == TokenKind::Await && !this->pc_->isAsync())
6820 ? JSMSG_FOR_AWAIT_OUTSIDE_ASYNC
6821 : JSMSG_PAREN_AFTER_FOR);
6822 })) {
6823 return errorResult();
6824 }
6825
6826 // ParseNodeKind::ForHead, ParseNodeKind::ForIn, or
6827 // ParseNodeKind::ForOf depending on the loop type.
6828 ParseNodeKind headKind;
6829
6830 // |x| in either |for (x; ...; ...)| or |for (x in/of ...)|.
6831 Node startNode;
6832
6833 // The next two variables are used to implement `for (let/const ...)`.
6834 //
6835 // We generate an implicit block, wrapping the whole loop, to store loop
6836 // variables declared this way. Note that if the loop uses `for (var...)`
6837 // instead, those variables go on some existing enclosing scope, so no
6838 // implicit block scope is created.
6839 //
6840 // Both variables remain null/none if the loop is any other form.
6841
6842 // The static block scope for the implicit block scope.
6843 Maybe<ParseContext::Scope> forLoopLexicalScope;
6844
6845 // The expression being iterated over, for for-in/of loops only. Unused
6846 // for for(;;) loops.
6847 Node iteratedExpr;
6848
6849 // Parse the entirety of the loop-head for a for-in/of loop (so the next
6850 // token is the closing ')'):
6851 //
6852 // for (... in/of ...) ...
6853 // ^next token
6854 //
6855 // ...OR, parse up to the first ';' in a C-style for-loop:
6856 //
6857 // for (...; ...; ...) ...
6858 // ^next token
6859 //
6860 // In either case the subsequent token can be consistently accessed using
6861 // TokenStream::SlashIsDiv semantics.
6862 if (!forHeadStart(yieldHandling, iterKind, &headKind, &startNode,
6863 forLoopLexicalScope, &iteratedExpr)) {
6864 return errorResult();
6865 }
6866
6867 MOZ_ASSERT(headKind == ParseNodeKind::ForIn ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf || headKind == ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(headKind == ParseNodeKind::ForIn
|| headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6869); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6869; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6868 headKind == ParseNodeKind::ForOf ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf || headKind == ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(headKind == ParseNodeKind::ForIn
|| headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6869); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6869; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6869 headKind == ParseNodeKind::ForHead)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf || headKind == ParseNodeKind::ForHead)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(headKind == ParseNodeKind::ForIn
|| headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind
::ForHead))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6869); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf || headKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 6869; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6870
6871 if (iterKind == IteratorKind::Async && headKind != ParseNodeKind::ForOf) {
6872 errorAt(begin, JSMSG_FOR_AWAIT_NOT_OF);
6873 return errorResult();
6874 }
6875
6876 TernaryNodeType forHead;
6877 if (headKind == ParseNodeKind::ForHead) {
6878 Node init = startNode;
6879
6880 // Look for an operand: |for (;| means we might have already examined
6881 // this semicolon with that modifier.
6882 if (!mustMatchToken(TokenKind::Semi, JSMSG_SEMI_AFTER_FOR_INIT)) {
6883 return errorResult();
6884 }
6885
6886 TokenKind tt;
6887 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6888 return errorResult();
6889 }
6890
6891 Node test;
6892 if (tt == TokenKind::Semi) {
6893 test = null();
6894 } else {
6895 MOZ_TRY_VAR(test, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (test) = mozTryVarTempResult_.unwrap(); } while (0)
;
6896 }
6897
6898 if (!mustMatchToken(TokenKind::Semi, JSMSG_SEMI_AFTER_FOR_COND)) {
6899 return errorResult();
6900 }
6901
6902 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
6903 return errorResult();
6904 }
6905
6906 Node update;
6907 if (tt == TokenKind::RightParen) {
6908 update = null();
6909 } else {
6910 MOZ_TRY_VAR(update, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (update) = mozTryVarTempResult_.unwrap(); } while (0)
;
6911 }
6912
6913 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_FOR_CTRL)) {
6914 return errorResult();
6915 }
6916
6917 TokenPos headPos(begin, pos().end);
6918 MOZ_TRY_VAR(forHead, handler_.newForHead(init, test, update, headPos))do { auto mozTryVarTempResult_ = (handler_.newForHead(init, test
, update, headPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forHead) = mozTryVarTempResult_.unwrap(); } while (0)
;
6919 } else {
6920 MOZ_ASSERT(headKind == ParseNodeKind::ForIn ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6921); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 6921; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
6921 headKind == ParseNodeKind::ForOf)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind
::ForOf))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6921); AnnotateMozCrashReason("MOZ_ASSERT" "(" "headKind == ParseNodeKind::ForIn || headKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 6921; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6922
6923 // |target| is the LeftHandSideExpression or declaration to which the
6924 // per-iteration value (an arbitrary value exposed by the iteration
6925 // protocol, or a string naming a property) is assigned.
6926 Node target = startNode;
6927
6928 // Parse the rest of the for-in/of head.
6929 if (headKind == ParseNodeKind::ForIn) {
6930 stmt.refineForKind(StatementKind::ForInLoop);
6931 } else {
6932 stmt.refineForKind(StatementKind::ForOfLoop);
6933 }
6934
6935 // Parser::declaration consumed everything up to the closing ')'. That
6936 // token follows an {Assignment,}Expression and so must be interpreted
6937 // as an operand to be consistent with normal expression tokenizing.
6938 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_FOR_CTRL)) {
6939 return errorResult();
6940 }
6941
6942 TokenPos headPos(begin, pos().end);
6943 MOZ_TRY_VAR(forHead, handler_.newForInOrOfHead(headKind, target,do { auto mozTryVarTempResult_ = (handler_.newForInOrOfHead(headKind
, target, iteratedExpr, headPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forHead) = mozTryVarTempResult_.unwrap(); } while (0)
6944 iteratedExpr, headPos))do { auto mozTryVarTempResult_ = (handler_.newForInOrOfHead(headKind
, target, iteratedExpr, headPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forHead) = mozTryVarTempResult_.unwrap(); } while (0)
;
6945 }
6946
6947 Node body;
6948 MOZ_TRY_VAR(body, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (body) = mozTryVarTempResult_
.unwrap(); } while (0)
;
6949
6950 ForNodeType forLoop;
6951 MOZ_TRY_VAR(forLoop, handler_.newForStatement(begin, forHead, body, iflags))do { auto mozTryVarTempResult_ = (handler_.newForStatement(begin
, forHead, body, iflags)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (forLoop) = mozTryVarTempResult_.unwrap(); } while (0)
;
6952
6953 if (forLoopLexicalScope) {
6954 return finishLexicalScope(*forLoopLexicalScope, forLoop);
6955 }
6956
6957 return forLoop;
6958}
6959
6960template <class ParseHandler, typename Unit>
6961typename ParseHandler::SwitchStatementResult
6962GeneralParser<ParseHandler, Unit>::switchStatement(
6963 YieldHandling yieldHandling) {
6964 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Switch))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Switch))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Switch)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Switch)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 6964); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Switch)"
")"); do { *((volatile int*)__null) = 6964; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
6965 uint32_t begin = pos().begin;
6966
6967 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_SWITCH)) {
6968 return errorResult();
6969 }
6970
6971 Node discriminant;
6972 MOZ_TRY_VAR(discriminant,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (discriminant) = mozTryVarTempResult_.unwrap(); } while (0
)
6973 exprInParens(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (discriminant) = mozTryVarTempResult_.unwrap(); } while (0
)
;
6974
6975 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_SWITCH)) {
6976 return errorResult();
6977 }
6978 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_SWITCH)) {
6979 return errorResult();
6980 }
6981
6982 ParseContext::Statement stmt(pc_, StatementKind::Switch);
6983 ParseContext::Scope scope(this);
6984 if (!scope.init(pc_)) {
6985 return errorResult();
6986 }
6987
6988 ListNodeType caseList;
6989 MOZ_TRY_VAR(caseList, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (caseList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
6990
6991 bool seenDefault = false;
6992 TokenKind tt;
6993 while (true) {
6994 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
6995 return errorResult();
6996 }
6997 if (tt == TokenKind::RightCurly) {
6998 break;
6999 }
7000 uint32_t caseBegin = pos().begin;
7001
7002 Node caseExpr;
7003 switch (tt) {
7004 case TokenKind::Default:
7005 if (seenDefault) {
7006 error(JSMSG_TOO_MANY_DEFAULTS);
7007 return errorResult();
7008 }
7009 seenDefault = true;
7010 caseExpr = null(); // The default case has pn_left == nullptr.
7011 break;
7012
7013 case TokenKind::Case:
7014 MOZ_TRY_VAR(caseExpr,do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
7015 expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
7016 break;
7017
7018 default:
7019 error(JSMSG_BAD_SWITCH);
7020 return errorResult();
7021 }
7022
7023 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_CASE)) {
7024 return errorResult();
7025 }
7026
7027 ListNodeType body;
7028 MOZ_TRY_VAR(body, handler_.newStatementList(pos()))do { auto mozTryVarTempResult_ = (handler_.newStatementList(pos
())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()),
0))) { return mozTryVarTempResult_.propagateErr(); } (body) =
mozTryVarTempResult_.unwrap(); } while (0)
;
7029
7030 bool afterReturn = false;
7031 bool warnedAboutStatementsAfterReturn = false;
7032 uint32_t statementBegin = 0;
7033 while (true) {
7034 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
7035 return errorResult();
7036 }
7037 if (tt == TokenKind::RightCurly || tt == TokenKind::Case ||
7038 tt == TokenKind::Default) {
7039 break;
7040 }
7041 if (afterReturn) {
7042 if (!tokenStream.peekOffset(&statementBegin,
7043 TokenStream::SlashIsRegExp)) {
7044 return errorResult();
7045 }
7046 }
7047 Node stmt;
7048 MOZ_TRY_VAR(stmt, statementListItem(yieldHandling))do { auto mozTryVarTempResult_ = (statementListItem(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (stmt) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7049 if (!warnedAboutStatementsAfterReturn) {
7050 if (afterReturn) {
7051 if (!handler_.isStatementPermittedAfterReturnStatement(stmt)) {
7052 if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
7053 return errorResult();
7054 }
7055
7056 warnedAboutStatementsAfterReturn = true;
7057 }
7058 } else if (handler_.isReturnStatement(stmt)) {
7059 afterReturn = true;
7060 }
7061 }
7062 handler_.addStatementToList(body, stmt);
7063 }
7064
7065 CaseClauseType caseClause;
7066 MOZ_TRY_VAR(caseClause,do { auto mozTryVarTempResult_ = (handler_.newCaseOrDefault(caseBegin
, caseExpr, body)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseClause) = mozTryVarTempResult_.unwrap(); } while (0)
7067 handler_.newCaseOrDefault(caseBegin, caseExpr, body))do { auto mozTryVarTempResult_ = (handler_.newCaseOrDefault(caseBegin
, caseExpr, body)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (caseClause) = mozTryVarTempResult_.unwrap(); } while (0)
;
7068 handler_.addCaseStatementToList(caseList, caseClause);
7069 }
7070
7071 LexicalScopeNodeType lexicalForCaseList;
7072 MOZ_TRY_VAR(lexicalForCaseList, finishLexicalScope(scope, caseList))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, caseList
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (lexicalForCaseList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7073
7074 handler_.setEndPosition(lexicalForCaseList, pos().end);
7075
7076 return handler_.newSwitchStatement(begin, discriminant, lexicalForCaseList,
7077 seenDefault);
7078}
7079
7080template <class ParseHandler, typename Unit>
7081typename ParseHandler::ContinueStatementResult
7082GeneralParser<ParseHandler, Unit>::continueStatement(
7083 YieldHandling yieldHandling) {
7084 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Continue))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Continue))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Continue)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Continue)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7084); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Continue)"
")"); do { *((volatile int*)__null) = 7084; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7085 uint32_t begin = pos().begin;
7086
7087 TaggedParserAtomIndex label;
7088 if (!matchLabel(yieldHandling, &label)) {
7089 return errorResult();
7090 }
7091
7092 auto validity = pc_->checkContinueStatement(label);
7093 if (validity.isErr()) {
7094 switch (validity.unwrapErr()) {
7095 case ParseContext::ContinueStatementError::NotInALoop:
7096 errorAt(begin, JSMSG_BAD_CONTINUE);
7097 break;
7098 case ParseContext::ContinueStatementError::LabelNotFound:
7099 error(JSMSG_LABEL_NOT_FOUND);
7100 break;
7101 }
7102 return errorResult();
7103 }
7104
7105 if (!matchOrInsertSemicolon()) {
7106 return errorResult();
7107 }
7108
7109 return handler_.newContinueStatement(label, TokenPos(begin, pos().end));
7110}
7111
7112template <class ParseHandler, typename Unit>
7113typename ParseHandler::BreakStatementResult
7114GeneralParser<ParseHandler, Unit>::breakStatement(YieldHandling yieldHandling) {
7115 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Break))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Break))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Break)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Break)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7115); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Break)"
")"); do { *((volatile int*)__null) = 7115; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7116 uint32_t begin = pos().begin;
7117
7118 TaggedParserAtomIndex label;
7119 if (!matchLabel(yieldHandling, &label)) {
7120 return errorResult();
7121 }
7122
7123 auto validity = pc_->checkBreakStatement(label);
7124 if (validity.isErr()) {
7125 switch (validity.unwrapErr()) {
7126 case ParseContext::BreakStatementError::ToughBreak:
7127 errorAt(begin, JSMSG_TOUGH_BREAK);
7128 return errorResult();
7129 case ParseContext::BreakStatementError::LabelNotFound:
7130 error(JSMSG_LABEL_NOT_FOUND);
7131 return errorResult();
7132 }
7133 }
7134
7135 if (!matchOrInsertSemicolon()) {
7136 return errorResult();
7137 }
7138
7139 return handler_.newBreakStatement(label, TokenPos(begin, pos().end));
7140}
7141
7142template <class ParseHandler, typename Unit>
7143typename ParseHandler::UnaryNodeResult
7144GeneralParser<ParseHandler, Unit>::returnStatement(
7145 YieldHandling yieldHandling) {
7146 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Return))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Return))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Return)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Return)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7146); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Return)"
")"); do { *((volatile int*)__null) = 7146; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7147 uint32_t begin = pos().begin;
7148
7149 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7149); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 7149; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7150
7151 // Parse an optional operand.
7152 //
7153 // This is ugly, but we don't want to require a semicolon.
7154 Node exprNode;
7155 TokenKind tt = TokenKind::Eof;
7156 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7157 return errorResult();
7158 }
7159 switch (tt) {
7160 case TokenKind::Eol:
7161 case TokenKind::Eof:
7162 case TokenKind::Semi:
7163 case TokenKind::RightCurly:
7164 exprNode = null();
7165 break;
7166 default: {
7167 MOZ_TRY_VAR(exprNode,do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
7168 expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
7169 }
7170 }
7171
7172 if (!matchOrInsertSemicolon()) {
7173 return errorResult();
7174 }
7175
7176 return handler_.newReturnStatement(exprNode, TokenPos(begin, pos().end));
7177}
7178
7179template <class ParseHandler, typename Unit>
7180typename ParseHandler::UnaryNodeResult
7181GeneralParser<ParseHandler, Unit>::yieldExpression(InHandling inHandling) {
7182 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Yield))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Yield))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Yield)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Yield)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7182); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Yield)"
")"); do { *((volatile int*)__null) = 7182; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7183 uint32_t begin = pos().begin;
7184
7185 MOZ_ASSERT(pc_->isGenerator())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isGenerator())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isGenerator()))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isGenerator()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7185); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isGenerator()"
")"); do { *((volatile int*)__null) = 7185; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7186 MOZ_ASSERT(pc_->isFunctionBox())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7186); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 7186; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7187
7188 pc_->lastYieldOffset = begin;
7189
7190 Node exprNode;
7191 ParseNodeKind kind = ParseNodeKind::YieldExpr;
7192 TokenKind tt = TokenKind::Eof;
7193 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7194 return errorResult();
7195 }
7196 switch (tt) {
7197 // TokenKind::Eol is special; it implements the [no LineTerminator here]
7198 // quirk in the grammar.
7199 case TokenKind::Eol:
7200 // The rest of these make up the complete set of tokens that can
7201 // appear after any of the places where AssignmentExpression is used
7202 // throughout the grammar. Conveniently, none of them can also be the
7203 // start an expression.
7204 case TokenKind::Eof:
7205 case TokenKind::Semi:
7206 case TokenKind::RightCurly:
7207 case TokenKind::RightBracket:
7208 case TokenKind::RightParen:
7209 case TokenKind::Colon:
7210 case TokenKind::Comma:
7211 case TokenKind::In: // Annex B.3.6 `for (x = yield in y) ;`
7212 // No value.
7213 exprNode = null();
7214 break;
7215 case TokenKind::Mul:
7216 kind = ParseNodeKind::YieldStarExpr;
7217 tokenStream.consumeKnownToken(TokenKind::Mul, TokenStream::SlashIsRegExp);
7218 [[fallthrough]];
7219 default:
7220 MOZ_TRY_VAR(exprNode,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, YieldIsKeyword
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
7221 assignExpr(inHandling, YieldIsKeyword, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, YieldIsKeyword
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
7222 }
7223 if (kind == ParseNodeKind::YieldStarExpr) {
7224 return handler_.newYieldStarExpression(begin, exprNode);
7225 }
7226 return handler_.newYieldExpression(begin, exprNode);
7227}
7228
7229template <class ParseHandler, typename Unit>
7230typename ParseHandler::BinaryNodeResult
7231GeneralParser<ParseHandler, Unit>::withStatement(YieldHandling yieldHandling) {
7232 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::With))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::With))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::With)))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::With)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7232); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 7232; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7233 uint32_t begin = pos().begin;
7234
7235 if (pc_->sc()->strict()) {
7236 if (!strictModeError(JSMSG_STRICT_CODE_WITH)) {
7237 return errorResult();
7238 }
7239 }
7240
7241 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_WITH)) {
7242 return errorResult();
7243 }
7244
7245 Node objectExpr;
7246 MOZ_TRY_VAR(objectExpr,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (objectExpr) = mozTryVarTempResult_.unwrap(); } while (0)
7247 exprInParens(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (objectExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
7248
7249 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_WITH)) {
7250 return errorResult();
7251 }
7252
7253 Node innerBlock;
7254 {
7255 ParseContext::Statement stmt(pc_, StatementKind::With);
7256 MOZ_TRY_VAR(innerBlock, statement(yieldHandling))do { auto mozTryVarTempResult_ = (statement(yieldHandling)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (innerBlock) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7257 }
7258
7259 pc_->sc()->setBindingsAccessedDynamically();
7260
7261 return handler_.newWithStatement(begin, objectExpr, innerBlock);
7262}
7263
7264template <class ParseHandler, typename Unit>
7265typename ParseHandler::NodeResult
7266GeneralParser<ParseHandler, Unit>::labeledItem(YieldHandling yieldHandling) {
7267 TokenKind tt;
7268 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
7269 return errorResult();
7270 }
7271
7272 if (tt == TokenKind::Function) {
7273 TokenKind next;
7274 if (!tokenStream.peekToken(&next)) {
7275 return errorResult();
7276 }
7277
7278 // GeneratorDeclaration is only matched by HoistableDeclaration in
7279 // StatementListItem, so generators can't be inside labels.
7280 if (next == TokenKind::Mul) {
7281 error(JSMSG_GENERATOR_LABEL);
7282 return errorResult();
7283 }
7284
7285 // Per 13.13.1 it's a syntax error if LabelledItem: FunctionDeclaration
7286 // is ever matched. Per Annex B.3.2 that modifies this text, this
7287 // applies only to strict mode code.
7288 if (pc_->sc()->strict()) {
7289 error(JSMSG_FUNCTION_LABEL);
7290 return errorResult();
7291 }
7292
7293 return functionStmt(pos().begin, yieldHandling, NameRequired);
7294 }
7295
7296 anyChars.ungetToken();
7297 return statement(yieldHandling);
7298}
7299
7300template <class ParseHandler, typename Unit>
7301typename ParseHandler::LabeledStatementResult
7302GeneralParser<ParseHandler, Unit>::labeledStatement(
7303 YieldHandling yieldHandling) {
7304 TaggedParserAtomIndex label = labelIdentifier(yieldHandling);
7305 if (!label) {
7306 return errorResult();
7307 }
7308
7309 auto hasSameLabel = [&label](ParseContext::LabelStatement* stmt) {
7310 return stmt->label() == label;
7311 };
7312
7313 uint32_t begin = pos().begin;
7314
7315 if (pc_->template findInnermostStatement<ParseContext::LabelStatement>(
7316 hasSameLabel)) {
7317 errorAt(begin, JSMSG_DUPLICATE_LABEL);
7318 return errorResult();
7319 }
7320
7321 tokenStream.consumeKnownToken(TokenKind::Colon);
7322
7323 /* Push a label struct and parse the statement. */
7324 ParseContext::LabelStatement stmt(pc_, label);
7325 Node pn;
7326 MOZ_TRY_VAR(pn, labeledItem(yieldHandling))do { auto mozTryVarTempResult_ = (labeledItem(yieldHandling))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7327
7328 return handler_.newLabeledStatement(label, pn, begin);
7329}
7330
7331template <class ParseHandler, typename Unit>
7332typename ParseHandler::UnaryNodeResult
7333GeneralParser<ParseHandler, Unit>::throwStatement(YieldHandling yieldHandling) {
7334 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Throw))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Throw))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Throw)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Throw)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7334); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Throw)"
")"); do { *((volatile int*)__null) = 7334; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7335 uint32_t begin = pos().begin;
7336
7337 /* ECMA-262 Edition 3 says 'throw [no LineTerminator here] Expr'. */
7338 TokenKind tt = TokenKind::Eof;
7339 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
7340 return errorResult();
7341 }
7342 if (tt == TokenKind::Eof || tt == TokenKind::Semi ||
7343 tt == TokenKind::RightCurly) {
7344 error(JSMSG_MISSING_EXPR_AFTER_THROW);
7345 return errorResult();
7346 }
7347 if (tt == TokenKind::Eol) {
7348 error(JSMSG_LINE_BREAK_AFTER_THROW);
7349 return errorResult();
7350 }
7351
7352 Node throwExpr;
7353 MOZ_TRY_VAR(throwExpr, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (throwExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
7354
7355 if (!matchOrInsertSemicolon()) {
7356 return errorResult();
7357 }
7358
7359 return handler_.newThrowStatement(throwExpr, TokenPos(begin, pos().end));
7360}
7361
7362template <class ParseHandler, typename Unit>
7363typename ParseHandler::TernaryNodeResult
7364GeneralParser<ParseHandler, Unit>::tryStatement(YieldHandling yieldHandling) {
7365 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Try))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Try))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Try)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Try)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7365); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Try)"
")"); do { *((volatile int*)__null) = 7365; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7366 uint32_t begin = pos().begin;
7367
7368 /*
7369 * try nodes are ternary.
7370 * kid1 is the try statement
7371 * kid2 is the catch node list or null
7372 * kid3 is the finally statement
7373 *
7374 * catch nodes are binary.
7375 * left is the catch-name/pattern or null
7376 * right is the catch block
7377 *
7378 * catch lvalue nodes are either:
7379 * a single identifier
7380 * TokenKind::RightBracket for a destructuring left-hand side
7381 * TokenKind::RightCurly for a destructuring left-hand side
7382 *
7383 * finally nodes are TokenKind::LeftCurly statement lists.
7384 */
7385
7386 Node innerBlock;
7387 {
7388 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_TRY)) {
7389 return errorResult();
7390 }
7391
7392 uint32_t openedPos = pos().begin;
7393
7394 ParseContext::Statement stmt(pc_, StatementKind::Try);
7395 ParseContext::Scope scope(this);
7396 if (!scope.init(pc_)) {
7397 return errorResult();
7398 }
7399
7400 MOZ_TRY_VAR(innerBlock, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7401
7402 MOZ_TRY_VAR(innerBlock, finishLexicalScope(scope, innerBlock))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, innerBlock
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (innerBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7403
7404 if (!mustMatchToken(
7405 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7406 this->reportMissingClosing(JSMSG_CURLY_AFTER_TRY,
7407 JSMSG_CURLY_OPENED, openedPos);
7408 })) {
7409 return errorResult();
7410 }
7411 }
7412
7413 LexicalScopeNodeType catchScope = null();
7414 TokenKind tt;
7415 if (!tokenStream.getToken(&tt)) {
7416 return errorResult();
7417 }
7418 if (tt == TokenKind::Catch) {
7419 /*
7420 * Create a lexical scope node around the whole catch clause,
7421 * including the head.
7422 */
7423 ParseContext::Statement stmt(pc_, StatementKind::Catch);
7424 ParseContext::Scope scope(this);
7425 if (!scope.init(pc_)) {
7426 return errorResult();
7427 }
7428
7429 /*
7430 * Legal catch forms are:
7431 * catch (lhs) {
7432 * catch {
7433 * where lhs is a name or a destructuring left-hand side.
7434 */
7435 bool omittedBinding;
7436 if (!tokenStream.matchToken(&omittedBinding, TokenKind::LeftCurly)) {
7437 return errorResult();
7438 }
7439
7440 Node catchName;
7441 if (omittedBinding) {
7442 catchName = null();
7443 } else {
7444 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_CATCH)) {
7445 return errorResult();
7446 }
7447
7448 if (!tokenStream.getToken(&tt)) {
7449 return errorResult();
7450 }
7451 switch (tt) {
7452 case TokenKind::LeftBracket:
7453 case TokenKind::LeftCurly:
7454 MOZ_TRY_VAR(catchName,do { auto mozTryVarTempResult_ = (destructuringDeclaration(DeclarationKind
::CatchParameter, yieldHandling, tt)); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7455 destructuringDeclaration(DeclarationKind::CatchParameter,do { auto mozTryVarTempResult_ = (destructuringDeclaration(DeclarationKind
::CatchParameter, yieldHandling, tt)); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7456 yieldHandling, tt))do { auto mozTryVarTempResult_ = (destructuringDeclaration(DeclarationKind
::CatchParameter, yieldHandling, tt)); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
;
7457 break;
7458
7459 default: {
7460 if (!TokenKindIsPossibleIdentifierName(tt)) {
7461 error(JSMSG_CATCH_IDENTIFIER);
7462 return errorResult();
7463 }
7464
7465 MOZ_TRY_VAR(catchName,do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7466 bindingIdentifier(DeclarationKind::SimpleCatchParameter,do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
7467 yieldHandling))do { auto mozTryVarTempResult_ = (bindingIdentifier(DeclarationKind
::SimpleCatchParameter, yieldHandling)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (catchName) = mozTryVarTempResult_.unwrap(
); } while (0)
;
7468 break;
7469 }
7470 }
7471
7472 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_CATCH)) {
7473 return errorResult();
7474 }
7475
7476 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_CATCH)) {
7477 return errorResult();
7478 }
7479 }
7480
7481 LexicalScopeNodeType catchBody;
7482 MOZ_TRY_VAR(catchBody, catchBlockStatement(yieldHandling, scope))do { auto mozTryVarTempResult_ = (catchBlockStatement(yieldHandling
, scope)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (catchBody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7483
7484 MOZ_TRY_VAR(catchScope, finishLexicalScope(scope, catchBody))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, catchBody
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (catchScope
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7485
7486 if (!handler_.setupCatchScope(catchScope, catchName, catchBody)) {
7487 return errorResult();
7488 }
7489 handler_.setEndPosition(catchScope, pos().end);
7490
7491 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
7492 return errorResult();
7493 }
7494 }
7495
7496 Node finallyBlock = null();
7497
7498 if (tt == TokenKind::Finally) {
7499 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_FINALLY)) {
7500 return errorResult();
7501 }
7502
7503 uint32_t openedPos = pos().begin;
7504
7505 ParseContext::Statement stmt(pc_, StatementKind::Finally);
7506 ParseContext::Scope scope(this);
7507 if (!scope.init(pc_)) {
7508 return errorResult();
7509 }
7510
7511 MOZ_TRY_VAR(finallyBlock, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (finallyBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7512
7513 MOZ_TRY_VAR(finallyBlock, finishLexicalScope(scope, finallyBlock))do { auto mozTryVarTempResult_ = (finishLexicalScope(scope, finallyBlock
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (finallyBlock
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7514
7515 if (!mustMatchToken(
7516 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7517 this->reportMissingClosing(JSMSG_CURLY_AFTER_FINALLY,
7518 JSMSG_CURLY_OPENED, openedPos);
7519 })) {
7520 return errorResult();
7521 }
7522 } else {
7523 anyChars.ungetToken();
7524 }
7525 if (!catchScope && !finallyBlock) {
7526 error(JSMSG_CATCH_OR_FINALLY);
7527 return errorResult();
7528 }
7529
7530 return handler_.newTryStatement(begin, innerBlock, catchScope, finallyBlock);
7531}
7532
7533template <class ParseHandler, typename Unit>
7534typename ParseHandler::LexicalScopeNodeResult
7535GeneralParser<ParseHandler, Unit>::catchBlockStatement(
7536 YieldHandling yieldHandling, ParseContext::Scope& catchParamScope) {
7537 uint32_t openedPos = pos().begin;
7538
7539 ParseContext::Statement stmt(pc_, StatementKind::Block);
7540
7541 // ES 13.15.7 CatchClauseEvaluation
7542 //
7543 // Step 8 means that the body of a catch block always has an additional
7544 // lexical scope.
7545 ParseContext::Scope scope(this);
7546 if (!scope.init(pc_)) {
7547 return errorResult();
7548 }
7549
7550 // The catch parameter names cannot be redeclared inside the catch
7551 // block, so declare the name in the inner scope.
7552 if (!scope.addCatchParameters(pc_, catchParamScope)) {
7553 return errorResult();
7554 }
7555
7556 ListNodeType list;
7557 MOZ_TRY_VAR(list, statementList(yieldHandling))do { auto mozTryVarTempResult_ = (statementList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (list) = mozTryVarTempResult_
.unwrap(); } while (0)
;
7558
7559 if (!mustMatchToken(
7560 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
7561 this->reportMissingClosing(JSMSG_CURLY_AFTER_CATCH,
7562 JSMSG_CURLY_OPENED, openedPos);
7563 })) {
7564 return errorResult();
7565 }
7566
7567 // The catch parameter names are not bound in the body scope, so remove
7568 // them before generating bindings.
7569 scope.removeCatchParameters(pc_, catchParamScope);
7570 return finishLexicalScope(scope, list);
7571}
7572
7573template <class ParseHandler, typename Unit>
7574typename ParseHandler::DebuggerStatementResult
7575GeneralParser<ParseHandler, Unit>::debuggerStatement() {
7576 TokenPos p;
7577 p.begin = pos().begin;
7578 if (!matchOrInsertSemicolon()) {
7579 return errorResult();
7580 }
7581 p.end = pos().end;
7582
7583 return handler_.newDebuggerStatement(p);
7584}
7585
7586static AccessorType ToAccessorType(PropertyType propType) {
7587 switch (propType) {
7588 case PropertyType::Getter:
7589 return AccessorType::Getter;
7590 case PropertyType::Setter:
7591 return AccessorType::Setter;
7592 case PropertyType::Normal:
7593 case PropertyType::Method:
7594 case PropertyType::GeneratorMethod:
7595 case PropertyType::AsyncMethod:
7596 case PropertyType::AsyncGeneratorMethod:
7597 case PropertyType::Constructor:
7598 case PropertyType::DerivedConstructor:
7599 return AccessorType::None;
7600 default:
7601 MOZ_CRASH("unexpected property type")do { do { } while (false); MOZ_ReportCrash("" "unexpected property type"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 7601); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected property type"
")"); do { *((volatile int*)__null) = 7601; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
7602 }
7603}
7604
7605#ifdef ENABLE_DECORATORS
7606template <class ParseHandler, typename Unit>
7607typename ParseHandler::ListNodeResult
7608GeneralParser<ParseHandler, Unit>::decoratorList(YieldHandling yieldHandling) {
7609 ListNodeType decorators;
7610 MOZ_TRY_VAR(decorators,do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::DecoratorList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decorators) = mozTryVarTempResult_.unwrap(); } while (0)
7611 handler_.newList(ParseNodeKind::DecoratorList, pos()))do { auto mozTryVarTempResult_ = (handler_.newList(ParseNodeKind
::DecoratorList, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decorators) = mozTryVarTempResult_.unwrap(); } while (0)
;
7612
7613 // Build a decorator list element. At each entry point to this loop we have
7614 // already consumed the |@| token
7615 TokenKind tt;
7616 for (;;) {
7617 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
7618 return errorResult();
7619 }
7620
7621 Node decorator;
7622 MOZ_TRY_VAR(decorator, decoratorExpr(yieldHandling, tt))do { auto mozTryVarTempResult_ = (decoratorExpr(yieldHandling
, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()
), 0))) { return mozTryVarTempResult_.propagateErr(); } (decorator
) = mozTryVarTempResult_.unwrap(); } while (0)
;
7623
7624 handler_.addList(decorators, decorator);
7625
7626 if (!tokenStream.getToken(&tt)) {
7627 return errorResult();
7628 }
7629 if (tt != TokenKind::At) {
7630 anyChars.ungetToken();
7631 break;
7632 }
7633 }
7634 return decorators;
7635}
7636#endif
7637
7638template <class ParseHandler, typename Unit>
7639bool GeneralParser<ParseHandler, Unit>::classMember(
7640 YieldHandling yieldHandling, const ParseContext::ClassStatement& classStmt,
7641 TaggedParserAtomIndex className, uint32_t classStartOffset,
7642 HasHeritage hasHeritage, ClassInitializedMembers& classInitializedMembers,
7643 ListNodeType& classMembers, bool* done) {
7644 *done = false;
7645
7646 TokenKind tt;
7647 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
7648 return false;
7649 }
7650 if (tt == TokenKind::RightCurly) {
7651 *done = true;
7652 return true;
7653 }
7654
7655 if (tt == TokenKind::Semi) {
7656 return true;
7657 }
7658
7659#ifdef ENABLE_DECORATORS
7660 ListNodeType decorators = null();
7661 if (tt == TokenKind::At) {
7662 MOZ_TRY_VAR_OR_RETURN(decorators, decoratorList(yieldHandling), false)do { auto parserTryVarTempResult_ = (decoratorList(yieldHandling
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (decorators) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7663
7664 if (!tokenStream.getToken(&tt, TokenStream::SlashIsInvalid)) {
7665 return false;
7666 }
7667 }
7668#endif
7669
7670 bool isStatic = false;
7671 if (tt == TokenKind::Static) {
7672 if (!tokenStream.peekToken(&tt)) {
7673 return false;
7674 }
7675
7676 if (tt == TokenKind::LeftCurly) {
7677 /* Parsing static class block: static { ... } */
7678 FunctionNodeType staticBlockBody;
7679 MOZ_TRY_VAR_OR_RETURN(staticBlockBody,do { auto parserTryVarTempResult_ = (staticClassBlock(classInitializedMembers
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (staticBlockBody) = parserTryVarTempResult_
.unwrap(); } while (0)
7680 staticClassBlock(classInitializedMembers), false)do { auto parserTryVarTempResult_ = (staticClassBlock(classInitializedMembers
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (staticBlockBody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7681
7682 StaticClassBlockType classBlock;
7683 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newStaticClassBlock
(staticBlockBody)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (classBlock) = parserTryVarTempResult_
.unwrap(); } while (0)
7684 classBlock, handler_.newStaticClassBlock(staticBlockBody), false)do { auto parserTryVarTempResult_ = (handler_.newStaticClassBlock
(staticBlockBody)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (classBlock) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7685
7686 return handler_.addClassMemberDefinition(classMembers, classBlock);
7687 }
7688
7689 if (tt != TokenKind::LeftParen && tt != TokenKind::Assign &&
7690 tt != TokenKind::Semi && tt != TokenKind::RightCurly) {
7691 isStatic = true;
7692 } else {
7693 anyChars.ungetToken();
7694 }
7695 } else {
7696 anyChars.ungetToken();
7697 }
7698
7699 uint32_t propNameOffset;
7700 if (!tokenStream.peekOffset(&propNameOffset, TokenStream::SlashIsInvalid)) {
7701 return false;
7702 }
7703
7704 TaggedParserAtomIndex propAtom;
7705 PropertyType propType;
7706 Node propName;
7707 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7708 propName,do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7709 propertyOrMethodName(yieldHandling, PropertyNameInClass,do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7710 /* maybeDecl = */ Nothing(), classMembers, &propType,do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7711 &propAtom),do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7712 false)do { auto parserTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInClass, Nothing(), classMembers, &propType
, &propAtom)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7713
7714 if (propType == PropertyType::Field ||
7715 propType == PropertyType::FieldWithAccessor) {
7716 if (isStatic) {
7717 if (propAtom == TaggedParserAtomIndex::WellKnown::prototype()) {
7718 errorAt(propNameOffset, JSMSG_CLASS_STATIC_PROTO);
7719 return false;
7720 }
7721 }
7722
7723 if (propAtom == TaggedParserAtomIndex::WellKnown::constructor()) {
7724 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7725 return false;
7726 }
7727
7728 if (handler_.isPrivateName(propName)) {
7729 if (propAtom == TaggedParserAtomIndex::WellKnown::hash_constructor_()) {
7730 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7731 return false;
7732 }
7733
7734 auto privateName = propAtom;
7735 if (!noteDeclaredPrivateName(
7736 propName, privateName, propType,
7737 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7738 pos())) {
7739 return false;
7740 }
7741 }
7742
7743#ifdef ENABLE_DECORATORS
7744 ClassMethodType accessorGetterNode = null();
7745 ClassMethodType accessorSetterNode = null();
7746 if (propType == PropertyType::FieldWithAccessor) {
7747 // Decorators Proposal
7748 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-runtime-semantics-classfielddefinitionevaluation
7749 //
7750 // FieldDefinition : accessor ClassElementName Initializeropt
7751 //
7752 // Step 1. Let name be the result of evaluating ClassElementName.
7753 // ...
7754 // Step 3. Let privateStateDesc be the string-concatenation of name
7755 // and " accessor storage".
7756 StringBuilder privateStateDesc(fc_);
7757 if (!privateStateDesc.append(this->parserAtoms(), propAtom)) {
7758 return false;
7759 }
7760 if (!privateStateDesc.append(" accessor storage")) {
7761 return false;
7762 }
7763 // Step 4. Let privateStateName be a new Private Name whose
7764 // [[Description]] value is privateStateDesc.
7765 TokenPos propNamePos(propNameOffset, pos().end);
7766 auto privateStateName =
7767 privateStateDesc.finishParserAtom(this->parserAtoms(), fc_);
7768 if (!noteDeclaredPrivateName(
7769 propName, privateStateName, propType,
7770 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7771 propNamePos)) {
7772 return false;
7773 }
7774
7775 // Step 5. Let getter be MakeAutoAccessorGetter(homeObject, name,
7776 // privateStateName).
7777 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7778 accessorGetterNode,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7779 synthesizeAccessor(propName, propNamePos, propAtom, privateStateName,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7780 isStatic, FunctionSyntaxKind::Getter,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7781 classInitializedMembers),do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7782 false)do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Getter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorGetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
;
7783
7784 // If the accessor is not decorated or is a non-static private field,
7785 // add it to the class here. Otherwise, we'll handle this when the
7786 // decorators are called. We don't need to keep a reference to the node
7787 // after this except for non-static private accessors. Please see the
7788 // comment in the definition of ClassField for details.
7789 bool addAccessorImmediately =
7790 !decorators || (!isStatic && handler_.isPrivateName(propName));
7791 if (addAccessorImmediately) {
7792 if (!handler_.addClassMemberDefinition(classMembers,
7793 accessorGetterNode)) {
7794 return false;
7795 }
7796 if (!handler_.isPrivateName(propName)) {
7797 accessorGetterNode = null();
7798 }
7799 }
7800
7801 // Step 6. Let setter be MakeAutoAccessorSetter(homeObject, name,
7802 // privateStateName).
7803 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7804 accessorSetterNode,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7805 synthesizeAccessor(propName, propNamePos, propAtom, privateStateName,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7806 isStatic, FunctionSyntaxKind::Setter,do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7807 classInitializedMembers),do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
7808 false)do { auto parserTryVarTempResult_ = (synthesizeAccessor(propName
, propNamePos, propAtom, privateStateName, isStatic, FunctionSyntaxKind
::Setter, classInitializedMembers)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
accessorSetterNode) = parserTryVarTempResult_.unwrap(); } while
(0)
;
7809
7810 if (addAccessorImmediately) {
7811 if (!handler_.addClassMemberDefinition(classMembers,
7812 accessorSetterNode)) {
7813 return false;
7814 }
7815 if (!handler_.isPrivateName(propName)) {
7816 accessorSetterNode = null();
7817 }
7818 }
7819
7820 // Step 10. Return ClassElementDefinition Record { [[Key]]: name,
7821 // [[Kind]]: accessor, [[Get]]: getter, [[Set]]: setter,
7822 // [[BackingStorageKey]]: privateStateName, [[Initializers]]:
7823 // initializers, [[Decorators]]: empty }.
7824 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newPrivateName(
privateStateName, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
7825 propName, handler_.newPrivateName(privateStateName, pos()), false)do { auto parserTryVarTempResult_ = (handler_.newPrivateName(
privateStateName, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (propName) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7826 propAtom = privateStateName;
7827 // We maintain `decorators` here to perform this step at the same time:
7828 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-static-semantics-classelementevaluation
7829 // 4. Set fieldDefinition.[[Decorators]] to decorators.
7830 }
7831#endif
7832 if (isStatic) {
7833 classInitializedMembers.staticFields++;
7834 } else {
7835 classInitializedMembers.instanceFields++;
7836#ifdef ENABLE_DECORATORS
7837 if (decorators) {
7838 classInitializedMembers.hasInstanceDecorators = true;
7839 }
7840#endif
7841 }
7842
7843 TokenPos propNamePos(propNameOffset, pos().end);
7844 FunctionNodeType initializer;
7845 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7846 initializer,do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7847 fieldInitializerOpt(propNamePos, propName, propAtom,do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7848 classInitializedMembers, isStatic, hasHeritage),do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
7849 false)do { auto parserTryVarTempResult_ = (fieldInitializerOpt(propNamePos
, propName, propAtom, classInitializedMembers, isStatic, hasHeritage
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (initializer) = parserTryVarTempResult_
.unwrap(); } while (0)
;
7850
7851 if (!matchOrInsertSemicolon(TokenStream::SlashIsInvalid)) {
7852 return false;
7853 }
7854
7855 ClassFieldType field;
7856 MOZ_TRY_VAR_OR_RETURN(field,do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7857 handler_.newClassFieldDefinition(do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7858 propName, initializer, isStaticdo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7859#ifdef ENABLE_DECORATORSdo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7860 ,do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7861 decorators, accessorGetterNode, accessorSetterNodedo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7862#endifdo { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7863 ),do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
7864 false)do { auto parserTryVarTempResult_ = (handler_.newClassFieldDefinition
( propName, initializer, isStatic ifdef ENABLE_DECORATORS , decorators
, accessorGetterNode, accessorSetterNode endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(field) = parserTryVarTempResult_.unwrap(); } while (0)
;
7865
7866 return handler_.addClassMemberDefinition(classMembers, field);
7867 }
7868
7869 if (propType != PropertyType::Getter && propType != PropertyType::Setter &&
7870 propType != PropertyType::Method &&
7871 propType != PropertyType::GeneratorMethod &&
7872 propType != PropertyType::AsyncMethod &&
7873 propType != PropertyType::AsyncGeneratorMethod) {
7874 errorAt(propNameOffset, JSMSG_BAD_CLASS_MEMBER_DEF);
7875 return false;
7876 }
7877
7878 bool isConstructor =
7879 !isStatic && propAtom == TaggedParserAtomIndex::WellKnown::constructor();
7880 if (isConstructor) {
7881 if (propType != PropertyType::Method) {
7882 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7883 return false;
7884 }
7885 if (classStmt.constructorBox) {
7886 errorAt(propNameOffset, JSMSG_DUPLICATE_CONSTRUCTOR);
7887 return false;
7888 }
7889 propType = hasHeritage == HasHeritage::Yes
7890 ? PropertyType::DerivedConstructor
7891 : PropertyType::Constructor;
7892 } else if (isStatic &&
7893 propAtom == TaggedParserAtomIndex::WellKnown::prototype()) {
7894 errorAt(propNameOffset, JSMSG_CLASS_STATIC_PROTO);
7895 return false;
7896 }
7897
7898 TaggedParserAtomIndex funName;
7899 switch (propType) {
7900 case PropertyType::Getter:
7901 case PropertyType::Setter: {
7902 bool hasStaticName =
7903 !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom;
7904 if (hasStaticName) {
7905 funName = prefixAccessorName(propType, propAtom);
7906 if (!funName) {
7907 return false;
7908 }
7909 }
7910 break;
7911 }
7912 case PropertyType::Constructor:
7913 case PropertyType::DerivedConstructor:
7914 funName = className;
7915 break;
7916 default:
7917 if (!anyChars.isCurrentTokenType(TokenKind::RightBracket)) {
7918 funName = propAtom;
7919 }
7920 }
7921
7922 // When |super()| is invoked, we search for the nearest scope containing
7923 // |.initializers| to initialize the class fields. This set-up precludes
7924 // declaring |.initializers| in the class scope, because in some syntactic
7925 // contexts |super()| can appear nested in a class, while actually belonging
7926 // to an outer class definition.
7927 //
7928 // Example:
7929 // class Outer extends Base {
7930 // field = 1;
7931 // constructor() {
7932 // class Inner {
7933 // field = 2;
7934 //
7935 // // The super() call in the computed property name mustn't access
7936 // // Inner's |.initializers| array, but instead Outer's.
7937 // [super()]() {}
7938 // }
7939 // }
7940 // }
7941 Maybe<ParseContext::Scope> dotInitializersScope;
7942 if (isConstructor && !options().selfHostingMode) {
7943 dotInitializersScope.emplace(this);
7944 if (!dotInitializersScope->init(pc_)) {
7945 return false;
7946 }
7947
7948 if (!noteDeclaredName(TaggedParserAtomIndex::WellKnown::dot_initializers_(),
7949 DeclarationKind::Let, pos())) {
7950 return false;
7951 }
7952
7953#ifdef ENABLE_DECORATORS
7954 if (!noteDeclaredName(
7955 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
7956 DeclarationKind::Let, pos())) {
7957 return false;
7958 }
7959#endif
7960 }
7961
7962 // Calling toString on constructors need to return the source text for
7963 // the entire class. The end offset is unknown at this point in
7964 // parsing and will be amended when class parsing finishes below.
7965 FunctionNodeType funNode;
7966 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7967 funNode,do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7968 methodDefinition(isConstructor ? classStartOffset : propNameOffset,do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7969 propType, funName),do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
7970 false)do { auto parserTryVarTempResult_ = (methodDefinition(isConstructor
? classStartOffset : propNameOffset, propType, funName)); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (funNode) = parserTryVarTempResult_.unwrap
(); } while (0)
;
7971
7972 AccessorType atype = ToAccessorType(propType);
7973
7974 Maybe<FunctionNodeType> initializerIfPrivate = Nothing();
7975 if (handler_.isPrivateName(propName)) {
7976 if (propAtom == TaggedParserAtomIndex::WellKnown::hash_constructor_()) {
7977 // #constructor is an invalid private name.
7978 errorAt(propNameOffset, JSMSG_BAD_CONSTRUCTOR_DEF);
7979 return false;
7980 }
7981
7982 TaggedParserAtomIndex privateName = propAtom;
7983 if (!noteDeclaredPrivateName(
7984 propName, privateName, propType,
7985 isStatic ? FieldPlacement::Static : FieldPlacement::Instance,
7986 pos())) {
7987 return false;
7988 }
7989
7990 // Private non-static methods are stored in the class body environment.
7991 // Private non-static accessors are stamped onto every instance using
7992 // initializers. Private static methods are stamped onto the constructor
7993 // during class evaluation; see BytecodeEmitter::emitPropertyList.
7994 if (!isStatic) {
7995 if (atype == AccessorType::Getter || atype == AccessorType::Setter) {
7996 classInitializedMembers.privateAccessors++;
7997 TokenPos propNamePos(propNameOffset, pos().end);
7998 FunctionNodeType initializerNode;
7999 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8000 initializerNode,do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8001 synthesizePrivateMethodInitializer(propAtom, atype, propNamePos),do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8002 false)do { auto parserTryVarTempResult_ = (synthesizePrivateMethodInitializer
(propAtom, atype, propNamePos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (initializerNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8003 initializerIfPrivate = Some(initializerNode);
8004 } else {
8005 MOZ_ASSERT(atype == AccessorType::None)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(atype == AccessorType::None)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(atype == AccessorType::None)
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("atype == AccessorType::None"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8005); AnnotateMozCrashReason("MOZ_ASSERT" "(" "atype == AccessorType::None"
")"); do { *((volatile int*)__null) = 8005; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8006 classInitializedMembers.privateMethods++;
8007 }
8008 }
8009 }
8010
8011#ifdef ENABLE_DECORATORS
8012 if (decorators) {
8013 classInitializedMembers.hasInstanceDecorators = true;
8014 }
8015#endif
8016
8017 Node method;
8018 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8019 method,do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8020 handler_.newClassMethodDefinition(propName, funNode, atype, isStatic,do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8021 initializerIfPrivatedo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8022#ifdef ENABLE_DECORATORSdo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8023 ,do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8024 decoratorsdo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8025#endifdo { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8026 ),do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8027 false)do { auto parserTryVarTempResult_ = (handler_.newClassMethodDefinition
(propName, funNode, atype, isStatic, initializerIfPrivate ifdef
ENABLE_DECORATORS , decorators endif )); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
;
8028
8029 if (dotInitializersScope.isSome()) {
8030 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(*dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (method) = parserTryVarTempResult_
.unwrap(); } while (0)
8031 method, finishLexicalScope(*dotInitializersScope, method), false)do { auto parserTryVarTempResult_ = (finishLexicalScope(*dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (method) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8032 dotInitializersScope.reset();
8033 }
8034
8035 return handler_.addClassMemberDefinition(classMembers, method);
8036}
8037
8038template <class ParseHandler, typename Unit>
8039bool GeneralParser<ParseHandler, Unit>::finishClassConstructor(
8040 const ParseContext::ClassStatement& classStmt,
8041 TaggedParserAtomIndex className, HasHeritage hasHeritage,
8042 uint32_t classStartOffset, uint32_t classEndOffset,
8043 const ClassInitializedMembers& classInitializedMembers,
8044 ListNodeType& classMembers) {
8045 if (classStmt.constructorBox == nullptr) {
8046 MOZ_ASSERT(!options().selfHostingMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!options().selfHostingMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!options().selfHostingMode))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!options().selfHostingMode"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8046); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 8046; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8047 // Unconditionally create the scope here, because it's always the
8048 // constructor.
8049 ParseContext::Scope dotInitializersScope(this);
8050 if (!dotInitializersScope.init(pc_)) {
8051 return false;
8052 }
8053
8054 if (!noteDeclaredName(TaggedParserAtomIndex::WellKnown::dot_initializers_(),
8055 DeclarationKind::Let, pos())) {
8056 return false;
8057 }
8058
8059#ifdef ENABLE_DECORATORS
8060 if (!noteDeclaredName(
8061 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_(),
8062 DeclarationKind::Let, pos(), ClosedOver::Yes)) {
8063 return false;
8064 }
8065#endif
8066
8067 // synthesizeConstructor assigns to classStmt.constructorBox
8068 TokenPos synthesizedBodyPos(classStartOffset, classEndOffset);
8069 FunctionNodeType synthesizedCtor;
8070 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8071 synthesizedCtor,do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8072 synthesizeConstructor(className, synthesizedBodyPos, hasHeritage),do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
8073 false)do { auto parserTryVarTempResult_ = (synthesizeConstructor(className
, synthesizedBodyPos, hasHeritage)); if ((__builtin_expect(!!
(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
synthesizedCtor) = parserTryVarTempResult_.unwrap(); } while (
0)
;
8074
8075 // Note: the *function* has the name of the class, but the *property*
8076 // containing the function has the name "constructor"
8077 Node constructorNameNode;
8078 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8079 constructorNameNode,do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8080 handler_.newObjectLiteralPropertyName(do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8081 TaggedParserAtomIndex::WellKnown::constructor(), pos()),do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
8082 false)do { auto parserTryVarTempResult_ = (handler_.newObjectLiteralPropertyName
( TaggedParserAtomIndex::WellKnown::constructor(), pos())); if
((__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0)))
{ return (false); } (constructorNameNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8083 ClassMethodType method;
8084 MOZ_TRY_VAR_OR_RETURN(method,do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8085 handler_.newDefaultClassConstructor(do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8086 constructorNameNode, synthesizedCtor),do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
8087 false)do { auto parserTryVarTempResult_ = (handler_.newDefaultClassConstructor
( constructorNameNode, synthesizedCtor)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(method) = parserTryVarTempResult_.unwrap(); } while (0)
;
8088 LexicalScopeNodeType scope;
8089 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (scope) = parserTryVarTempResult_
.unwrap(); } while (0)
8090 scope, finishLexicalScope(dotInitializersScope, method), false)do { auto parserTryVarTempResult_ = (finishLexicalScope(dotInitializersScope
, method)); if ((__builtin_expect(!!(parserTryVarTempResult_.
isErr()), 0))) { return (false); } (scope) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8091 if (!handler_.addClassMemberDefinition(classMembers, scope)) {
8092 return false;
8093 }
8094 }
8095
8096 MOZ_ASSERT(classStmt.constructorBox)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(classStmt.constructorBox)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(classStmt.constructorBox))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("classStmt.constructorBox"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8096); AnnotateMozCrashReason("MOZ_ASSERT" "(" "classStmt.constructorBox"
")"); do { *((volatile int*)__null) = 8096; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8097 FunctionBox* ctorbox = classStmt.constructorBox;
8098
8099 // Amend the toStringEnd offset for the constructor now that we've
8100 // finished parsing the class.
8101 ctorbox->setCtorToStringEnd(classEndOffset);
8102
8103 size_t numMemberInitializers = classInitializedMembers.privateAccessors +
8104 classInitializedMembers.instanceFields;
8105 bool hasPrivateBrand = classInitializedMembers.hasPrivateBrand();
8106 if (hasPrivateBrand || numMemberInitializers > 0) {
8107 // Now that we have full set of initializers, update the constructor.
8108 MemberInitializers initializers(
8109 hasPrivateBrand,
8110#ifdef ENABLE_DECORATORS
8111 classInitializedMembers.hasInstanceDecorators,
8112#endif
8113 numMemberInitializers);
8114 ctorbox->setMemberInitializers(initializers);
8115
8116 // Field initialization need access to `this`.
8117 ctorbox->setCtorFunctionHasThisBinding();
8118 }
8119
8120 return true;
8121}
8122
8123template <class ParseHandler, typename Unit>
8124typename ParseHandler::ClassNodeResult
8125GeneralParser<ParseHandler, Unit>::classDefinition(
8126 YieldHandling yieldHandling, ClassContext classContext,
8127 DefaultHandling defaultHandling) {
8128#ifdef ENABLE_DECORATORS
8129 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::At) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::At) || anyChars
.isCurrentTokenType(TokenKind::Class))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8130; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
8130 anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::At) || anyChars
.isCurrentTokenType(TokenKind::Class))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class
)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::At) || anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8130; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8131
8132 ListNodeType decorators = null();
8133 FunctionNodeType addInitializerFunction = null();
8134 if (anyChars.isCurrentTokenType(TokenKind::At)) {
8135 MOZ_TRY_VAR(decorators, decoratorList(yieldHandling))do { auto mozTryVarTempResult_ = (decoratorList(yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (decorators
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8136 TokenKind next;
8137 if (!tokenStream.getToken(&next)) {
8138 return errorResult();
8139 }
8140 if (next != TokenKind::Class) {
8141 error(JSMSG_CLASS_EXPECTED);
8142 return errorResult();
8143 }
8144 }
8145#else
8146 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Class))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Class))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Class)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Class)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8146); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Class)"
")"); do { *((volatile int*)__null) = 8146; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8147#endif
8148
8149 uint32_t classStartOffset = pos().begin;
8150 bool savedStrictness = setLocalStrictMode(true);
8151
8152 // Classes are quite broken in self-hosted code.
8153 if (options().selfHostingMode) {
8154 error(JSMSG_SELFHOSTED_CLASS);
8155 return errorResult();
8156 }
8157
8158 TokenKind tt;
8159 if (!tokenStream.getToken(&tt)) {
8160 return errorResult();
8161 }
8162
8163 TaggedParserAtomIndex className;
8164 if (TokenKindIsPossibleIdentifier(tt)) {
8165 className = bindingIdentifier(yieldHandling);
8166 if (!className) {
8167 return errorResult();
8168 }
8169 } else if (classContext == ClassStatement) {
8170 if (defaultHandling == AllowDefaultName) {
8171 className = TaggedParserAtomIndex::WellKnown::default_();
8172 anyChars.ungetToken();
8173 } else {
8174 // Class statements must have a bound name
8175 error(JSMSG_UNNAMED_CLASS_STMT);
8176 return errorResult();
8177 }
8178 } else {
8179 // Make sure to put it back, whatever it was
8180 anyChars.ungetToken();
8181 }
8182
8183 // Because the binding definitions keep track of their blockId, we need to
8184 // create at least the inner binding later. Keep track of the name's
8185 // position in order to provide it for the nodes created later.
8186 TokenPos namePos = pos();
8187
8188 auto isClass = [](ParseContext::Statement* stmt) {
8189 return stmt->kind() == StatementKind::Class;
8190 };
8191
8192 bool isInClass = pc_->sc()->inClass() || pc_->findInnermostStatement(isClass);
8193
8194 // Push a ParseContext::ClassStatement to keep track of the constructor
8195 // funbox.
8196 ParseContext::ClassStatement classStmt(pc_);
8197
8198 NameNodeType innerName;
8199 Node nameNode = null();
8200 Node classHeritage = null();
8201 LexicalScopeNodeType classBlock = null();
8202 ClassBodyScopeNodeType classBodyBlock = null();
8203 uint32_t classEndOffset;
8204 {
8205 // A named class creates a new lexical scope with a const binding of the
8206 // class name for the "inner name".
8207 ParseContext::Statement innerScopeStmt(pc_, StatementKind::Block);
8208 ParseContext::Scope innerScope(this);
8209 if (!innerScope.init(pc_)) {
8210 return errorResult();
8211 }
8212
8213 bool hasHeritageBool;
8214 if (!tokenStream.matchToken(&hasHeritageBool, TokenKind::Extends)) {
8215 return errorResult();
8216 }
8217 HasHeritage hasHeritage =
8218 hasHeritageBool ? HasHeritage::Yes : HasHeritage::No;
8219 if (hasHeritage == HasHeritage::Yes) {
8220 if (!tokenStream.getToken(&tt)) {
8221 return errorResult();
8222 }
8223 MOZ_TRY_VAR(classHeritage,do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classHeritage) = mozTryVarTempResult_.unwrap(); } while (
0)
8224 optionalExpr(yieldHandling, TripledotProhibited, tt))do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classHeritage) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8225 }
8226
8227 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_BEFORE_CLASS)) {
8228 return errorResult();
8229 }
8230
8231 {
8232 ParseContext::Statement bodyScopeStmt(pc_, StatementKind::Block);
8233 ParseContext::Scope bodyScope(this);
8234 if (!bodyScope.init(pc_)) {
8235 return errorResult();
8236 }
8237
8238 ListNodeType classMembers;
8239 MOZ_TRY_VAR(classMembers, handler_.newClassMemberList(pos().begin))do { auto mozTryVarTempResult_ = (handler_.newClassMemberList
(pos().begin)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classMembers) = mozTryVarTempResult_.unwrap(); } while (0
)
;
8240
8241 ClassInitializedMembers classInitializedMembers{};
8242 for (;;) {
8243 bool done;
8244 if (!classMember(yieldHandling, classStmt, className, classStartOffset,
8245 hasHeritage, classInitializedMembers, classMembers,
8246 &done)) {
8247 return errorResult();
8248 }
8249 if (done) {
8250 break;
8251 }
8252 }
8253#ifdef ENABLE_DECORATORS
8254 if (classInitializedMembers.hasInstanceDecorators) {
8255 MOZ_TRY_VAR(addInitializerFunction,do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8256 synthesizeAddInitializerFunction(do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8257 TaggedParserAtomIndex::WellKnown::do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8258 dot_instanceExtraInitializers_(),do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
8259 yieldHandling))do { auto mozTryVarTempResult_ = (synthesizeAddInitializerFunction
( TaggedParserAtomIndex::WellKnown:: dot_instanceExtraInitializers_
(), yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (addInitializerFunction) = mozTryVarTempResult_.unwrap(); }
while (0)
;
8260 }
8261#endif
8262
8263 if (classInitializedMembers.privateMethods +
8264 classInitializedMembers.privateAccessors >
8265 0) {
8266 // We declare `.privateBrand` as ClosedOver because the constructor
8267 // always uses it, even a default constructor. We could equivalently
8268 // `noteUsedName` when parsing the constructor, except that at that
8269 // time, we don't necessarily know if the class has a private brand.
8270 if (!noteDeclaredName(
8271 TaggedParserAtomIndex::WellKnown::dot_privateBrand_(),
8272 DeclarationKind::Synthetic, namePos, ClosedOver::Yes)) {
8273 return errorResult();
8274 }
8275 }
8276
8277 if (classInitializedMembers.instanceFieldKeys > 0) {
8278 if (!noteDeclaredName(
8279 TaggedParserAtomIndex::WellKnown::dot_fieldKeys_(),
8280 DeclarationKind::Synthetic, namePos)) {
8281 return errorResult();
8282 }
8283 }
8284
8285 if (classInitializedMembers.staticFields > 0) {
8286 if (!noteDeclaredName(
8287 TaggedParserAtomIndex::WellKnown::dot_staticInitializers_(),
8288 DeclarationKind::Synthetic, namePos)) {
8289 return errorResult();
8290 }
8291 }
8292
8293 if (classInitializedMembers.staticFieldKeys > 0) {
8294 if (!noteDeclaredName(
8295 TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_(),
8296 DeclarationKind::Synthetic, namePos)) {
8297 return errorResult();
8298 }
8299 }
8300
8301 classEndOffset = pos().end;
8302 if (!finishClassConstructor(classStmt, className, hasHeritage,
8303 classStartOffset, classEndOffset,
8304 classInitializedMembers, classMembers)) {
8305 return errorResult();
8306 }
8307
8308 MOZ_TRY_VAR(classBodyBlock,do { auto mozTryVarTempResult_ = (finishClassBodyScope(bodyScope
, classMembers)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBodyBlock) = mozTryVarTempResult_.unwrap(); } while (
0)
8309 finishClassBodyScope(bodyScope, classMembers))do { auto mozTryVarTempResult_ = (finishClassBodyScope(bodyScope
, classMembers)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBodyBlock) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8310
8311 // Pop the class body scope
8312 }
8313
8314 if (className) {
8315 // The inner name is immutable.
8316 if (!noteDeclaredName(className, DeclarationKind::Const, namePos)) {
8317 return errorResult();
8318 }
8319
8320 MOZ_TRY_VAR(innerName, newName(className, namePos))do { auto mozTryVarTempResult_ = (newName(className, namePos)
); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)
)) { return mozTryVarTempResult_.propagateErr(); } (innerName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8321 }
8322
8323 MOZ_TRY_VAR(classBlock, finishLexicalScope(innerScope, classBodyBlock))do { auto mozTryVarTempResult_ = (finishLexicalScope(innerScope
, classBodyBlock)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (classBlock) = mozTryVarTempResult_.unwrap(); } while (0)
;
8324
8325 // Pop the inner scope.
8326 }
8327
8328 if (className) {
8329 NameNodeType outerName = null();
8330 if (classContext == ClassStatement) {
8331 // The outer name is mutable.
8332 if (!noteDeclaredName(className, DeclarationKind::Class, namePos)) {
8333 return errorResult();
8334 }
8335
8336 MOZ_TRY_VAR(outerName, newName(className, namePos))do { auto mozTryVarTempResult_ = (newName(className, namePos)
); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)
)) { return mozTryVarTempResult_.propagateErr(); } (outerName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8337 }
8338
8339 MOZ_TRY_VAR(nameNode,do { auto mozTryVarTempResult_ = (handler_.newClassNames(outerName
, innerName, namePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nameNode) = mozTryVarTempResult_.unwrap(); } while (0)
8340 handler_.newClassNames(outerName, innerName, namePos))do { auto mozTryVarTempResult_ = (handler_.newClassNames(outerName
, innerName, namePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nameNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8341 }
8342 MOZ_ALWAYS_TRUE(setLocalStrictMode(savedStrictness))do { if ((__builtin_expect(!!(setLocalStrictMode(savedStrictness
)), 1))) { } else { do { do { } while (false); MOZ_ReportCrash
("" "setLocalStrictMode(savedStrictness)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8342); AnnotateMozCrashReason("MOZ_CRASH(" "setLocalStrictMode(savedStrictness)"
")"); do { *((volatile int*)__null) = 8342; __attribute__((nomerge
)) ::abort(); } while (false); } while (false); } } while (false
)
;
8343 // We're leaving a class definition that was not itself nested within a class
8344 if (!isInClass) {
8345 mozilla::Maybe<UnboundPrivateName> maybeUnboundName;
8346 if (!usedNames_.hasUnboundPrivateNames(fc_, maybeUnboundName)) {
8347 return errorResult();
8348 }
8349 if (maybeUnboundName) {
8350 UniqueChars str =
8351 this->parserAtoms().toPrintableString(maybeUnboundName->atom);
8352 if (!str) {
8353 ReportOutOfMemory(this->fc_);
8354 return errorResult();
8355 }
8356
8357 errorAt(maybeUnboundName->position.begin, JSMSG_MISSING_PRIVATE_DECL,
8358 str.get());
8359 return errorResult();
8360 }
8361 }
8362
8363 return handler_.newClass(nameNode, classHeritage, classBlock,
8364#ifdef ENABLE_DECORATORS
8365 decorators, addInitializerFunction,
8366#endif
8367 TokenPos(classStartOffset, classEndOffset));
8368}
8369
8370template <class ParseHandler, typename Unit>
8371typename ParseHandler::FunctionNodeResult
8372GeneralParser<ParseHandler, Unit>::synthesizeConstructor(
8373 TaggedParserAtomIndex className, TokenPos synthesizedBodyPos,
8374 HasHeritage hasHeritage) {
8375 FunctionSyntaxKind functionSyntaxKind =
8376 hasHeritage == HasHeritage::Yes
8377 ? FunctionSyntaxKind::DerivedClassConstructor
8378 : FunctionSyntaxKind::ClassConstructor;
8379
8380 bool isSelfHosting = options().selfHostingMode;
8381 FunctionFlags flags =
8382 InitialFunctionFlags(functionSyntaxKind, GeneratorKind::NotGenerator,
8383 FunctionAsyncKind::SyncFunction, isSelfHosting);
8384
8385 // Create the top-level field initializer node.
8386 FunctionNodeType funNode;
8387 MOZ_TRY_VAR(funNode,do { auto mozTryVarTempResult_ = (handler_.newFunction(functionSyntaxKind
, synthesizedBodyPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
8388 handler_.newFunction(functionSyntaxKind, synthesizedBodyPos))do { auto mozTryVarTempResult_ = (handler_.newFunction(functionSyntaxKind
, synthesizedBodyPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8389
8390 // If we see any inner function, note it on our current context. The bytecode
8391 // emitter may eliminate the function later, but we use a conservative
8392 // definition for consistency between lazy and full parsing.
8393 pc_->sc()->setHasInnerFunctions();
8394
8395 // When fully parsing a lazy script, we do not fully reparse its inner
8396 // functions, which are also lazy. Instead, their free variables and source
8397 // extents are recorded and may be skipped.
8398 if (handler_.reuseLazyInnerFunctions()) {
8399 if (!skipLazyInnerFunction(funNode, synthesizedBodyPos.begin,
8400 /* tryAnnexB = */ false)) {
8401 return errorResult();
8402 }
8403
8404 return funNode;
8405 }
8406
8407 // Create the FunctionBox and link it to the function object.
8408 Directives directives(true);
8409 FunctionBox* funbox = newFunctionBox(
8410 funNode, className, flags, synthesizedBodyPos.begin, directives,
8411 GeneratorKind::NotGenerator, FunctionAsyncKind::SyncFunction);
8412 if (!funbox) {
8413 return errorResult();
8414 }
8415 funbox->initWithEnclosingParseContext(pc_, functionSyntaxKind);
8416 setFunctionEndFromCurrentToken(funbox);
8417
8418 // Mark this function as being synthesized by the parser. This means special
8419 // handling in delazification will be used since we don't have typical
8420 // function syntax.
8421 funbox->setSyntheticFunction();
8422
8423 // Push a SourceParseContext on to the stack.
8424 ParseContext* outerpc = pc_;
8425 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8426 if (!funpc.init()) {
8427 return errorResult();
8428 }
8429
8430 if (!synthesizeConstructorBody(synthesizedBodyPos, hasHeritage, funNode,
8431 funbox)) {
8432 return errorResult();
8433 }
8434
8435 if (!leaveInnerFunction(outerpc)) {
8436 return errorResult();
8437 }
8438
8439 return funNode;
8440}
8441
8442template <class ParseHandler, typename Unit>
8443bool GeneralParser<ParseHandler, Unit>::synthesizeConstructorBody(
8444 TokenPos synthesizedBodyPos, HasHeritage hasHeritage,
8445 FunctionNodeType funNode, FunctionBox* funbox) {
8446 MOZ_ASSERT(funbox->isClassConstructor())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isClassConstructor())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isClassConstructor
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isClassConstructor()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8446); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isClassConstructor()"
")"); do { *((volatile int*)__null) = 8446; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8447
8448 // Create a ParamsBodyNode for the parameters + body (there are no
8449 // parameters).
8450 ParamsBodyNodeType argsbody;
8451 MOZ_TRY_VAR_OR_RETURN(argsbody, handler_.newParamsBody(synthesizedBodyPos),do { auto parserTryVarTempResult_ = (handler_.newParamsBody(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
8452 false)do { auto parserTryVarTempResult_ = (handler_.newParamsBody(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (argsbody) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8453 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8454 setFunctionStartAtPosition(funbox, synthesizedBodyPos);
8455
8456 if (hasHeritage == HasHeritage::Yes) {
8457 // Synthesize the equivalent to `function f(...args)`
8458 funbox->setHasRest();
8459 if (!notePositionalFormalParameter(
8460 funNode, TaggedParserAtomIndex::WellKnown::dot_args_(),
8461 synthesizedBodyPos.begin,
8462 /* disallowDuplicateParams = */ false,
8463 /* duplicatedParam = */ nullptr)) {
8464 return false;
8465 }
8466 funbox->setArgCount(1);
8467 } else {
8468 funbox->setArgCount(0);
8469 }
8470
8471 pc_->functionScope().useAsVarScope(pc_);
8472
8473 ListNodeType stmtList;
8474 MOZ_TRY_VAR_OR_RETURN(stmtList, handler_.newStatementList(synthesizedBodyPos),do { auto parserTryVarTempResult_ = (handler_.newStatementList
(synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (stmtList) = parserTryVarTempResult_
.unwrap(); } while (0)
8475 false)do { auto parserTryVarTempResult_ = (handler_.newStatementList
(synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (stmtList) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8476
8477 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_this_())) {
8478 return false;
8479 }
8480
8481 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
8482 return false;
8483 }
8484
8485#ifdef ENABLE_DECORATORS
8486 if (!noteUsedName(
8487 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_())) {
8488 return false;
8489 }
8490#endif
8491
8492 if (hasHeritage == HasHeritage::Yes) {
8493 // |super()| implicitly reads |new.target|.
8494 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
8495 return false;
8496 }
8497
8498 NameNodeType thisName;
8499 MOZ_TRY_VAR_OR_RETURN(thisName, newThisName(), false)do { auto parserTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(thisName) = parserTryVarTempResult_.unwrap(); } while (0)
;
8500
8501 UnaryNodeType superBase;
8502 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newSuperBase(thisName
, synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superBase) = parserTryVarTempResult_
.unwrap(); } while (0)
8503 superBase, handler_.newSuperBase(thisName, synthesizedBodyPos), false)do { auto parserTryVarTempResult_ = (handler_.newSuperBase(thisName
, synthesizedBodyPos)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superBase) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8504
8505 ListNodeType arguments;
8506 MOZ_TRY_VAR_OR_RETURN(arguments, handler_.newArguments(synthesizedBodyPos),do { auto parserTryVarTempResult_ = (handler_.newArguments(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (arguments) = parserTryVarTempResult_
.unwrap(); } while (0)
8507 false)do { auto parserTryVarTempResult_ = (handler_.newArguments(synthesizedBodyPos
)); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr())
, 0))) { return (false); } (arguments) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8508
8509 NameNodeType argsNameNode;
8510 MOZ_TRY_VAR_OR_RETURN(argsNameNode,do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
8511 newName(TaggedParserAtomIndex::WellKnown::dot_args_(),do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
8512 synthesizedBodyPos),do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
8513 false)do { auto parserTryVarTempResult_ = (newName(TaggedParserAtomIndex
::WellKnown::dot_args_(), synthesizedBodyPos)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(argsNameNode) = parserTryVarTempResult_.unwrap(); } while (
0)
;
8514 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_args_())) {
8515 return false;
8516 }
8517
8518 UnaryNodeType spreadArgs;
8519 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newSpread(synthesizedBodyPos
.begin, argsNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (spreadArgs) = parserTryVarTempResult_
.unwrap(); } while (0)
8520 spreadArgs, handler_.newSpread(synthesizedBodyPos.begin, argsNameNode),do { auto parserTryVarTempResult_ = (handler_.newSpread(synthesizedBodyPos
.begin, argsNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (spreadArgs) = parserTryVarTempResult_
.unwrap(); } while (0)
8521 false)do { auto parserTryVarTempResult_ = (handler_.newSpread(synthesizedBodyPos
.begin, argsNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (spreadArgs) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8522 handler_.addList(arguments, spreadArgs);
8523
8524 CallNodeType superCall;
8525 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
8526 superCall,do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
8527 handler_.newSuperCall(superBase, arguments, /* isSpread = */ true),do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
8528 false)do { auto parserTryVarTempResult_ = (handler_.newSuperCall(superBase
, arguments, true)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (superCall) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8529
8530 BinaryNodeType setThis;
8531 MOZ_TRY_VAR_OR_RETURN(setThis, handler_.newSetThis(thisName, superCall),do { auto parserTryVarTempResult_ = (handler_.newSetThis(thisName
, superCall)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (setThis) = parserTryVarTempResult_
.unwrap(); } while (0)
8532 false)do { auto parserTryVarTempResult_ = (handler_.newSetThis(thisName
, superCall)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (setThis) = parserTryVarTempResult_
.unwrap(); } while (0)
;
8533
8534 UnaryNodeType exprStatement;
8535 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newExprStatement
(setThis, synthesizedBodyPos.end)); if ((__builtin_expect(!!(
parserTryVarTempResult_.isErr()), 0))) { return (false); } (exprStatement
) = parserTryVarTempResult_.unwrap(); } while (0)
8536 exprStatement,do { auto parserTryVarTempResult_ = (handler_.newExprStatement
(setThis, synthesizedBodyPos.end)); if ((__builtin_expect(!!(
parserTryVarTempResult_.isErr()), 0))) { return (false); } (exprStatement
) = parserTryVarTempResult_.unwrap(); } while (0)
8537 handler_.newExprStatement(setThis, synthesizedBodyPos.end), false)do { auto parserTryVarTempResult_ = (handler_.newExprStatement
(setThis, synthesizedBodyPos.end)); if ((__builtin_expect(!!(
parserTryVarTempResult_.isErr()), 0))) { return (false); } (exprStatement
) = parserTryVarTempResult_.unwrap(); } while (0)
;
8538
8539 handler_.addStatementToList(stmtList, exprStatement);
8540 }
8541
8542 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8543 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8544 return false;
8545 }
8546 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8547 return false;
8548 }
8549
8550 LexicalScopeNodeType initializerBody;
8551 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
8552 initializerBody,do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
8553 finishLexicalScope(pc_->varScope(), stmtList, ScopeKind::FunctionLexical),do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
8554 false)do { auto parserTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(initializerBody) = parserTryVarTempResult_.unwrap(); } while
(0)
;
8555 handler_.setBeginPosition(initializerBody, stmtList);
8556 handler_.setEndPosition(initializerBody, stmtList);
8557
8558 handler_.setFunctionBody(funNode, initializerBody);
8559
8560 return finishFunction();
8561}
8562
8563template <class ParseHandler, typename Unit>
8564typename ParseHandler::FunctionNodeResult
8565GeneralParser<ParseHandler, Unit>::privateMethodInitializer(
8566 TokenPos propNamePos, TaggedParserAtomIndex propAtom,
8567 TaggedParserAtomIndex storedMethodAtom) {
8568 if (!abortIfSyntaxParser()) {
8569 return errorResult();
8570 }
8571
8572 // Synthesize an initializer function that the constructor can use to stamp a
8573 // private method onto an instance object.
8574 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer;
8575 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8576 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8577 bool isSelfHosting = options().selfHostingMode;
8578 FunctionFlags flags =
8579 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8580
8581 FunctionNodeType funNode;
8582 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8583
8584 Directives directives(true);
8585 FunctionBox* funbox =
8586 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
8587 propNamePos.begin, directives, generatorKind, asyncKind);
8588 if (!funbox) {
8589 return errorResult();
8590 }
8591 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8592
8593 // Push a SourceParseContext on to the stack.
8594 ParseContext* outerpc = pc_;
8595 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8596 if (!funpc.init()) {
8597 return errorResult();
8598 }
8599 pc_->functionScope().useAsVarScope(pc_);
8600
8601 // Add empty parameter list.
8602 ParamsBodyNodeType argsbody;
8603 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8604 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8605 setFunctionStartAtCurrentToken(funbox);
8606 funbox->setArgCount(0);
8607
8608 // Note both the stored private method body and it's private name as being
8609 // used in the initializer. They will be emitted into the method body in the
8610 // BCE.
8611 if (!noteUsedName(storedMethodAtom)) {
8612 return errorResult();
8613 }
8614 MOZ_TRY(privateNameReference(propAtom))do { auto mozTryTempResult_ = ::mozilla::ToResult(privateNameReference
(propAtom)); if ((__builtin_expect(!!(mozTryTempResult_.isErr
()), 0))) { return mozTryTempResult_.propagateErr(); } } while
(0)
;
8615
8616 // Unlike field initializers, private method initializers are not created with
8617 // a body of synthesized AST nodes. Instead, the body is left empty and the
8618 // initializer is synthesized at the bytecode level.
8619 // See BytecodeEmitter::emitPrivateMethodInitializer.
8620 ListNodeType stmtList;
8621 MOZ_TRY_VAR(stmtList, handler_.newStatementList(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8622
8623 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8624 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8625 return errorResult();
8626 }
8627 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8628 return errorResult();
8629 }
8630
8631 LexicalScopeNodeType initializerBody;
8632 MOZ_TRY_VAR(initializerBody, finishLexicalScope(pc_->varScope(), stmtList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerBody) = mozTryVarTempResult_.unwrap
(); } while (0)
8633 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerBody) = mozTryVarTempResult_.unwrap
(); } while (0)
;
8634 handler_.setBeginPosition(initializerBody, stmtList);
8635 handler_.setEndPosition(initializerBody, stmtList);
8636 handler_.setFunctionBody(funNode, initializerBody);
8637
8638 // Set field-initializer lambda boundary to start at property name and end
8639 // after method body.
8640 setFunctionStartAtPosition(funbox, propNamePos);
8641 setFunctionEndFromCurrentToken(funbox);
8642
8643 if (!finishFunction()) {
8644 return errorResult();
8645 }
8646
8647 if (!leaveInnerFunction(outerpc)) {
8648 return errorResult();
8649 }
8650
8651 return funNode;
8652}
8653
8654template <class ParseHandler, typename Unit>
8655typename ParseHandler::FunctionNodeResult
8656GeneralParser<ParseHandler, Unit>::staticClassBlock(
8657 ClassInitializedMembers& classInitializedMembers) {
8658 // Both for getting-this-done, and because this will invariably be executed,
8659 // syntax parsing should be aborted.
8660 if (!abortIfSyntaxParser()) {
8661 return errorResult();
8662 }
8663
8664 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::StaticClassBlock;
8665 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8666 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8667 bool isSelfHosting = options().selfHostingMode;
8668 FunctionFlags flags =
8669 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8670
8671 AutoAwaitIsKeyword awaitIsKeyword(this, AwaitHandling::AwaitIsDisallowed);
8672
8673 // Create the function node for the static class body.
8674 FunctionNodeType funNode;
8675 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8676
8677 // Create the FunctionBox and link it to the function object.
8678 Directives directives(true);
8679 FunctionBox* funbox =
8680 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags, pos().begin,
8681 directives, generatorKind, asyncKind);
8682 if (!funbox) {
8683 return errorResult();
8684 }
8685 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8686 MOZ_ASSERT(funbox->isSyntheticFunction())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isSyntheticFunction())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isSyntheticFunction
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isSyntheticFunction()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8686); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isSyntheticFunction()"
")"); do { *((volatile int*)__null) = 8686; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8687 MOZ_ASSERT(!funbox->allowSuperCall())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!funbox->allowSuperCall())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!funbox->allowSuperCall()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!funbox->allowSuperCall()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8687); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowSuperCall()"
")"); do { *((volatile int*)__null) = 8687; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8688 MOZ_ASSERT(!funbox->allowArguments())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!funbox->allowArguments())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!funbox->allowArguments()
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!funbox->allowArguments()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8688); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowArguments()"
")"); do { *((volatile int*)__null) = 8688; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8689 MOZ_ASSERT(!funbox->allowReturn())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!funbox->allowReturn())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!funbox->allowReturn())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("!funbox->allowReturn()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8689); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!funbox->allowReturn()"
")"); do { *((volatile int*)__null) = 8689; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8690
8691 // Set start at `static` token.
8692 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Static))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Static))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Static)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Static)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8692); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Static)"
")"); do { *((volatile int*)__null) = 8692; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8693 setFunctionStartAtCurrentToken(funbox);
8694
8695 // Push a SourceParseContext on to the stack.
8696 ParseContext* outerpc = pc_;
8697 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8698 if (!funpc.init()) {
8699 return errorResult();
8700 }
8701
8702 pc_->functionScope().useAsVarScope(pc_);
8703
8704 uint32_t start = pos().begin;
8705
8706 tokenStream.consumeKnownToken(TokenKind::LeftCurly);
8707
8708 // Static class blocks are code-generated as if they were static field
8709 // initializers, so we bump the staticFields count here, which ensures
8710 // .staticInitializers is noted as used.
8711 classInitializedMembers.staticFields++;
8712
8713 LexicalScopeNodeType body;
8714 MOZ_TRY_VAR(body,do { auto mozTryVarTempResult_ = (functionBody(InHandling::InAllowed
, YieldHandling::YieldIsKeyword, syntaxKind, FunctionBodyType
::StatementListBody)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (body) = mozTryVarTempResult_.unwrap(); } while (0)
8715 functionBody(InHandling::InAllowed, YieldHandling::YieldIsKeyword,do { auto mozTryVarTempResult_ = (functionBody(InHandling::InAllowed
, YieldHandling::YieldIsKeyword, syntaxKind, FunctionBodyType
::StatementListBody)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (body) = mozTryVarTempResult_.unwrap(); } while (0)
8716 syntaxKind, FunctionBodyType::StatementListBody))do { auto mozTryVarTempResult_ = (functionBody(InHandling::InAllowed
, YieldHandling::YieldIsKeyword, syntaxKind, FunctionBodyType
::StatementListBody)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (body) = mozTryVarTempResult_.unwrap(); } while (0)
;
8717
8718 if (anyChars.isEOF()) {
8719 error(JSMSG_UNTERMINATED_STATIC_CLASS_BLOCK);
8720 return errorResult();
8721 }
8722
8723 tokenStream.consumeKnownToken(TokenKind::RightCurly,
8724 TokenStream::Modifier::SlashIsRegExp);
8725
8726 TokenPos wholeBodyPos(start, pos().end);
8727
8728 handler_.setEndPosition(funNode, wholeBodyPos.end);
8729 setFunctionEndFromCurrentToken(funbox);
8730
8731 // Create a ParamsBodyNode for the parameters + body (there are no
8732 // parameters).
8733 ParamsBodyNodeType argsbody;
8734 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(wholeBodyPos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(wholeBodyPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8735
8736 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8737 funbox->setArgCount(0);
8738
8739 if (pc_->superScopeNeedsHomeObject()) {
8740 funbox->setNeedsHomeObject();
8741 }
8742
8743 handler_.setEndPosition(body, pos().begin);
8744 handler_.setEndPosition(funNode, pos().end);
8745 handler_.setFunctionBody(funNode, body);
8746
8747 if (!finishFunction()) {
8748 return errorResult();
8749 }
8750
8751 if (!leaveInnerFunction(outerpc)) {
8752 return errorResult();
8753 }
8754
8755 return funNode;
8756}
8757
8758template <class ParseHandler, typename Unit>
8759typename ParseHandler::FunctionNodeResult
8760GeneralParser<ParseHandler, Unit>::fieldInitializerOpt(
8761 TokenPos propNamePos, Node propName, TaggedParserAtomIndex propAtom,
8762 ClassInitializedMembers& classInitializedMembers, bool isStatic,
8763 HasHeritage hasHeritage) {
8764 if (!abortIfSyntaxParser()) {
8765 return errorResult();
8766 }
8767
8768 bool hasInitializer = false;
8769 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
8770 TokenStream::SlashIsDiv)) {
8771 return errorResult();
8772 }
8773
8774 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::FieldInitializer;
8775 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
8776 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
8777 bool isSelfHosting = options().selfHostingMode;
8778 FunctionFlags flags =
8779 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
8780
8781 // Create the top-level field initializer node.
8782 FunctionNodeType funNode;
8783 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
8784
8785 // Create the FunctionBox and link it to the function object.
8786 Directives directives(true);
8787 FunctionBox* funbox =
8788 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
8789 propNamePos.begin, directives, generatorKind, asyncKind);
8790 if (!funbox) {
8791 return errorResult();
8792 }
8793 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
8794 MOZ_ASSERT(funbox->isSyntheticFunction())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funbox->isSyntheticFunction())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funbox->isSyntheticFunction
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("funbox->isSyntheticFunction()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 8794); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isSyntheticFunction()"
")"); do { *((volatile int*)__null) = 8794; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
8795
8796 // We can't use setFunctionStartAtCurrentToken because that uses pos().begin,
8797 // which is incorrect for fields without initializers (pos() points to the
8798 // field identifier)
8799 setFunctionStartAtPosition(funbox, propNamePos);
8800
8801 // Push a SourceParseContext on to the stack.
8802 ParseContext* outerpc = pc_;
8803 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
8804 if (!funpc.init()) {
8805 return errorResult();
8806 }
8807
8808 pc_->functionScope().useAsVarScope(pc_);
8809
8810 Node initializerExpr;
8811 if (hasInitializer) {
8812 // Parse the expression for the field initializer.
8813 {
8814 AutoAwaitIsKeyword awaitHandling(this, AwaitIsName);
8815 MOZ_TRY_VAR(initializerExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, YieldIsName
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerExpr) = mozTryVarTempResult_.unwrap(); } while
(0)
8816 assignExpr(InAllowed, YieldIsName, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, YieldIsName
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerExpr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
8817 }
8818
8819 handler_.checkAndSetIsDirectRHSAnonFunction(initializerExpr);
8820 } else {
8821 MOZ_TRY_VAR(initializerExpr, handler_.newRawUndefinedLiteral(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newRawUndefinedLiteral
(propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerExpr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
8822 }
8823
8824 TokenPos wholeInitializerPos(propNamePos.begin, pos().end);
8825
8826 // Update the end position of the parse node.
8827 handler_.setEndPosition(funNode, wholeInitializerPos.end);
8828 setFunctionEndFromCurrentToken(funbox);
8829
8830 // Create a ParamsBodyNode for the parameters + body (there are no
8831 // parameters).
8832 ParamsBodyNodeType argsbody;
8833 MOZ_TRY_VAR(argsbody, handler_.newParamsBody(wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(wholeInitializerPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8834 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
8835 funbox->setArgCount(0);
8836
8837 NameNodeType thisName;
8838 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
8839
8840 // Build `this.field` expression.
8841 ThisLiteralType propAssignThis;
8842 MOZ_TRY_VAR(propAssignThis,do { auto mozTryVarTempResult_ = (handler_.newThisLiteral(wholeInitializerPos
, thisName)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propAssignThis
) = mozTryVarTempResult_.unwrap(); } while (0)
8843 handler_.newThisLiteral(wholeInitializerPos, thisName))do { auto mozTryVarTempResult_ = (handler_.newThisLiteral(wholeInitializerPos
, thisName)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propAssignThis
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8844
8845 Node propAssignFieldAccess;
8846 uint32_t indexValue;
8847 if (!propAtom) {
8848 // See BytecodeEmitter::emitCreateFieldKeys for an explanation of what
8849 // .fieldKeys means and its purpose.
8850 NameNodeType fieldKeysName;
8851 if (isStatic) {
8852 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8853 fieldKeysName,do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8854 newInternalDotName(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
8855 TaggedParserAtomIndex::WellKnown::dot_staticFieldKeys_()))do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_staticFieldKeys_())); if ((__builtin_expect(
!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeysName) = mozTryVarTempResult_.unwrap
(); } while (0)
;
8856 } else {
8857 MOZ_TRY_VAR(fieldKeysName,do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_fieldKeys_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fieldKeysName) = mozTryVarTempResult_.unwrap(); } while (
0)
8858 newInternalDotName(do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_fieldKeys_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fieldKeysName) = mozTryVarTempResult_.unwrap(); } while (
0)
8859 TaggedParserAtomIndex::WellKnown::dot_fieldKeys_()))do { auto mozTryVarTempResult_ = (newInternalDotName( TaggedParserAtomIndex
::WellKnown::dot_fieldKeys_())); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (fieldKeysName) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8860 }
8861 if (!fieldKeysName) {
8862 return errorResult();
8863 }
8864
8865 double fieldKeyIndex;
8866 if (isStatic) {
8867 fieldKeyIndex = classInitializedMembers.staticFieldKeys++;
8868 } else {
8869 fieldKeyIndex = classInitializedMembers.instanceFieldKeys++;
8870 }
8871 Node fieldKeyIndexNode;
8872 MOZ_TRY_VAR(fieldKeyIndexNode,do { auto mozTryVarTempResult_ = (handler_.newNumber(fieldKeyIndex
, DecimalPoint::NoDecimal, wholeInitializerPos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeyIndexNode) = mozTryVarTempResult_
.unwrap(); } while (0)
8873 handler_.newNumber(fieldKeyIndex, DecimalPoint::NoDecimal,do { auto mozTryVarTempResult_ = (handler_.newNumber(fieldKeyIndex
, DecimalPoint::NoDecimal, wholeInitializerPos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeyIndexNode) = mozTryVarTempResult_
.unwrap(); } while (0)
8874 wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newNumber(fieldKeyIndex
, DecimalPoint::NoDecimal, wholeInitializerPos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (fieldKeyIndexNode) = mozTryVarTempResult_
.unwrap(); } while (0)
;
8875
8876 Node fieldKeyValue;
8877 MOZ_TRY_VAR(fieldKeyValue,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(fieldKeysName, fieldKeyIndexNode, wholeInitializerPos.end));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (fieldKeyValue
) = mozTryVarTempResult_.unwrap(); } while (0)
8878 handler_.newPropertyByValue(fieldKeysName, fieldKeyIndexNode,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(fieldKeysName, fieldKeyIndexNode, wholeInitializerPos.end));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (fieldKeyValue
) = mozTryVarTempResult_.unwrap(); } while (0)
8879 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(fieldKeysName, fieldKeyIndexNode, wholeInitializerPos.end));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (fieldKeyValue
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8880
8881 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, fieldKeyValue, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8882 handler_.newPropertyByValue(propAssignThis, fieldKeyValue,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, fieldKeyValue, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8883 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, fieldKeyValue, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8884 } else if (handler_.isPrivateName(propName)) {
8885 // It would be nice if we could tweak this here such that only if
8886 // HasHeritage::Yes we end up emitting CheckPrivateField, but otherwise we
8887 // emit InitElem -- this is an optimization to minimize HasOwn checks
8888 // in InitElem for classes without heritage.
8889 //
8890 // Further tweaking would be to ultimately only do CheckPrivateField for the
8891 // -first- field in a derived class, which would suffice to match the
8892 // semantic check.
8893
8894 NameNodeType privateNameNode;
8895 MOZ_TRY_VAR(privateNameNode, privateNameReference(propAtom))do { auto mozTryVarTempResult_ = (privateNameReference(propAtom
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (privateNameNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8896
8897 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
(propAssignThis, privateNameNode, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8898 handler_.newPrivateMemberAccess(propAssignThis, privateNameNode,do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
(propAssignThis, privateNameNode, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
8899 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
(propAssignThis, privateNameNode, wholeInitializerPos.end)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propAssignFieldAccess
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8900 } else if (this->parserAtoms().isIndex(propAtom, &indexValue)) {
8901 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, propName, wholeInitializerPos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propAssignFieldAccess) = mozTryVarTempResult_
.unwrap(); } while (0)
8902 handler_.newPropertyByValue(propAssignThis, propName,do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, propName, wholeInitializerPos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propAssignFieldAccess) = mozTryVarTempResult_
.unwrap(); } while (0)
8903 wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newPropertyByValue
(propAssignThis, propName, wholeInitializerPos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propAssignFieldAccess) = mozTryVarTempResult_
.unwrap(); } while (0)
;
8904 } else {
8905 NameNodeType propAssignName;
8906 MOZ_TRY_VAR(propAssignName,do { auto mozTryVarTempResult_ = (handler_.newPropertyName(propAtom
, wholeInitializerPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignName) = mozTryVarTempResult_.unwrap(); } while (
0)
8907 handler_.newPropertyName(propAtom, wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newPropertyName(propAtom
, wholeInitializerPos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignName) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8908
8909 MOZ_TRY_VAR(propAssignFieldAccess,do { auto mozTryVarTempResult_ = (handler_.newPropertyAccess(
propAssignThis, propAssignName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignFieldAccess) = mozTryVarTempResult_.unwrap(); }
while (0)
8910 handler_.newPropertyAccess(propAssignThis, propAssignName))do { auto mozTryVarTempResult_ = (handler_.newPropertyAccess(
propAssignThis, propAssignName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propAssignFieldAccess) = mozTryVarTempResult_.unwrap(); }
while (0)
;
8911 }
8912
8913 // Synthesize an property init.
8914 BinaryNodeType initializerPropInit;
8915 MOZ_TRY_VAR(initializerPropInit,do { auto mozTryVarTempResult_ = (handler_.newInitExpr(propAssignFieldAccess
, initializerExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerPropInit) = mozTryVarTempResult_.unwrap(); } while
(0)
8916 handler_.newInitExpr(propAssignFieldAccess, initializerExpr))do { auto mozTryVarTempResult_ = (handler_.newInitExpr(propAssignFieldAccess
, initializerExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (initializerPropInit) = mozTryVarTempResult_.unwrap(); } while
(0)
;
8917
8918 UnaryNodeType exprStatement;
8919 MOZ_TRY_VAR(exprStatement, handler_.newExprStatement(do { auto mozTryVarTempResult_ = (handler_.newExprStatement( initializerPropInit
, wholeInitializerPos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprStatement) = mozTryVarTempResult_.unwrap(); } while (
0)
8920 initializerPropInit, wholeInitializerPos.end))do { auto mozTryVarTempResult_ = (handler_.newExprStatement( initializerPropInit
, wholeInitializerPos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (exprStatement) = mozTryVarTempResult_.unwrap(); } while (
0)
;
8921
8922 ListNodeType statementList;
8923 MOZ_TRY_VAR(statementList, handler_.newStatementList(wholeInitializerPos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(wholeInitializerPos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (statementList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
8924 handler_.addStatementToList(statementList, exprStatement);
8925
8926 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
8927 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
8928 return errorResult();
8929 }
8930 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
8931 return errorResult();
8932 }
8933
8934 // Set the function's body to the field assignment.
8935 LexicalScopeNodeType initializerBody;
8936 MOZ_TRY_VAR(initializerBody,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
8937 finishLexicalScope(pc_->varScope(), statementList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
8938 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
;
8939
8940 handler_.setFunctionBody(funNode, initializerBody);
8941
8942 if (pc_->superScopeNeedsHomeObject()) {
8943 funbox->setNeedsHomeObject();
8944 }
8945
8946 if (!finishFunction()) {
8947 return errorResult();
8948 }
8949
8950 if (!leaveInnerFunction(outerpc)) {
8951 return errorResult();
8952 }
8953
8954 return funNode;
8955}
8956
8957template <class ParseHandler, typename Unit>
8958typename ParseHandler::FunctionNodeResult
8959GeneralParser<ParseHandler, Unit>::synthesizePrivateMethodInitializer(
8960 TaggedParserAtomIndex propAtom, AccessorType accessorType,
8961 TokenPos propNamePos) {
8962 if (!abortIfSyntaxParser()) {
8963 return errorResult();
8964 }
8965
8966 // Synthesize a name for the lexical variable that will store the
8967 // accessor body.
8968 StringBuilder storedMethodName(fc_);
8969 if (!storedMethodName.append(this->parserAtoms(), propAtom)) {
8970 return errorResult();
8971 }
8972 if (!storedMethodName.append(
8973 accessorType == AccessorType::Getter ? ".getter" : ".setter")) {
8974 return errorResult();
8975 }
8976 auto storedMethodProp =
8977 storedMethodName.finishParserAtom(this->parserAtoms(), fc_);
8978 if (!storedMethodProp) {
8979 return errorResult();
8980 }
8981 if (!noteDeclaredName(storedMethodProp, DeclarationKind::Synthetic, pos())) {
8982 return errorResult();
8983 }
8984
8985 return privateMethodInitializer(propNamePos, propAtom, storedMethodProp);
8986}
8987
8988#ifdef ENABLE_DECORATORS
8989template <class ParseHandler, typename Unit>
8990typename ParseHandler::FunctionNodeResult
8991GeneralParser<ParseHandler, Unit>::synthesizeAddInitializerFunction(
8992 TaggedParserAtomIndex initializers, YieldHandling yieldHandling) {
8993 if (!abortIfSyntaxParser()) {
8994 return errorResult();
8995 }
8996
8997 // TODO: Add support for static and class extra initializers, see bug 1868220
8998 // and bug 1868221.
8999 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9001; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9000 initializers ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9001; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9001 TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
())>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9001); AnnotateMozCrashReason("MOZ_ASSERT" "(" "initializers == TaggedParserAtomIndex::WellKnown::dot_instanceExtraInitializers_()"
")"); do { *((volatile int*)__null) = 9001; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9002
9003 TokenPos propNamePos = pos();
9004
9005 // Synthesize an addInitializer function that can be used to append to
9006 // .initializers
9007 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
9008 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
9009 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
9010 bool isSelfHosting = options().selfHostingMode;
9011 FunctionFlags flags =
9012 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
9013
9014 FunctionNodeType funNode;
9015 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
9016
9017 Directives directives(true);
9018 FunctionBox* funbox =
9019 newFunctionBox(funNode, TaggedParserAtomIndex::null(), flags,
9020 propNamePos.begin, directives, generatorKind, asyncKind);
9021 if (!funbox) {
9022 return errorResult();
9023 }
9024 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
9025
9026 ParseContext* outerpc = pc_;
9027 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
9028 if (!funpc.init()) {
9029 return errorResult();
9030 }
9031 pc_->functionScope().useAsVarScope(pc_);
9032
9033 // Takes a single parameter, `initializer`.
9034 ParamsBodyNodeType params;
9035 MOZ_TRY_VAR(params, handler_.newParamsBody(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (params) =
mozTryVarTempResult_.unwrap(); } while (0)
;
9036
9037 handler_.setFunctionFormalParametersAndBody(funNode, params);
9038
9039 constexpr bool disallowDuplicateParams = true;
9040 bool duplicatedParam = false;
9041 if (!notePositionalFormalParameter(
9042 funNode, TaggedParserAtomIndex::WellKnown::initializer(), pos().begin,
9043 disallowDuplicateParams, &duplicatedParam)) {
9044 return null();
9045 }
9046 MOZ_ASSERT(!duplicatedParam)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!duplicatedParam)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!duplicatedParam))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("!duplicatedParam"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9046); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!duplicatedParam"
")"); do { *((volatile int*)__null) = 9046; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9047 MOZ_ASSERT(pc_->positionalFormalParameterNames().length() == 1)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->positionalFormalParameterNames().length() ==
1)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(pc_->positionalFormalParameterNames().length() ==
1))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("pc_->positionalFormalParameterNames().length() == 1", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9047); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->positionalFormalParameterNames().length() == 1"
")"); do { *((volatile int*)__null) = 9047; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9048
9049 funbox->setLength(1);
9050 funbox->setArgCount(1);
9051 setFunctionStartAtCurrentToken(funbox);
9052
9053 // Like private method initializers, the addInitializer method is not created
9054 // with a body of synthesized AST nodes. Instead, the body is left empty and
9055 // the initializer is synthesized at the bytecode level. See
9056 // DecoratorEmitter::emitCreateAddInitializerFunction.
9057 ListNodeType stmtList;
9058 MOZ_TRY_VAR(stmtList, handler_.newStatementList(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (stmtList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9059
9060 if (!noteUsedName(initializers)) {
9061 return null();
9062 }
9063
9064 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
9065 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
9066 return null();
9067 }
9068 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
9069 return null();
9070 }
9071
9072 LexicalScopeNodeType addInitializerBody;
9073 MOZ_TRY_VAR(addInitializerBody,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (addInitializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9074 finishLexicalScope(pc_->varScope(), stmtList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (addInitializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9075 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), stmtList, ScopeKind::FunctionLexical)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (addInitializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
;
9076 handler_.setBeginPosition(addInitializerBody, stmtList);
9077 handler_.setEndPosition(addInitializerBody, stmtList);
9078 handler_.setFunctionBody(funNode, addInitializerBody);
9079
9080 // Set field-initializer lambda boundary to start at property name and end
9081 // after method body.
9082 setFunctionStartAtPosition(funbox, propNamePos);
9083 setFunctionEndFromCurrentToken(funbox);
9084
9085 if (!finishFunction()) {
9086 return errorResult();
9087 }
9088
9089 if (!leaveInnerFunction(outerpc)) {
9090 return errorResult();
9091 }
9092
9093 return funNode;
9094}
9095
9096template <class ParseHandler, typename Unit>
9097typename ParseHandler::ClassMethodResult
9098GeneralParser<ParseHandler, Unit>::synthesizeAccessor(
9099 Node propName, TokenPos propNamePos, TaggedParserAtomIndex propAtom,
9100 TaggedParserAtomIndex privateStateNameAtom, bool isStatic,
9101 FunctionSyntaxKind syntaxKind,
9102 ClassInitializedMembers& classInitializedMembers) {
9103 // Decorators Proposal
9104 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9105 // The abstract operation MakeAutoAccessorGetter takes arguments homeObject
9106 // (an Object), name (a property key or Private Name), and privateStateName (a
9107 // Private Name) and returns a function object.
9108 //
9109 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9110 // The abstract operation MakeAutoAccessorSetter takes arguments homeObject
9111 // (an Object), name (a property key or Private Name), and privateStateName (a
9112 // Private Name) and returns a function object.
9113 if (!abortIfSyntaxParser()) {
9114 return errorResult();
9115 }
9116
9117 AccessorType accessorType = syntaxKind == FunctionSyntaxKind::Getter
9118 ? AccessorType::Getter
9119 : AccessorType::Setter;
9120
9121 mozilla::Maybe<FunctionNodeType> initializerIfPrivate = Nothing();
9122 if (!isStatic && handler_.isPrivateName(propName)) {
9123 classInitializedMembers.privateAccessors++;
9124 FunctionNodeType initializerNode;
9125 MOZ_TRY_VAR(initializerNode, synthesizePrivateMethodInitializer(do { auto mozTryVarTempResult_ = (synthesizePrivateMethodInitializer
( propAtom, accessorType, propNamePos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerNode) = mozTryVarTempResult_.unwrap
(); } while (0)
9126 propAtom, accessorType, propNamePos))do { auto mozTryVarTempResult_ = (synthesizePrivateMethodInitializer
( propAtom, accessorType, propNamePos)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerNode) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9127 initializerIfPrivate = Some(initializerNode);
9128 handler_.setPrivateNameKind(propName, PrivateNameKind::GetterSetter);
9129 }
9130
9131 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9132 // 2. Let getter be CreateBuiltinFunction(getterClosure, 0, "get", « »).
9133 //
9134 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9135 // 2. Let setter be CreateBuiltinFunction(setterClosure, 1, "set", « »).
9136 StringBuilder storedMethodName(fc_);
9137 if (!storedMethodName.append(accessorType == AccessorType::Getter ? "get"
9138 : "set")) {
9139 return errorResult();
9140 }
9141 TaggedParserAtomIndex funNameAtom =
9142 storedMethodName.finishParserAtom(this->parserAtoms(), fc_);
9143
9144 FunctionNodeType funNode;
9145 MOZ_TRY_VAR(funNode,do { auto mozTryVarTempResult_ = (synthesizeAccessorBody(funNameAtom
, propNamePos, privateStateNameAtom, syntaxKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (funNode) = mozTryVarTempResult_.unwrap();
} while (0)
9146 synthesizeAccessorBody(funNameAtom, propNamePos,do { auto mozTryVarTempResult_ = (synthesizeAccessorBody(funNameAtom
, propNamePos, privateStateNameAtom, syntaxKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (funNode) = mozTryVarTempResult_.unwrap();
} while (0)
9147 privateStateNameAtom, syntaxKind))do { auto mozTryVarTempResult_ = (synthesizeAccessorBody(funNameAtom
, propNamePos, privateStateNameAtom, syntaxKind)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (funNode) = mozTryVarTempResult_.unwrap();
} while (0)
;
9148
9149 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9150 // 3. Perform MakeMethod(getter, homeObject).
9151 // 4. Return getter.
9152 //
9153 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9154 // 3. Perform MakeMethod(setter, homeObject).
9155 // 4. Return setter.
9156 return handler_.newClassMethodDefinition(
9157 propName, funNode, accessorType, isStatic, initializerIfPrivate, null());
9158}
9159
9160template <class ParseHandler, typename Unit>
9161typename ParseHandler::FunctionNodeResult
9162GeneralParser<ParseHandler, Unit>::synthesizeAccessorBody(
9163 TaggedParserAtomIndex funNameAtom, TokenPos propNamePos,
9164 TaggedParserAtomIndex propNameAtom, FunctionSyntaxKind syntaxKind) {
9165 if (!abortIfSyntaxParser()) {
9166 return errorResult();
9167 }
9168
9169 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
9170 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
9171 bool isSelfHosting = options().selfHostingMode;
9172 FunctionFlags flags =
9173 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
9174
9175 // Create the top-level function node.
9176 FunctionNodeType funNode;
9177 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
9178
9179 // Create the FunctionBox and link it to the function object.
9180 Directives directives(true);
9181 FunctionBox* funbox =
9182 newFunctionBox(funNode, funNameAtom, flags, propNamePos.begin, directives,
9183 generatorKind, asyncKind);
9184 if (!funbox) {
9185 return errorResult();
9186 }
9187 funbox->initWithEnclosingParseContext(pc_, syntaxKind);
9188 funbox->setSyntheticFunction();
9189
9190 // Push a SourceParseContext on to the stack.
9191 ParseContext* outerpc = pc_;
9192 SourceParseContext funpc(this, funbox, /* newDirectives = */ nullptr);
9193 if (!funpc.init()) {
9194 return errorResult();
9195 }
9196
9197 pc_->functionScope().useAsVarScope(pc_);
9198
9199 // The function we synthesize is located at the field with the
9200 // accessor.
9201 setFunctionStartAtCurrentToken(funbox);
9202 setFunctionEndFromCurrentToken(funbox);
9203
9204 // Create a ListNode for the parameters + body
9205 ParamsBodyNodeType paramsbody;
9206 MOZ_TRY_VAR(paramsbody, handler_.newParamsBody(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newParamsBody(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (paramsbody
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9207 handler_.setFunctionFormalParametersAndBody(funNode, paramsbody);
9208
9209 if (syntaxKind == FunctionSyntaxKind::Getter) {
9210 funbox->setArgCount(0);
9211 } else {
9212 funbox->setArgCount(1);
9213 }
9214
9215 // Build `this` expression to access the privateStateName for use in the
9216 // operations to create the getter and setter below.
9217 NameNodeType thisName;
9218 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
9219
9220 ThisLiteralType propThis;
9221 MOZ_TRY_VAR(propThis, handler_.newThisLiteral(propNamePos, thisName))do { auto mozTryVarTempResult_ = (handler_.newThisLiteral(propNamePos
, thisName)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propThis
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9222
9223 NameNodeType privateNameNode;
9224 MOZ_TRY_VAR(privateNameNode, privateNameReference(propNameAtom))do { auto mozTryVarTempResult_ = (privateNameReference(propNameAtom
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (privateNameNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9225
9226 Node propFieldAccess;
9227 MOZ_TRY_VAR(propFieldAccess, handler_.newPrivateMemberAccess(do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
( propThis, privateNameNode, propNamePos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propFieldAccess) = mozTryVarTempResult_.unwrap
(); } while (0)
9228 propThis, privateNameNode, propNamePos.end))do { auto mozTryVarTempResult_ = (handler_.newPrivateMemberAccess
( propThis, privateNameNode, propNamePos.end)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propFieldAccess) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9229
9230 Node accessorBody;
9231 if (syntaxKind == FunctionSyntaxKind::Getter) {
9232 // Decorators Proposal
9233 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorgetter
9234 // 1. Let getterClosure be a new Abstract Closure with no parameters that
9235 // captures privateStateName and performs the following steps when called:
9236 // 1.a. Let o be the this value.
9237 // 1.b. Return ? PrivateGet(privateStateName, o).
9238 MOZ_TRY_VAR(accessorBody,do { auto mozTryVarTempResult_ = (handler_.newReturnStatement
(propFieldAccess, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
9239 handler_.newReturnStatement(propFieldAccess, propNamePos))do { auto mozTryVarTempResult_ = (handler_.newReturnStatement
(propFieldAccess, propNamePos)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
;
9240 } else {
9241 // Decorators Proposal
9242 // https://arai-a.github.io/ecma262-compare/?pr=2417&id=sec-makeautoaccessorsetter
9243 // The abstract operation MakeAutoAccessorSetter takes arguments homeObject
9244 // (an Object), name (a property key or Private Name), and privateStateName
9245 // (a Private Name) and returns a function object.
9246 // 1. Let setterClosure be a new Abstract Closure with parameters (value)
9247 // that captures privateStateName and performs the following steps when
9248 // called:
9249 // 1.a. Let o be the this value.
9250 notePositionalFormalParameter(funNode,
9251 TaggedParserAtomIndex::WellKnown::value(),
9252 /* pos = */ 0, false,
9253 /* duplicatedParam = */ nullptr);
9254
9255 Node initializerExpr;
9256 MOZ_TRY_VAR(initializerExpr,do { auto mozTryVarTempResult_ = (handler_.newName(TaggedParserAtomIndex
::WellKnown::value(), propNamePos)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerExpr) = mozTryVarTempResult_.unwrap
(); } while (0)
9257 handler_.newName(TaggedParserAtomIndex::WellKnown::value(),do { auto mozTryVarTempResult_ = (handler_.newName(TaggedParserAtomIndex
::WellKnown::value(), propNamePos)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerExpr) = mozTryVarTempResult_.unwrap
(); } while (0)
9258 propNamePos))do { auto mozTryVarTempResult_ = (handler_.newName(TaggedParserAtomIndex
::WellKnown::value(), propNamePos)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (initializerExpr) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9259
9260 // 1.b. Perform ? PrivateSet(privateStateName, o, value).
9261 Node assignment;
9262 MOZ_TRY_VAR(assignment,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, propFieldAccess, initializerExpr)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (assignment) = mozTryVarTempResult_.unwrap
(); } while (0)
9263 handler_.newAssignment(ParseNodeKind::AssignExpr,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, propFieldAccess, initializerExpr)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (assignment) = mozTryVarTempResult_.unwrap
(); } while (0)
9264 propFieldAccess, initializerExpr))do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, propFieldAccess, initializerExpr)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (assignment) = mozTryVarTempResult_.unwrap
(); } while (0)
;
9265
9266 MOZ_TRY_VAR(accessorBody,do { auto mozTryVarTempResult_ = (handler_.newExprStatement(assignment
, propNamePos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
9267 handler_.newExprStatement(assignment, propNamePos.end))do { auto mozTryVarTempResult_ = (handler_.newExprStatement(assignment
, propNamePos.end)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (accessorBody) = mozTryVarTempResult_.unwrap(); } while (0
)
;
9268
9269 // 1.c. Return undefined.
9270 }
9271
9272 ListNodeType statementList;
9273 MOZ_TRY_VAR(statementList, handler_.newStatementList(propNamePos))do { auto mozTryVarTempResult_ = (handler_.newStatementList(propNamePos
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (statementList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
9274 handler_.addStatementToList(statementList, accessorBody);
9275
9276 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
9277 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
9278 return errorResult();
9279 }
9280 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
9281 return errorResult();
9282 }
9283
9284 LexicalScopeNodeType initializerBody;
9285 MOZ_TRY_VAR(initializerBody,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9286 finishLexicalScope(pc_->varScope(), statementList,do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
9287 ScopeKind::FunctionLexical))do { auto mozTryVarTempResult_ = (finishLexicalScope(pc_->
varScope(), statementList, ScopeKind::FunctionLexical)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (initializerBody) = mozTryVarTempResult_
.unwrap(); } while (0)
;
9288
9289 handler_.setFunctionBody(funNode, initializerBody);
9290
9291 if (pc_->superScopeNeedsHomeObject()) {
9292 funbox->setNeedsHomeObject();
9293 }
9294
9295 if (!finishFunction()) {
9296 return errorResult();
9297 }
9298
9299 if (!leaveInnerFunction(outerpc)) {
9300 return errorResult();
9301 }
9302
9303 return funNode;
9304}
9305
9306#endif
9307
9308bool ParserBase::nextTokenContinuesLetDeclaration(TokenKind next) {
9309 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Let))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Let))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::Let)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Let)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9309); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Let)"
")"); do { *((volatile int*)__null) = 9309; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9310 MOZ_ASSERT(anyChars.nextToken().type == next)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.nextToken().type == next)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.nextToken().type ==
next))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.nextToken().type == next", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9310); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.nextToken().type == next"
")"); do { *((volatile int*)__null) = 9310; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9311
9312 TokenStreamShared::verifyConsistentModifier(TokenStreamShared::SlashIsDiv,
9313 anyChars.nextToken());
9314
9315 // Destructuring continues a let declaration.
9316 if (next == TokenKind::LeftBracket || next == TokenKind::LeftCurly) {
9317 return true;
9318 }
9319
9320 // A "let" edge case deserves special comment. Consider this:
9321 //
9322 // let // not an ASI opportunity
9323 // let;
9324 //
9325 // Static semantics in §13.3.1.1 turn a LexicalDeclaration that binds
9326 // "let" into an early error. Does this retroactively permit ASI so
9327 // that we should parse this as two ExpressionStatements? No. ASI
9328 // resolves during parsing. Static semantics only apply to the full
9329 // parse tree with ASI applied. No backsies!
9330
9331 // Otherwise a let declaration must have a name.
9332 return TokenKindIsPossibleIdentifier(next);
9333}
9334
9335template <class ParseHandler, typename Unit>
9336typename ParseHandler::DeclarationListNodeResult
9337GeneralParser<ParseHandler, Unit>::variableStatement(
9338 YieldHandling yieldHandling) {
9339 DeclarationListNodeType vars;
9340 MOZ_TRY_VAR(vars, declarationList(yieldHandling, ParseNodeKind::VarStmt))do { auto mozTryVarTempResult_ = (declarationList(yieldHandling
, ParseNodeKind::VarStmt)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (vars) = mozTryVarTempResult_.unwrap(); } while (0)
;
9341 if (!matchOrInsertSemicolon()) {
9342 return errorResult();
9343 }
9344 return vars;
9345}
9346
9347template <class ParseHandler, typename Unit>
9348typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::statement(
9349 YieldHandling yieldHandling) {
9350 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9350); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 9350; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9351
9352 AutoCheckRecursionLimit recursion(this->fc_);
9353 if (!recursion.check(this->fc_)) {
9354 return errorResult();
9355 }
9356
9357 TokenKind tt;
9358 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
9359 return errorResult();
9360 }
9361
9362 switch (tt) {
9363 // BlockStatement[?Yield, ?Return]
9364 case TokenKind::LeftCurly:
9365 return blockStatement(yieldHandling);
9366
9367 // VariableStatement[?Yield]
9368 case TokenKind::Var:
9369 return variableStatement(yieldHandling);
9370
9371 // EmptyStatement
9372 case TokenKind::Semi:
9373 return handler_.newEmptyStatement(pos());
9374
9375 // ExpressionStatement[?Yield].
9376
9377 case TokenKind::Yield: {
9378 // Don't use a ternary operator here due to obscure linker issues
9379 // around using static consts in the arms of a ternary.
9380 Modifier modifier;
9381 if (yieldExpressionsSupported()) {
9382 modifier = TokenStream::SlashIsRegExp;
9383 } else {
9384 modifier = TokenStream::SlashIsDiv;
9385 }
9386
9387 TokenKind next;
9388 if (!tokenStream.peekToken(&next, modifier)) {
9389 return errorResult();
9390 }
9391
9392 if (next == TokenKind::Colon) {
9393 return labeledStatement(yieldHandling);
9394 }
9395
9396 return expressionStatement(yieldHandling);
9397 }
9398
9399 default: {
9400 // If we encounter an await in a module, and the module is not marked
9401 // as async, mark the module as async.
9402 if (tt == TokenKind::Await && !pc_->isAsync()) {
9403 if (pc_->atModuleTopLevel()) {
9404 if (!options().topLevelAwait) {
9405 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
9406 return errorResult();
9407 }
9408 pc_->sc()->asModuleContext()->setIsAsync();
9409 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9409); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 9409; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9410 }
9411 }
9412
9413 // Avoid getting next token with SlashIsDiv.
9414 if (tt == TokenKind::Await && pc_->isAsync()) {
9415 return expressionStatement(yieldHandling);
9416 }
9417
9418 if (!TokenKindIsPossibleIdentifier(tt)) {
9419 return expressionStatement(yieldHandling);
9420 }
9421
9422 TokenKind next;
9423 if (!tokenStream.peekToken(&next)) {
9424 return errorResult();
9425 }
9426
9427 // |let| here can only be an Identifier, not a declaration. Give nicer
9428 // errors for declaration-looking typos.
9429 if (tt == TokenKind::Let) {
9430 bool forbiddenLetDeclaration = false;
9431
9432 if (next == TokenKind::LeftBracket) {
9433 // Enforce ExpressionStatement's 'let [' lookahead restriction.
9434 forbiddenLetDeclaration = true;
9435 } else if (next == TokenKind::LeftCurly ||
9436 TokenKindIsPossibleIdentifier(next)) {
9437 // 'let {' and 'let foo' aren't completely forbidden, if ASI
9438 // causes 'let' to be the entire Statement. But if they're
9439 // same-line, we can aggressively give a better error message.
9440 //
9441 // Note that this ignores 'yield' as TokenKind::Yield: we'll handle it
9442 // correctly but with a worse error message.
9443 TokenKind nextSameLine;
9444 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
9445 return errorResult();
9446 }
9447
9448 MOZ_ASSERT(TokenKindIsPossibleIdentifier(nextSameLine) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9450); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9450; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9449 nextSameLine == TokenKind::LeftCurly ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9450); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9450; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
9450 nextSameLine == TokenKind::Eol)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine
== TokenKind::LeftCurly || nextSameLine == TokenKind::Eol)))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9450); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(nextSameLine) || nextSameLine == TokenKind::LeftCurly || nextSameLine == TokenKind::Eol"
")"); do { *((volatile int*)__null) = 9450; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9451
9452 forbiddenLetDeclaration = nextSameLine != TokenKind::Eol;
9453 }
9454
9455 if (forbiddenLetDeclaration) {
9456 error(JSMSG_FORBIDDEN_AS_STATEMENT, "lexical declarations");
9457 return errorResult();
9458 }
9459 } else if (tt == TokenKind::Async) {
9460 // Peek only on the same line: ExpressionStatement's lookahead
9461 // restriction is phrased as
9462 //
9463 // [lookahead ∉ { '{',
9464 // function,
9465 // async [no LineTerminator here] function,
9466 // class,
9467 // let '[' }]
9468 //
9469 // meaning that code like this is valid:
9470 //
9471 // if (true)
9472 // async // ASI opportunity
9473 // function clownshoes() {}
9474 TokenKind maybeFunction;
9475 if (!tokenStream.peekTokenSameLine(&maybeFunction)) {
9476 return errorResult();
9477 }
9478
9479 if (maybeFunction == TokenKind::Function) {
9480 error(JSMSG_FORBIDDEN_AS_STATEMENT, "async function declarations");
9481 return errorResult();
9482 }
9483
9484 // Otherwise this |async| begins an ExpressionStatement or is a
9485 // label name.
9486 }
9487
9488 // NOTE: It's unfortunately allowed to have a label named 'let' in
9489 // non-strict code. 💯
9490 if (next == TokenKind::Colon) {
9491 return labeledStatement(yieldHandling);
9492 }
9493
9494 return expressionStatement(yieldHandling);
9495 }
9496
9497 case TokenKind::New:
9498 return expressionStatement(yieldHandling, PredictInvoked);
9499
9500 // IfStatement[?Yield, ?Return]
9501 case TokenKind::If:
9502 return ifStatement(yieldHandling);
9503
9504 // BreakableStatement[?Yield, ?Return]
9505 //
9506 // BreakableStatement[Yield, Return]:
9507 // IterationStatement[?Yield, ?Return]
9508 // SwitchStatement[?Yield, ?Return]
9509 case TokenKind::Do:
9510 return doWhileStatement(yieldHandling);
9511
9512 case TokenKind::While:
9513 return whileStatement(yieldHandling);
9514
9515 case TokenKind::For:
9516 return forStatement(yieldHandling);
9517
9518 case TokenKind::Switch:
9519 return switchStatement(yieldHandling);
9520
9521 // ContinueStatement[?Yield]
9522 case TokenKind::Continue:
9523 return continueStatement(yieldHandling);
9524
9525 // BreakStatement[?Yield]
9526 case TokenKind::Break:
9527 return breakStatement(yieldHandling);
9528
9529 // [+Return] ReturnStatement[?Yield]
9530 case TokenKind::Return:
9531 // The Return parameter is only used here, and the effect is easily
9532 // detected this way, so don't bother passing around an extra parameter
9533 // everywhere.
9534 if (!pc_->allowReturn()) {
9535 error(JSMSG_BAD_RETURN_OR_YIELD, "return");
9536 return errorResult();
9537 }
9538 return returnStatement(yieldHandling);
9539
9540 // WithStatement[?Yield, ?Return]
9541 case TokenKind::With:
9542 return withStatement(yieldHandling);
9543
9544 // LabelledStatement[?Yield, ?Return]
9545 // This is really handled by default and TokenKind::Yield cases above.
9546
9547 // ThrowStatement[?Yield]
9548 case TokenKind::Throw:
9549 return throwStatement(yieldHandling);
9550
9551 // TryStatement[?Yield, ?Return]
9552 case TokenKind::Try:
9553 return tryStatement(yieldHandling);
9554
9555 // DebuggerStatement
9556 case TokenKind::Debugger:
9557 return debuggerStatement();
9558
9559 // |function| is forbidden by lookahead restriction (unless as child
9560 // statement of |if| or |else|, but Parser::consequentOrAlternative
9561 // handles that).
9562 case TokenKind::Function:
9563 error(JSMSG_FORBIDDEN_AS_STATEMENT, "function declarations");
9564 return errorResult();
9565
9566 // |class| is also forbidden by lookahead restriction.
9567 case TokenKind::Class:
9568 error(JSMSG_FORBIDDEN_AS_STATEMENT, "classes");
9569 return errorResult();
9570
9571 // ImportDeclaration (only inside modules)
9572 case TokenKind::Import:
9573 return importDeclarationOrImportExpr(yieldHandling);
9574
9575 // ExportDeclaration (only inside modules)
9576 case TokenKind::Export:
9577 return exportDeclaration();
9578
9579 // Miscellaneous error cases arguably better caught here than elsewhere.
9580
9581 case TokenKind::Catch:
9582 error(JSMSG_CATCH_WITHOUT_TRY);
9583 return errorResult();
9584
9585 case TokenKind::Finally:
9586 error(JSMSG_FINALLY_WITHOUT_TRY);
9587 return errorResult();
9588
9589 // NOTE: default case handled in the ExpressionStatement section.
9590 }
9591}
9592
9593template <class ParseHandler, typename Unit>
9594typename ParseHandler::NodeResult
9595GeneralParser<ParseHandler, Unit>::statementListItem(
9596 YieldHandling yieldHandling, bool canHaveDirectives /* = false */) {
9597 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9597); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 9597; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9598
9599 AutoCheckRecursionLimit recursion(this->fc_);
9600 if (!recursion.check(this->fc_)) {
9601 return errorResult();
9602 }
9603
9604 TokenKind tt;
9605 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
9606 return errorResult();
9607 }
9608
9609 switch (tt) {
9610 // BlockStatement[?Yield, ?Return]
9611 case TokenKind::LeftCurly:
9612 return blockStatement(yieldHandling);
9613
9614 // VariableStatement[?Yield]
9615 case TokenKind::Var:
9616 return variableStatement(yieldHandling);
9617
9618 // EmptyStatement
9619 case TokenKind::Semi:
9620 return handler_.newEmptyStatement(pos());
9621
9622 // ExpressionStatement[?Yield].
9623 //
9624 // These should probably be handled by a single ExpressionStatement
9625 // function in a default, not split up this way.
9626 case TokenKind::String:
9627 if (!canHaveDirectives &&
9628 anyChars.currentToken().atom() ==
9629 TaggedParserAtomIndex::WellKnown::use_asm_()) {
9630 if (!warning(JSMSG_USE_ASM_DIRECTIVE_FAIL)) {
9631 return errorResult();
9632 }
9633 }
9634 return expressionStatement(yieldHandling);
9635
9636 case TokenKind::Yield: {
9637 // Don't use a ternary operator here due to obscure linker issues
9638 // around using static consts in the arms of a ternary.
9639 Modifier modifier;
9640 if (yieldExpressionsSupported()) {
9641 modifier = TokenStream::SlashIsRegExp;
9642 } else {
9643 modifier = TokenStream::SlashIsDiv;
9644 }
9645
9646 TokenKind next;
9647 if (!tokenStream.peekToken(&next, modifier)) {
9648 return errorResult();
9649 }
9650
9651 if (next == TokenKind::Colon) {
9652 return labeledStatement(yieldHandling);
9653 }
9654
9655 return expressionStatement(yieldHandling);
9656 }
9657
9658 default: {
9659 // If we encounter an await in a module, and the module is not marked
9660 // as async, mark the module as async.
9661 if (tt == TokenKind::Await && !pc_->isAsync()) {
9662 if (pc_->atModuleTopLevel()) {
9663 if (!options().topLevelAwait) {
9664 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
9665 return errorResult();
9666 }
9667 pc_->sc()->asModuleContext()->setIsAsync();
9668 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9668); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 9668; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9669 }
9670 }
9671
9672 if (tt == TokenKind::Await && pc_->isAsync()) {
9673#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
9674 if (options().explicitResourceManagement()) {
9675 // Try finding evidence of a AwaitUsingDeclaration the syntax for
9676 // which
9677 // would be:
9678 // await [no LineTerminator here] using [no LineTerminator here]
9679 // identifier
9680
9681 TokenKind nextTokUsing = TokenKind::Eof;
9682 // Scan with regex modifier because when its await expression, `/`
9683 // should be treated as a regexp.
9684 if (!tokenStream.peekTokenSameLine(&nextTokUsing,
9685 TokenStream::SlashIsRegExp)) {
9686 return errorResult();
9687 }
9688
9689 if (nextTokUsing == TokenKind::Using &&
9690 this->pc_->isUsingSyntaxAllowed()) {
9691 tokenStream.consumeKnownToken(nextTokUsing,
9692 TokenStream::SlashIsRegExp);
9693 TokenKind nextTokIdentifier = TokenKind::Eof;
9694 // Here we can use the Div modifier because if the next token is
9695 // using then a `/` as the next token can only be considered a
9696 // division.
9697 if (!tokenStream.peekTokenSameLine(&nextTokIdentifier)) {
9698 return errorResult();
9699 }
9700 if (TokenKindIsPossibleIdentifier(nextTokIdentifier)) {
9701 return lexicalDeclaration(yieldHandling,
9702 DeclarationKind::AwaitUsing);
9703 }
9704 anyChars.ungetToken(); // put back using.
9705 }
9706 }
9707#endif
9708 return expressionStatement(yieldHandling);
9709 }
9710
9711 if (!TokenKindIsPossibleIdentifier(tt)) {
9712 return expressionStatement(yieldHandling);
9713 }
9714
9715 TokenKind next;
9716 if (!tokenStream.peekToken(&next)) {
9717 return errorResult();
9718 }
9719
9720 if (tt == TokenKind::Let && nextTokenContinuesLetDeclaration(next)) {
9721 return lexicalDeclaration(yieldHandling, DeclarationKind::Let);
9722 }
9723
9724 if (tt == TokenKind::Async) {
9725 TokenKind nextSameLine = TokenKind::Eof;
9726 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
9727 return errorResult();
9728 }
9729 if (nextSameLine == TokenKind::Function) {
9730 uint32_t toStringStart = pos().begin;
9731 tokenStream.consumeKnownToken(TokenKind::Function);
9732 return functionStmt(toStringStart, yieldHandling, NameRequired,
9733 FunctionAsyncKind::AsyncFunction);
9734 }
9735 }
9736
9737 if (next == TokenKind::Colon) {
9738 return labeledStatement(yieldHandling);
9739 }
9740
9741 return expressionStatement(yieldHandling);
9742 }
9743
9744 case TokenKind::New:
9745 return expressionStatement(yieldHandling, PredictInvoked);
9746
9747 // IfStatement[?Yield, ?Return]
9748 case TokenKind::If:
9749 return ifStatement(yieldHandling);
9750
9751 // BreakableStatement[?Yield, ?Return]
9752 //
9753 // BreakableStatement[Yield, Return]:
9754 // IterationStatement[?Yield, ?Return]
9755 // SwitchStatement[?Yield, ?Return]
9756 case TokenKind::Do:
9757 return doWhileStatement(yieldHandling);
9758
9759 case TokenKind::While:
9760 return whileStatement(yieldHandling);
9761
9762 case TokenKind::For:
9763 return forStatement(yieldHandling);
9764
9765 case TokenKind::Switch:
9766 return switchStatement(yieldHandling);
9767
9768 // ContinueStatement[?Yield]
9769 case TokenKind::Continue:
9770 return continueStatement(yieldHandling);
9771
9772 // BreakStatement[?Yield]
9773 case TokenKind::Break:
9774 return breakStatement(yieldHandling);
9775
9776 // [+Return] ReturnStatement[?Yield]
9777 case TokenKind::Return:
9778 // The Return parameter is only used here, and the effect is easily
9779 // detected this way, so don't bother passing around an extra parameter
9780 // everywhere.
9781 if (!pc_->allowReturn()) {
9782 error(JSMSG_BAD_RETURN_OR_YIELD, "return");
9783 return errorResult();
9784 }
9785 return returnStatement(yieldHandling);
9786
9787 // WithStatement[?Yield, ?Return]
9788 case TokenKind::With:
9789 return withStatement(yieldHandling);
9790
9791 // LabelledStatement[?Yield, ?Return]
9792 // This is really handled by default and TokenKind::Yield cases above.
9793
9794 // ThrowStatement[?Yield]
9795 case TokenKind::Throw:
9796 return throwStatement(yieldHandling);
9797
9798 // TryStatement[?Yield, ?Return]
9799 case TokenKind::Try:
9800 return tryStatement(yieldHandling);
9801
9802 // DebuggerStatement
9803 case TokenKind::Debugger:
9804 return debuggerStatement();
9805
9806 // Declaration[Yield]:
9807
9808 // HoistableDeclaration[?Yield, ~Default]
9809 case TokenKind::Function:
9810 return functionStmt(pos().begin, yieldHandling, NameRequired);
9811
9812 // DecoratorList[?Yield, ?Await] opt ClassDeclaration[?Yield, ~Default]
9813#ifdef ENABLE_DECORATORS
9814 case TokenKind::At:
9815 return classDefinition(yieldHandling, ClassStatement, NameRequired);
9816#endif
9817
9818 case TokenKind::Class:
9819 return classDefinition(yieldHandling, ClassStatement, NameRequired);
9820
9821 // LexicalDeclaration[In, ?Yield]
9822 // LetOrConst BindingList[?In, ?Yield]
9823 case TokenKind::Const:
9824 // [In] is the default behavior, because for-loops specially parse
9825 // their heads to handle |in| in this situation.
9826 return lexicalDeclaration(yieldHandling, DeclarationKind::Const);
9827
9828#ifdef ENABLE_EXPLICIT_RESOURCE_MANAGEMENT1
9829 case TokenKind::Using: {
9830 TokenKind nextTok = TokenKind::Eol;
9831 if (!tokenStream.peekTokenSameLine(&nextTok)) {
9832 return errorResult();
9833 }
9834 if (!options().explicitResourceManagement() ||
9835 !TokenKindIsPossibleIdentifier(nextTok) ||
9836 !this->pc_->isUsingSyntaxAllowed()) {
9837 if (!tokenStream.peekToken(&nextTok)) {
9838 return errorResult();
9839 }
9840 // labelled statement could be like using\n:\nexpr
9841 if (nextTok == TokenKind::Colon) {
9842 return labeledStatement(yieldHandling);
9843 }
9844 return expressionStatement(yieldHandling);
9845 }
9846 return lexicalDeclaration(yieldHandling, DeclarationKind::Using);
9847 }
9848#endif
9849
9850 // ImportDeclaration (only inside modules)
9851 case TokenKind::Import:
9852 return importDeclarationOrImportExpr(yieldHandling);
9853
9854 // ExportDeclaration (only inside modules)
9855 case TokenKind::Export:
9856 return exportDeclaration();
9857
9858 // Miscellaneous error cases arguably better caught here than elsewhere.
9859
9860 case TokenKind::Catch:
9861 error(JSMSG_CATCH_WITHOUT_TRY);
9862 return errorResult();
9863
9864 case TokenKind::Finally:
9865 error(JSMSG_FINALLY_WITHOUT_TRY);
9866 return errorResult();
9867
9868 // NOTE: default case handled in the ExpressionStatement section.
9869 }
9870}
9871
9872template <class ParseHandler, typename Unit>
9873typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::expr(
9874 InHandling inHandling, YieldHandling yieldHandling,
9875 TripledotHandling tripledotHandling,
9876 PossibleError* possibleError /* = nullptr */,
9877 InvokedPrediction invoked /* = PredictUninvoked */) {
9878 Node pn;
9879 MOZ_TRY_VAR(pn, assignExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
9880 possibleError, invoked))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
;
9881
9882 bool matched;
9883 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
9884 TokenStream::SlashIsRegExp)) {
9885 return errorResult();
9886 }
9887 if (!matched) {
9888 return pn;
9889 }
9890
9891 ListNodeType seq;
9892 MOZ_TRY_VAR(seq, handler_.newCommaExpressionList(pn))do { auto mozTryVarTempResult_ = (handler_.newCommaExpressionList
(pn)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr())
, 0))) { return mozTryVarTempResult_.propagateErr(); } (seq) =
mozTryVarTempResult_.unwrap(); } while (0)
;
9893 while (true) {
9894 // Trailing comma before the closing parenthesis is valid in an arrow
9895 // function parameters list: `(a, b, ) => body`. Check if we are
9896 // directly under CoverParenthesizedExpressionAndArrowParameterList,
9897 // and the next two tokens are closing parenthesis and arrow. If all
9898 // are present allow the trailing comma.
9899 if (tripledotHandling == TripledotAllowed) {
9900 TokenKind tt;
9901 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
9902 return errorResult();
9903 }
9904
9905 if (tt == TokenKind::RightParen) {
9906 tokenStream.consumeKnownToken(TokenKind::RightParen,
9907 TokenStream::SlashIsRegExp);
9908
9909 if (!tokenStream.peekToken(&tt)) {
9910 return errorResult();
9911 }
9912 if (tt != TokenKind::Arrow) {
9913 error(JSMSG_UNEXPECTED_TOKEN, "expression",
9914 TokenKindToDesc(TokenKind::RightParen));
9915 return errorResult();
9916 }
9917
9918 anyChars.ungetToken(); // put back right paren
9919 break;
9920 }
9921 }
9922
9923 // Additional calls to assignExpr should not reuse the possibleError
9924 // which had been passed into the function. Otherwise we would lose
9925 // information needed to determine whether or not we're dealing with
9926 // a non-recoverable situation.
9927 PossibleError possibleErrorInner(*this);
9928 MOZ_TRY_VAR(pn, assignExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
9929 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
;
9930
9931 if (!possibleError) {
9932 // Report any pending expression error.
9933 if (!possibleErrorInner.checkForExpressionError()) {
9934 return errorResult();
9935 }
9936 } else {
9937 possibleErrorInner.transferErrorsTo(possibleError);
9938 }
9939
9940 handler_.addList(seq, pn);
9941
9942 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
9943 TokenStream::SlashIsRegExp)) {
9944 return errorResult();
9945 }
9946 if (!matched) {
9947 break;
9948 }
9949 }
9950 return seq;
9951}
9952
9953static ParseNodeKind BinaryOpTokenKindToParseNodeKind(TokenKind tok) {
9954 MOZ_ASSERT(TokenKindIsBinaryOp(tok))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsBinaryOp(tok))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(TokenKindIsBinaryOp(tok)))),
0))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsBinaryOp(tok)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 9954); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsBinaryOp(tok)"
")"); do { *((volatile int*)__null) = 9954; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
9955 return ParseNodeKind(size_t(ParseNodeKind::BinOpFirst) +
9956 (size_t(tok) - size_t(TokenKind::BinOpFirst)));
9957}
9958
9959// This list must be kept in the same order in several places:
9960// - The binary operators in ParseNode.h ,
9961// - the binary operators in TokenKind.h
9962// - the JSOp code list in BytecodeEmitter.cpp
9963static const int PrecedenceTable[] = {
9964 1, /* ParseNodeKind::Coalesce */
9965 2, /* ParseNodeKind::Or */
9966 3, /* ParseNodeKind::And */
9967 4, /* ParseNodeKind::BitOr */
9968 5, /* ParseNodeKind::BitXor */
9969 6, /* ParseNodeKind::BitAnd */
9970 7, /* ParseNodeKind::StrictEq */
9971 7, /* ParseNodeKind::Eq */
9972 7, /* ParseNodeKind::StrictNe */
9973 7, /* ParseNodeKind::Ne */
9974 8, /* ParseNodeKind::Lt */
9975 8, /* ParseNodeKind::Le */
9976 8, /* ParseNodeKind::Gt */
9977 8, /* ParseNodeKind::Ge */
9978 8, /* ParseNodeKind::InstanceOf */
9979 8, /* ParseNodeKind::In */
9980 8, /* ParseNodeKind::PrivateIn */
9981 9, /* ParseNodeKind::Lsh */
9982 9, /* ParseNodeKind::Rsh */
9983 9, /* ParseNodeKind::Ursh */
9984 10, /* ParseNodeKind::Add */
9985 10, /* ParseNodeKind::Sub */
9986 11, /* ParseNodeKind::Star */
9987 11, /* ParseNodeKind::Div */
9988 11, /* ParseNodeKind::Mod */
9989 12 /* ParseNodeKind::Pow */
9990};
9991
9992static const int PRECEDENCE_CLASSES = 12;
9993
9994static int Precedence(ParseNodeKind pnk) {
9995 // Everything binds tighter than ParseNodeKind::Limit, because we want
9996 // to reduce all nodes to a single node when we reach a token that is not
9997 // another binary operator.
9998 if (pnk == ParseNodeKind::Limit) {
9999 return 0;
10000 }
10001
10002 MOZ_ASSERT(pnk >= ParseNodeKind::BinOpFirst)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pnk >= ParseNodeKind::BinOpFirst)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pnk >= ParseNodeKind::BinOpFirst
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"pnk >= ParseNodeKind::BinOpFirst", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10002); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pnk >= ParseNodeKind::BinOpFirst"
")"); do { *((volatile int*)__null) = 10002; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10003 MOZ_ASSERT(pnk <= ParseNodeKind::BinOpLast)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pnk <= ParseNodeKind::BinOpLast)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pnk <= ParseNodeKind::BinOpLast
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"pnk <= ParseNodeKind::BinOpLast", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10003); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pnk <= ParseNodeKind::BinOpLast"
")"); do { *((volatile int*)__null) = 10003; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10004 return PrecedenceTable[size_t(pnk) - size_t(ParseNodeKind::BinOpFirst)];
10005}
10006
10007enum class EnforcedParentheses : uint8_t { CoalesceExpr, AndOrExpr, None };
10008
10009template <class ParseHandler, typename Unit>
10010MOZ_ALWAYS_INLINEinline typename ParseHandler::NodeResult
10011GeneralParser<ParseHandler, Unit>::orExpr(InHandling inHandling,
10012 YieldHandling yieldHandling,
10013 TripledotHandling tripledotHandling,
10014 PossibleError* possibleError,
10015 InvokedPrediction invoked) {
10016 // Shift-reduce parser for the binary operator part of the JS expression
10017 // syntax.
10018
10019 // Conceptually there's just one stack, a stack of pairs (lhs, op).
10020 // It's implemented using two separate arrays, though.
10021 Node nodeStack[PRECEDENCE_CLASSES];
10022 ParseNodeKind kindStack[PRECEDENCE_CLASSES];
10023 int depth = 0;
10024 Node pn;
10025 EnforcedParentheses unparenthesizedExpression = EnforcedParentheses::None;
10026 for (;;) {
10027 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked, PrivateNameHandling::PrivateNameAllowed
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
10028 pn, unaryExpr(yieldHandling, tripledotHandling, possibleError, invoked,do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked, PrivateNameHandling::PrivateNameAllowed
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
10029 PrivateNameHandling::PrivateNameAllowed))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked, PrivateNameHandling::PrivateNameAllowed
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (pn) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10030
10031 // If a binary operator follows, consume it and compute the
10032 // corresponding operator.
10033 TokenKind tok;
10034 if (!tokenStream.getToken(&tok)) {
10035 return errorResult();
10036 }
10037
10038 // Ensure that if we have a private name lhs we are legally constructing a
10039 // `#x in obj` expessions:
10040 if (handler_.isPrivateName(pn)) {
10041 if (tok != TokenKind::In || inHandling != InAllowed) {
10042 error(JSMSG_ILLEGAL_PRIVATE_NAME);
10043 return errorResult();
10044 }
10045 }
10046
10047 ParseNodeKind pnk;
10048 if (tok == TokenKind::In ? inHandling == InAllowed
10049 : TokenKindIsBinaryOp(tok)) {
10050 // We're definitely not in a destructuring context, so report any
10051 // pending expression error now.
10052 if (possibleError && !possibleError->checkForExpressionError()) {
10053 return errorResult();
10054 }
10055
10056 bool isErgonomicBrandCheck = false;
10057 switch (tok) {
10058 // Report an error for unary expressions on the LHS of **.
10059 case TokenKind::Pow:
10060 if (handler_.isUnparenthesizedUnaryExpression(pn)) {
10061 error(JSMSG_BAD_POW_LEFTSIDE);
10062 return errorResult();
10063 }
10064 break;
10065
10066 case TokenKind::Or:
10067 case TokenKind::And:
10068 // In the case that the `??` is on the left hand side of the
10069 // expression: Disallow Mixing of ?? and other logical operators (||
10070 // and &&) unless one expression is parenthesized
10071 if (unparenthesizedExpression == EnforcedParentheses::CoalesceExpr) {
10072 error(JSMSG_BAD_COALESCE_MIXING);
10073 return errorResult();
10074 }
10075 // If we have not detected a mixing error at this point, record that
10076 // we have an unparenthesized expression, in case we have one later.
10077 unparenthesizedExpression = EnforcedParentheses::AndOrExpr;
10078 break;
10079
10080 case TokenKind::Coalesce:
10081 if (unparenthesizedExpression == EnforcedParentheses::AndOrExpr) {
10082 error(JSMSG_BAD_COALESCE_MIXING);
10083 return errorResult();
10084 }
10085 // If we have not detected a mixing error at this point, record that
10086 // we have an unparenthesized expression, in case we have one later.
10087 unparenthesizedExpression = EnforcedParentheses::CoalesceExpr;
10088 break;
10089
10090 case TokenKind::In:
10091 // if the LHS is a private name, and the operator is In,
10092 // ensure we're construcing an ergonomic brand check of
10093 // '#x in y', rather than having a higher precedence operator
10094 // like + cause a different reduction, such as
10095 // 1 + #x in y.
10096 if (handler_.isPrivateName(pn)) {
10097 if (depth > 0 && Precedence(kindStack[depth - 1]) >=
10098 Precedence(ParseNodeKind::InExpr)) {
10099 error(JSMSG_INVALID_PRIVATE_NAME_PRECEDENCE);
10100 return errorResult();
10101 }
10102
10103 isErgonomicBrandCheck = true;
10104 }
10105 break;
10106
10107 default:
10108 // do nothing in other cases
10109 break;
10110 }
10111
10112 if (isErgonomicBrandCheck) {
10113 pnk = ParseNodeKind::PrivateInExpr;
10114 } else {
10115 pnk = BinaryOpTokenKindToParseNodeKind(tok);
10116 }
10117
10118 } else {
10119 tok = TokenKind::Eof;
10120 pnk = ParseNodeKind::Limit;
10121 }
10122
10123 // From this point on, destructuring defaults are definitely an error.
10124 possibleError = nullptr;
10125
10126 // If pnk has precedence less than or equal to another operator on the
10127 // stack, reduce. This combines nodes on the stack until we form the
10128 // actual lhs of pnk.
10129 //
10130 // The >= in this condition works because it is appendOrCreateList's
10131 // job to decide if the operator in question is left- or
10132 // right-associative, and build the corresponding tree.
10133 while (depth > 0 && Precedence(kindStack[depth - 1]) >= Precedence(pnk)) {
10134 depth--;
10135 ParseNodeKind combiningPnk = kindStack[depth];
10136 MOZ_TRY_VAR(pn, handler_.appendOrCreateList(combiningPnk,do { auto mozTryVarTempResult_ = (handler_.appendOrCreateList
(combiningPnk, nodeStack[depth], pn, pc_)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
10137 nodeStack[depth], pn, pc_))do { auto mozTryVarTempResult_ = (handler_.appendOrCreateList
(combiningPnk, nodeStack[depth], pn, pc_)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (pn) = mozTryVarTempResult_.unwrap(); } while
(0)
;
10138 }
10139
10140 if (pnk == ParseNodeKind::Limit) {
10141 break;
10142 }
10143
10144 nodeStack[depth] = pn;
10145 kindStack[depth] = pnk;
10146 depth++;
10147 MOZ_ASSERT(depth <= PRECEDENCE_CLASSES)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(depth <= PRECEDENCE_CLASSES)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(depth <= PRECEDENCE_CLASSES
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"depth <= PRECEDENCE_CLASSES", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10147); AnnotateMozCrashReason("MOZ_ASSERT" "(" "depth <= PRECEDENCE_CLASSES"
")"); do { *((volatile int*)__null) = 10147; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10148 }
10149
10150 anyChars.ungetToken();
10151
10152 // Had the next token been a Div, we would have consumed it. So there's no
10153 // ambiguity if we later (after ASI) re-get this token with SlashIsRegExp.
10154 anyChars.allowGettingNextTokenWithSlashIsRegExp();
10155
10156 MOZ_ASSERT(depth == 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(depth == 0)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(depth == 0))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("depth == 0", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10156); AnnotateMozCrashReason("MOZ_ASSERT" "(" "depth == 0"
")"); do { *((volatile int*)__null) = 10156; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10157 return pn;
10158}
10159
10160template <class ParseHandler, typename Unit>
10161MOZ_ALWAYS_INLINEinline typename ParseHandler::NodeResult
10162GeneralParser<ParseHandler, Unit>::condExpr(InHandling inHandling,
10163 YieldHandling yieldHandling,
10164 TripledotHandling tripledotHandling,
10165 PossibleError* possibleError,
10166 InvokedPrediction invoked) {
10167 Node condition;
10168 MOZ_TRY_VAR(condition, orExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (orExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (condition) = mozTryVarTempResult_.unwrap(
); } while (0)
10169 possibleError, invoked))do { auto mozTryVarTempResult_ = (orExpr(inHandling, yieldHandling
, tripledotHandling, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (condition) = mozTryVarTempResult_.unwrap(
); } while (0)
;
10170
10171 bool matched;
10172 if (!tokenStream.matchToken(&matched, TokenKind::Hook,
10173 TokenStream::SlashIsInvalid)) {
10174 return errorResult();
10175 }
10176 if (!matched) {
10177 return condition;
10178 }
10179
10180 Node thenExpr;
10181 MOZ_TRY_VAR(thenExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (thenExpr) = mozTryVarTempResult_.unwrap(); } while (0)
10182 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (thenExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
10183
10184 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_IN_COND)) {
10185 return errorResult();
10186 }
10187
10188 Node elseExpr;
10189 MOZ_TRY_VAR(elseExpr,do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (elseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
10190 assignExpr(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (elseExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
10191
10192 return handler_.newConditional(condition, thenExpr, elseExpr);
10193}
10194
10195template <class ParseHandler, typename Unit>
10196typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::assignExpr(
10197 InHandling inHandling, YieldHandling yieldHandling,
10198 TripledotHandling tripledotHandling,
10199 PossibleError* possibleError /* = nullptr */,
10200 InvokedPrediction invoked /* = PredictUninvoked */) {
10201 AutoCheckRecursionLimit recursion(this->fc_);
10202 if (!recursion.check(this->fc_)) {
10203 return errorResult();
10204 }
10205
10206 // It's very common at this point to have a "detectably simple" expression,
10207 // i.e. a name/number/string token followed by one of the following tokens
10208 // that obviously isn't part of an expression: , ; : ) ] }
10209 //
10210 // (In Parsemark this happens 81.4% of the time; in code with large
10211 // numeric arrays, such as some Kraken benchmarks, it happens more often.)
10212 //
10213 // In such cases, we can avoid the full expression parsing route through
10214 // assignExpr(), condExpr(), orExpr(), unaryExpr(), memberExpr(), and
10215 // primaryExpr().
10216
10217 TokenKind firstToken;
10218 if (!tokenStream.getToken(&firstToken, TokenStream::SlashIsRegExp)) {
10219 return errorResult();
10220 }
10221
10222 TokenPos exprPos = pos();
10223
10224 bool endsExpr;
10225
10226 // This only handles identifiers that *never* have special meaning anywhere
10227 // in the language. Contextual keywords, reserved words in strict mode,
10228 // and other hard cases are handled outside this fast path.
10229 if (firstToken == TokenKind::Name) {
10230 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10231 return errorResult();
10232 }
10233 if (endsExpr) {
10234 TaggedParserAtomIndex name = identifierReference(yieldHandling);
10235 if (!name) {
10236 return errorResult();
10237 }
10238
10239 return identifierReference(name);
10240 }
10241 }
10242
10243 if (firstToken == TokenKind::Number) {
10244 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10245 return errorResult();
10246 }
10247 if (endsExpr) {
10248 return newNumber(anyChars.currentToken());
10249 }
10250 }
10251
10252 if (firstToken == TokenKind::String) {
10253 if (!tokenStream.nextTokenEndsExpr(&endsExpr)) {
10254 return errorResult();
10255 }
10256 if (endsExpr) {
10257 return stringLiteral();
10258 }
10259 }
10260
10261 if (firstToken == TokenKind::Yield && yieldExpressionsSupported()) {
10262 return yieldExpression(inHandling);
10263 }
10264
10265 bool maybeAsyncArrow = false;
10266 if (firstToken == TokenKind::Async) {
10267 TokenKind nextSameLine = TokenKind::Eof;
10268 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
10269 return errorResult();
10270 }
10271
10272 if (TokenKindIsPossibleIdentifier(nextSameLine)) {
10273 maybeAsyncArrow = true;
10274 }
10275 }
10276
10277 anyChars.ungetToken();
10278
10279 // Save the tokenizer state in case we find an arrow function and have to
10280 // rewind.
10281 Position start(tokenStream);
10282 auto ghostToken = this->compilationState_.getPosition();
10283
10284 PossibleError possibleErrorInner(*this);
10285 Node lhs;
10286 TokenKind tokenAfterLHS;
10287 bool isArrow;
10288 if (maybeAsyncArrow) {
10289 tokenStream.consumeKnownToken(TokenKind::Async, TokenStream::SlashIsRegExp);
10290
10291 TokenKind tokenAfterAsync;
10292 if (!tokenStream.getToken(&tokenAfterAsync)) {
10293 return errorResult();
10294 }
10295 MOZ_ASSERT(TokenKindIsPossibleIdentifier(tokenAfterAsync))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifier(tokenAfterAsync))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifier(tokenAfterAsync)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("TokenKindIsPossibleIdentifier(tokenAfterAsync)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10295); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifier(tokenAfterAsync)"
")"); do { *((volatile int*)__null) = 10295; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10296
10297 // Check yield validity here.
10298 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
10299 if (!name) {
10300 return errorResult();
10301 }
10302
10303 if (!tokenStream.peekToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)) {
10304 return errorResult();
10305 }
10306
10307 isArrow = tokenAfterLHS == TokenKind::Arrow;
10308
10309 // |async [no LineTerminator] of| without being followed by => is only
10310 // possible in for-await-of loops, e.g. |for await (async of [])|. Pretend
10311 // the |async| token was parsed an identifier reference and then proceed
10312 // with the rest of this function.
10313 if (!isArrow) {
10314 anyChars.ungetToken(); // unget the binding identifier
10315
10316 // The next token is guaranteed to never be a Div (, because it's an
10317 // identifier), so it's okay to re-get the token with SlashIsRegExp.
10318 anyChars.allowGettingNextTokenWithSlashIsRegExp();
10319
10320 TaggedParserAtomIndex asyncName = identifierReference(yieldHandling);
10321 if (!asyncName) {
10322 return errorResult();
10323 }
10324
10325 MOZ_TRY_VAR(lhs, identifierReference(asyncName))do { auto mozTryVarTempResult_ = (identifierReference(asyncName
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10326 }
10327 } else {
10328 MOZ_TRY_VAR(lhs, condExpr(inHandling, yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (condExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner, invoked)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
10329 &possibleErrorInner, invoked))do { auto mozTryVarTempResult_ = (condExpr(inHandling, yieldHandling
, tripledotHandling, &possibleErrorInner, invoked)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10330
10331 // Use SlashIsRegExp here because the ConditionalExpression parsed above
10332 // could be the entirety of this AssignmentExpression, and then ASI
10333 // permits this token to be a regular expression.
10334 if (!tokenStream.peekToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)) {
10335 return errorResult();
10336 }
10337
10338 isArrow = tokenAfterLHS == TokenKind::Arrow;
10339 }
10340
10341 if (isArrow) {
10342 // Rewind to reparse as an arrow function.
10343 //
10344 // Note: We do not call CompilationState::rewind here because parsing
10345 // during delazification will see the same rewind and need the same sequence
10346 // of inner functions to skip over.
10347 // Instead, we mark inner functions as "ghost".
10348 //
10349 // See GHOST_FUNCTION in FunctionFlags.h for more details.
10350 tokenStream.rewind(start);
10351 this->compilationState_.markGhost(ghostToken);
10352
10353 TokenKind next;
10354 if (!tokenStream.getToken(&next, TokenStream::SlashIsRegExp)) {
10355 return errorResult();
10356 }
10357 TokenPos startPos = pos();
10358 uint32_t toStringStart = startPos.begin;
10359 anyChars.ungetToken();
10360
10361 FunctionAsyncKind asyncKind = FunctionAsyncKind::SyncFunction;
10362
10363 if (next == TokenKind::Async) {
10364 tokenStream.consumeKnownToken(next, TokenStream::SlashIsRegExp);
10365
10366 TokenKind nextSameLine = TokenKind::Eof;
10367 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
10368 return errorResult();
10369 }
10370
10371 // The AsyncArrowFunction production are
10372 // async [no LineTerminator here] AsyncArrowBindingIdentifier ...
10373 // async [no LineTerminator here] ArrowFormalParameters ...
10374 if (TokenKindIsPossibleIdentifier(nextSameLine) ||
10375 nextSameLine == TokenKind::LeftParen) {
10376 asyncKind = FunctionAsyncKind::AsyncFunction;
10377 } else {
10378 anyChars.ungetToken();
10379 }
10380 }
10381
10382 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Arrow;
10383 FunctionNodeType funNode;
10384 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, startPos))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, startPos)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10385
10386 return functionDefinition(funNode, toStringStart, inHandling, yieldHandling,
10387 TaggedParserAtomIndex::null(), syntaxKind,
10388 GeneratorKind::NotGenerator, asyncKind);
10389 }
10390
10391 MOZ_ALWAYS_TRUE(do { if ((__builtin_expect(!!(tokenStream.getToken(&tokenAfterLHS
, TokenStream::SlashIsRegExp)), 1))) { } else { do { do { } while
(false); MOZ_ReportCrash("" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10392); AnnotateMozCrashReason("MOZ_CRASH(" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")"); do { *((volatile int*)__null) = 10392; __attribute__((
nomerge)) ::abort(); } while (false); } while (false); } } while
(false)
10392 tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp))do { if ((__builtin_expect(!!(tokenStream.getToken(&tokenAfterLHS
, TokenStream::SlashIsRegExp)), 1))) { } else { do { do { } while
(false); MOZ_ReportCrash("" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10392); AnnotateMozCrashReason("MOZ_CRASH(" "tokenStream.getToken(&tokenAfterLHS, TokenStream::SlashIsRegExp)"
")"); do { *((volatile int*)__null) = 10392; __attribute__((
nomerge)) ::abort(); } while (false); } while (false); } } while
(false)
;
10393
10394 ParseNodeKind kind;
10395 switch (tokenAfterLHS) {
10396 case TokenKind::Assign:
10397 kind = ParseNodeKind::AssignExpr;
10398 break;
10399 case TokenKind::AddAssign:
10400 kind = ParseNodeKind::AddAssignExpr;
10401 break;
10402 case TokenKind::SubAssign:
10403 kind = ParseNodeKind::SubAssignExpr;
10404 break;
10405 case TokenKind::CoalesceAssign:
10406 kind = ParseNodeKind::CoalesceAssignExpr;
10407 break;
10408 case TokenKind::OrAssign:
10409 kind = ParseNodeKind::OrAssignExpr;
10410 break;
10411 case TokenKind::AndAssign:
10412 kind = ParseNodeKind::AndAssignExpr;
10413 break;
10414 case TokenKind::BitOrAssign:
10415 kind = ParseNodeKind::BitOrAssignExpr;
10416 break;
10417 case TokenKind::BitXorAssign:
10418 kind = ParseNodeKind::BitXorAssignExpr;
10419 break;
10420 case TokenKind::BitAndAssign:
10421 kind = ParseNodeKind::BitAndAssignExpr;
10422 break;
10423 case TokenKind::LshAssign:
10424 kind = ParseNodeKind::LshAssignExpr;
10425 break;
10426 case TokenKind::RshAssign:
10427 kind = ParseNodeKind::RshAssignExpr;
10428 break;
10429 case TokenKind::UrshAssign:
10430 kind = ParseNodeKind::UrshAssignExpr;
10431 break;
10432 case TokenKind::MulAssign:
10433 kind = ParseNodeKind::MulAssignExpr;
10434 break;
10435 case TokenKind::DivAssign:
10436 kind = ParseNodeKind::DivAssignExpr;
10437 break;
10438 case TokenKind::ModAssign:
10439 kind = ParseNodeKind::ModAssignExpr;
10440 break;
10441 case TokenKind::PowAssign:
10442 kind = ParseNodeKind::PowAssignExpr;
10443 break;
10444
10445 default:
10446 MOZ_ASSERT(!anyChars.isCurrentTokenAssignment())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!anyChars.isCurrentTokenAssignment())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!anyChars.isCurrentTokenAssignment
()))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("!anyChars.isCurrentTokenAssignment()", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10446); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!anyChars.isCurrentTokenAssignment()"
")"); do { *((volatile int*)__null) = 10446; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10447 if (!possibleError) {
10448 if (!possibleErrorInner.checkForExpressionError()) {
10449 return errorResult();
10450 }
10451 } else {
10452 possibleErrorInner.transferErrorsTo(possibleError);
10453 }
10454
10455 anyChars.ungetToken();
10456 return lhs;
10457 }
10458
10459 // Verify the left-hand side expression doesn't have a forbidden form.
10460 if (handler_.isUnparenthesizedDestructuringPattern(lhs)) {
10461 if (kind != ParseNodeKind::AssignExpr) {
10462 error(JSMSG_BAD_DESTRUCT_ASS);
10463 return errorResult();
10464 }
10465
10466 if (!possibleErrorInner.checkForDestructuringErrorOrWarning()) {
10467 return errorResult();
10468 }
10469 } else if (handler_.isName(lhs)) {
10470 if (const char* chars = nameIsArgumentsOrEval(lhs)) {
10471 // |chars| is "arguments" or "eval" here.
10472 if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_STRICT_ASSIGN, chars)) {
10473 return errorResult();
10474 }
10475 }
10476 } else if (handler_.isArgumentsLength(lhs)) {
10477 pc_->sc()->setIneligibleForArgumentsLength();
10478 } else if (handler_.isPropertyOrPrivateMemberAccess(lhs)) {
10479 // Permitted: no additional testing/fixup needed.
10480 } else if (handler_.isFunctionCall(lhs)) {
10481 // We don't have to worry about backward compatibility issues with the new
10482 // compound assignment operators, so we always throw here. Also that way we
10483 // don't have to worry if |f() &&= expr| should always throw an error or
10484 // only if |f()| returns true.
10485 if (kind == ParseNodeKind::CoalesceAssignExpr ||
10486 kind == ParseNodeKind::OrAssignExpr ||
10487 kind == ParseNodeKind::AndAssignExpr) {
10488 errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
10489 return errorResult();
10490 }
10491
10492 if (!strictModeErrorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS)) {
10493 return errorResult();
10494 }
10495
10496 if (possibleError) {
10497 possibleError->setPendingDestructuringErrorAt(exprPos,
10498 JSMSG_BAD_DESTRUCT_TARGET);
10499 }
10500 } else {
10501 errorAt(exprPos.begin, JSMSG_BAD_LEFTSIDE_OF_ASS);
10502 return errorResult();
10503 }
10504
10505 if (!possibleErrorInner.checkForExpressionError()) {
10506 return errorResult();
10507 }
10508
10509 Node rhs;
10510 MOZ_TRY_VAR(rhs, assignExpr(inHandling, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(inHandling, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
10511
10512 return handler_.newAssignment(kind, lhs, rhs);
10513}
10514
10515template <class ParseHandler>
10516const char* PerHandlerParser<ParseHandler>::nameIsArgumentsOrEval(Node node) {
10517 MOZ_ASSERT(handler_.isName(node),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(handler_.isName(node))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(handler_.isName(node)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("handler_.isName(node)"
" (" "must only call this function on known names" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10518); AnnotateMozCrashReason("MOZ_ASSERT" "(" "handler_.isName(node)"
") (" "must only call this function on known names" ")"); do
{ *((volatile int*)__null) = 10518; __attribute__((nomerge))
::abort(); } while (false); } } while (false)
10518 "must only call this function on known names")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(handler_.isName(node))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(handler_.isName(node)))), 0)
)) { do { } while (false); MOZ_ReportAssertionFailure("handler_.isName(node)"
" (" "must only call this function on known names" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10518); AnnotateMozCrashReason("MOZ_ASSERT" "(" "handler_.isName(node)"
") (" "must only call this function on known names" ")"); do
{ *((volatile int*)__null) = 10518; __attribute__((nomerge))
::abort(); } while (false); } } while (false)
;
10519
10520 if (handler_.isEvalName(node)) {
10521 return "eval";
10522 }
10523 if (handler_.isArgumentsName(node)) {
10524 return "arguments";
10525 }
10526 return nullptr;
10527}
10528
10529template <class ParseHandler, typename Unit>
10530bool GeneralParser<ParseHandler, Unit>::checkIncDecOperand(
10531 Node operand, uint32_t operandOffset) {
10532 if (handler_.isName(operand)) {
10533 if (const char* chars = nameIsArgumentsOrEval(operand)) {
10534 if (!strictModeErrorAt(operandOffset, JSMSG_BAD_STRICT_ASSIGN, chars)) {
10535 return false;
10536 }
10537 }
10538 } else if (handler_.isArgumentsLength(operand)) {
10539 pc_->sc()->setIneligibleForArgumentsLength();
10540 } else if (handler_.isPropertyOrPrivateMemberAccess(operand)) {
10541 // Permitted: no additional testing/fixup needed.
10542 } else if (handler_.isFunctionCall(operand)) {
10543 // Assignment to function calls is forbidden in ES6. We're still
10544 // somewhat concerned about sites using this in dead code, so forbid it
10545 // only in strict mode code.
10546 if (!strictModeErrorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND)) {
10547 return false;
10548 }
10549 } else {
10550 errorAt(operandOffset, JSMSG_BAD_INCOP_OPERAND);
10551 return false;
10552 }
10553 return true;
10554}
10555
10556template <class ParseHandler, typename Unit>
10557typename ParseHandler::UnaryNodeResult
10558GeneralParser<ParseHandler, Unit>::unaryOpExpr(YieldHandling yieldHandling,
10559 ParseNodeKind kind,
10560 uint32_t begin) {
10561 Node kid;
10562 MOZ_TRY_VAR(kid, unaryExpr(yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, TripledotProhibited
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (kid) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10563 return handler_.newUnary(kind, begin, kid);
10564}
10565
10566template <class ParseHandler, typename Unit>
10567typename ParseHandler::NodeResult
10568GeneralParser<ParseHandler, Unit>::optionalExpr(
10569 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10570 TokenKind tt, PossibleError* possibleError /* = nullptr */,
10571 InvokedPrediction invoked /* = PredictUninvoked */) {
10572 AutoCheckRecursionLimit recursion(this->fc_);
10573 if (!recursion.check(this->fc_)) {
10574 return errorResult();
10575 }
10576
10577 uint32_t begin = pos().begin;
10578
10579 Node lhs;
10580 MOZ_TRY_VAR(lhs,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, tripledotHandling
, tt, true, possibleError, invoked)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (lhs) = mozTryVarTempResult_.unwrap(); } while
(0)
10581 memberExpr(yieldHandling, tripledotHandling, tt,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, tripledotHandling
, tt, true, possibleError, invoked)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (lhs) = mozTryVarTempResult_.unwrap(); } while
(0)
10582 /* allowCallSyntax = */ true, possibleError, invoked))do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, tripledotHandling
, tt, true, possibleError, invoked)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (lhs) = mozTryVarTempResult_.unwrap(); } while
(0)
;
10583
10584 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsDiv)) {
10585 return errorResult();
10586 }
10587
10588 if (tt != TokenKind::OptionalChain) {
10589 return lhs;
10590 }
10591
10592 while (true) {
10593 if (!tokenStream.getToken(&tt)) {
10594 return errorResult();
10595 }
10596
10597 if (tt == TokenKind::Eof) {
10598 anyChars.ungetToken();
10599 break;
10600 }
10601
10602 Node nextMember;
10603 if (tt == TokenKind::OptionalChain) {
10604 if (!tokenStream.getToken(&tt)) {
10605 return errorResult();
10606 }
10607 if (TokenKindIsPossibleIdentifierName(tt)) {
10608 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
10609 memberPropertyAccess(lhs, OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10610 } else if (tt == TokenKind::PrivateName) {
10611 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
10612 memberPrivateAccess(lhs, OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs, OptionalKind
::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10613 } else if (tt == TokenKind::LeftBracket) {
10614 MOZ_TRY_VAR(nextMember, memberElemAccess(lhs, yieldHandling,do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
, OptionalKind::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
10615 OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
, OptionalKind::Optional)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
;
10616 } else if (tt == TokenKind::LeftParen) {
10617 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError, OptionalKind::Optional)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nextMember) = mozTryVarTempResult_.unwrap
(); } while (0)
10618 memberCall(tt, lhs, yieldHandling, possibleError,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError, OptionalKind::Optional)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nextMember) = mozTryVarTempResult_.unwrap
(); } while (0)
10619 OptionalKind::Optional))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError, OptionalKind::Optional)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (nextMember) = mozTryVarTempResult_.unwrap
(); } while (0)
;
10620 } else {
10621 error(JSMSG_NAME_AFTER_DOT);
10622 return errorResult();
10623 }
10624 } else if (tt == TokenKind::Dot) {
10625 if (!tokenStream.getToken(&tt)) {
10626 return errorResult();
10627 }
10628 if (TokenKindIsPossibleIdentifierName(tt)) {
10629 MOZ_TRY_VAR(nextMember, memberPropertyAccess(lhs))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nextMember)
= mozTryVarTempResult_.unwrap(); } while (0)
;
10630 } else if (tt == TokenKind::PrivateName) {
10631 MOZ_TRY_VAR(nextMember, memberPrivateAccess(lhs))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (nextMember) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10632 } else {
10633 error(JSMSG_NAME_AFTER_DOT);
10634 return errorResult();
10635 }
10636 } else if (tt == TokenKind::LeftBracket) {
10637 MOZ_TRY_VAR(nextMember, memberElemAccess(lhs, yieldHandling))do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10638 } else if (tt == TokenKind::LeftParen) {
10639 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
10640 memberCall(tt, lhs, yieldHandling, possibleError))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
;
10641 } else if (tt == TokenKind::TemplateHead ||
10642 tt == TokenKind::NoSubsTemplate) {
10643 error(JSMSG_BAD_OPTIONAL_TEMPLATE);
10644 return errorResult();
10645 } else {
10646 anyChars.ungetToken();
10647 break;
10648 }
10649
10650 MOZ_ASSERT(nextMember)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(nextMember)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(nextMember))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("nextMember", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10650); AnnotateMozCrashReason("MOZ_ASSERT" "(" "nextMember"
")"); do { *((volatile int*)__null) = 10650; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10651 lhs = nextMember;
10652 }
10653
10654 return handler_.newOptionalChain(begin, lhs);
10655}
10656
10657template <class ParseHandler, typename Unit>
10658typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::unaryExpr(
10659 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10660 PossibleError* possibleError /* = nullptr */,
10661 InvokedPrediction invoked /* = PredictUninvoked */,
10662 PrivateNameHandling privateNameHandling /* = PrivateNameProhibited */) {
10663 AutoCheckRecursionLimit recursion(this->fc_);
10664 if (!recursion.check(this->fc_)) {
10665 return errorResult();
10666 }
10667
10668 TokenKind tt;
10669 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
10670 return errorResult();
10671 }
10672 uint32_t begin = pos().begin;
10673 switch (tt) {
10674 case TokenKind::Void:
10675 return unaryOpExpr(yieldHandling, ParseNodeKind::VoidExpr, begin);
10676 case TokenKind::Not:
10677 return unaryOpExpr(yieldHandling, ParseNodeKind::NotExpr, begin);
10678 case TokenKind::BitNot:
10679 return unaryOpExpr(yieldHandling, ParseNodeKind::BitNotExpr, begin);
10680 case TokenKind::Add:
10681 return unaryOpExpr(yieldHandling, ParseNodeKind::PosExpr, begin);
10682 case TokenKind::Sub:
10683 return unaryOpExpr(yieldHandling, ParseNodeKind::NegExpr, begin);
10684
10685 case TokenKind::TypeOf: {
10686 // The |typeof| operator is specially parsed to distinguish its
10687 // application to a name, from its application to a non-name
10688 // expression:
10689 //
10690 // // Looks up the name, doesn't find it and so evaluates to
10691 // // "undefined".
10692 // assertEq(typeof nonExistentName, "undefined");
10693 //
10694 // // Evaluates expression, triggering a runtime ReferenceError for
10695 // // the undefined name.
10696 // typeof (1, nonExistentName);
10697 Node kid;
10698 MOZ_TRY_VAR(kid, unaryExpr(yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, TripledotProhibited
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (kid) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10699
10700 return handler_.newTypeof(begin, kid);
10701 }
10702
10703 case TokenKind::Inc:
10704 case TokenKind::Dec: {
10705 TokenKind tt2;
10706 if (!tokenStream.getToken(&tt2, TokenStream::SlashIsRegExp)) {
10707 return errorResult();
10708 }
10709
10710 uint32_t operandOffset = pos().begin;
10711 Node operand;
10712 MOZ_TRY_VAR(operand,do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt2)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (operand) = mozTryVarTempResult_.unwrap(); } while (0)
10713 optionalExpr(yieldHandling, TripledotProhibited, tt2))do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
TripledotProhibited, tt2)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (operand) = mozTryVarTempResult_.unwrap(); } while (0)
;
10714 if (!checkIncDecOperand(operand, operandOffset)) {
10715 return errorResult();
10716 }
10717 ParseNodeKind pnk = (tt == TokenKind::Inc)
10718 ? ParseNodeKind::PreIncrementExpr
10719 : ParseNodeKind::PreDecrementExpr;
10720 return handler_.newUpdate(pnk, begin, operand);
10721 }
10722 case TokenKind::PrivateName: {
10723 if (privateNameHandling == PrivateNameHandling::PrivateNameAllowed) {
10724 TaggedParserAtomIndex field = anyChars.currentName();
10725 return privateNameReference(field);
10726 }
10727 error(JSMSG_INVALID_PRIVATE_NAME_IN_UNARY_EXPR);
10728 return errorResult();
10729 }
10730
10731 case TokenKind::Delete: {
10732 uint32_t exprOffset;
10733 if (!tokenStream.peekOffset(&exprOffset, TokenStream::SlashIsRegExp)) {
10734 return errorResult();
10735 }
10736
10737 Node expr;
10738 MOZ_TRY_VAR(expr, unaryExpr(yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, TripledotProhibited
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (expr) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10739
10740 // Per spec, deleting most unary expressions is valid -- it simply
10741 // returns true -- except for two cases:
10742 // 1. `var x; ...; delete x` is a syntax error in strict mode.
10743 // 2. Private fields cannot be deleted.
10744 if (handler_.isName(expr)) {
10745 if (!strictModeErrorAt(exprOffset, JSMSG_DEPRECATED_DELETE_OPERAND)) {
10746 return errorResult();
10747 }
10748
10749 pc_->sc()->setBindingsAccessedDynamically();
10750 }
10751
10752 if (handler_.isPrivateMemberAccess(expr)) {
10753 errorAt(exprOffset, JSMSG_PRIVATE_DELETE);
10754 return errorResult();
10755 }
10756
10757 return handler_.newDelete(begin, expr);
10758 }
10759 case TokenKind::Await: {
10760 // If we encounter an await in a module, mark it as async.
10761 if (!pc_->isAsync() && pc_->sc()->isModule()) {
10762 if (!options().topLevelAwait) {
10763 error(JSMSG_TOP_LEVEL_AWAIT_NOT_SUPPORTED);
10764 return errorResult();
10765 }
10766 pc_->sc()->asModuleContext()->setIsAsync();
10767 MOZ_ASSERT(pc_->isAsync())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isAsync())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isAsync()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isAsync()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10767); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isAsync()"
")"); do { *((volatile int*)__null) = 10767; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10768 }
10769
10770 if (pc_->isAsync()) {
10771 if (inParametersOfAsyncFunction()) {
10772 error(JSMSG_AWAIT_IN_PARAMETER);
10773 return errorResult();
10774 }
10775 Node kid;
10776 MOZ_TRY_VAR(kid, unaryExpr(yieldHandling, tripledotHandling,do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
10777 possibleError, invoked))do { auto mozTryVarTempResult_ = (unaryExpr(yieldHandling, tripledotHandling
, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (kid) = mozTryVarTempResult_.unwrap(); } while (0)
;
10778 pc_->lastAwaitOffset = begin;
10779 return handler_.newAwaitExpression(begin, kid);
10780 }
10781 }
10782
10783 [[fallthrough]];
10784
10785 default: {
10786 Node expr;
10787 MOZ_TRY_VAR(expr, optionalExpr(yieldHandling, tripledotHandling, tt,do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
tripledotHandling, tt, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
10788 possibleError, invoked))do { auto mozTryVarTempResult_ = (optionalExpr(yieldHandling,
tripledotHandling, tt, possibleError, invoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
10789
10790 /* Don't look across a newline boundary for a postfix incop. */
10791 if (!tokenStream.peekTokenSameLine(&tt)) {
10792 return errorResult();
10793 }
10794
10795 if (tt != TokenKind::Inc && tt != TokenKind::Dec) {
10796 return expr;
10797 }
10798
10799 tokenStream.consumeKnownToken(tt);
10800 if (!checkIncDecOperand(expr, begin)) {
10801 return errorResult();
10802 }
10803
10804 ParseNodeKind pnk = (tt == TokenKind::Inc)
10805 ? ParseNodeKind::PostIncrementExpr
10806 : ParseNodeKind::PostDecrementExpr;
10807 return handler_.newUpdate(pnk, begin, expr);
10808 }
10809 }
10810}
10811
10812template <class ParseHandler, typename Unit>
10813typename ParseHandler::NodeResult
10814GeneralParser<ParseHandler, Unit>::assignExprWithoutYieldOrAwait(
10815 YieldHandling yieldHandling) {
10816 uint32_t startYieldOffset = pc_->lastYieldOffset;
10817 uint32_t startAwaitOffset = pc_->lastAwaitOffset;
10818
10819 Node res;
10820 MOZ_TRY_VAR(res, assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (res) = mozTryVarTempResult_.unwrap(); } while (0)
;
10821
10822 if (pc_->lastYieldOffset != startYieldOffset) {
10823 errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
10824 return errorResult();
10825 }
10826 if (pc_->lastAwaitOffset != startAwaitOffset) {
10827 errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
10828 return errorResult();
10829 }
10830 return res;
10831}
10832
10833template <class ParseHandler, typename Unit>
10834typename ParseHandler::ListNodeResult
10835GeneralParser<ParseHandler, Unit>::argumentList(
10836 YieldHandling yieldHandling, bool* isSpread,
10837 PossibleError* possibleError /* = nullptr */) {
10838 ListNodeType argsList;
10839 MOZ_TRY_VAR(argsList, handler_.newArguments(pos()))do { auto mozTryVarTempResult_ = (handler_.newArguments(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argsList
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10840
10841 bool matched;
10842 if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
10843 TokenStream::SlashIsRegExp)) {
10844 return errorResult();
10845 }
10846 if (matched) {
10847 handler_.setEndPosition(argsList, pos().end);
10848 return argsList;
10849 }
10850
10851 while (true) {
10852 bool spread = false;
10853 uint32_t begin = 0;
10854 if (!tokenStream.matchToken(&matched, TokenKind::TripleDot,
10855 TokenStream::SlashIsRegExp)) {
10856 return errorResult();
10857 }
10858 if (matched) {
10859 spread = true;
10860 begin = pos().begin;
10861 *isSpread = true;
10862 }
10863
10864 Node argNode;
10865 MOZ_TRY_VAR(argNode, assignExpr(InAllowed, yieldHandling,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, possibleError)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (argNode) = mozTryVarTempResult_.unwrap();
} while (0)
10866 TripledotProhibited, possibleError))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, possibleError)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (argNode) = mozTryVarTempResult_.unwrap();
} while (0)
;
10867 if (spread) {
10868 MOZ_TRY_VAR(argNode, handler_.newSpread(begin, argNode))do { auto mozTryVarTempResult_ = (handler_.newSpread(begin, argNode
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (argNode)
= mozTryVarTempResult_.unwrap(); } while (0)
;
10869 }
10870
10871 handler_.addList(argsList, argNode);
10872
10873 bool matched;
10874 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
10875 TokenStream::SlashIsRegExp)) {
10876 return errorResult();
10877 }
10878 if (!matched) {
10879 break;
10880 }
10881
10882 TokenKind tt;
10883 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
10884 return errorResult();
10885 }
10886 if (tt == TokenKind::RightParen) {
10887 break;
10888 }
10889 }
10890
10891 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_ARGS)) {
10892 return errorResult();
10893 }
10894
10895 handler_.setEndPosition(argsList, pos().end);
10896 return argsList;
10897}
10898
10899bool ParserBase::checkAndMarkSuperScope() {
10900 if (!pc_->sc()->allowSuperProperty()) {
10901 return false;
10902 }
10903
10904 pc_->setSuperScopeNeedsHomeObject();
10905 return true;
10906}
10907
10908template <class ParseHandler, typename Unit>
10909bool GeneralParser<ParseHandler, Unit>::computeErrorMetadata(
10910 ErrorMetadata* err, const ErrorReportMixin::ErrorOffset& offset) const {
10911 if (offset.is<ErrorReportMixin::Current>()) {
10912 return tokenStream.computeErrorMetadata(err, AsVariant(pos().begin));
10913 }
10914 return tokenStream.computeErrorMetadata(err, offset);
10915}
10916
10917template <class ParseHandler, typename Unit>
10918typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::memberExpr(
10919 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
10920 TokenKind tt, bool allowCallSyntax, PossibleError* possibleError,
10921 InvokedPrediction invoked) {
10922 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10922); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 10922; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
10923
10924 Node lhs;
10925
10926 AutoCheckRecursionLimit recursion(this->fc_);
10927 if (!recursion.check(this->fc_)) {
10928 return errorResult();
10929 }
10930
10931 /* Check for new expression first. */
10932 if (tt == TokenKind::New) {
10933 uint32_t newBegin = pos().begin;
10934 // Make sure this wasn't a |new.target| in disguise.
10935 NewTargetNodeType newTarget;
10936 if (!tryNewTarget(&newTarget)) {
10937 return errorResult();
10938 }
10939 if (newTarget) {
10940 lhs = newTarget;
10941 } else {
10942 // Gotten by tryNewTarget
10943 tt = anyChars.currentToken().type;
10944 Node ctorExpr;
10945 MOZ_TRY_VAR(ctorExpr,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
10946 memberExpr(yieldHandling, TripledotProhibited, tt,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
10947 /* allowCallSyntax = */ false,do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
10948 /* possibleError = */ nullptr, PredictInvoked))do { auto mozTryVarTempResult_ = (memberExpr(yieldHandling, TripledotProhibited
, tt, false, nullptr, PredictInvoked)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (ctorExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
;
10949
10950 // If we have encountered an optional chain, in the form of `new
10951 // ClassName?.()` then we need to throw, as this is disallowed by the
10952 // spec.
10953 bool optionalToken;
10954 if (!tokenStream.matchToken(&optionalToken, TokenKind::OptionalChain)) {
10955 return errorResult();
10956 }
10957 if (optionalToken) {
10958 errorAt(newBegin, JSMSG_BAD_NEW_OPTIONAL);
10959 return errorResult();
10960 }
10961
10962 bool matched;
10963 if (!tokenStream.matchToken(&matched, TokenKind::LeftParen)) {
10964 return errorResult();
10965 }
10966
10967 bool isSpread = false;
10968 ListNodeType args;
10969 if (matched) {
10970 MOZ_TRY_VAR(args, argumentList(yieldHandling, &isSpread))do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (args) = mozTryVarTempResult_.unwrap(); } while (0)
;
10971 } else {
10972 MOZ_TRY_VAR(args, handler_.newArguments(pos()))do { auto mozTryVarTempResult_ = (handler_.newArguments(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (args) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10973 }
10974
10975 if (!args) {
10976 return errorResult();
10977 }
10978
10979 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (handler_.newNewExpression(newBegin
, ctorExpr, args, isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
10980 lhs, handler_.newNewExpression(newBegin, ctorExpr, args, isSpread))do { auto mozTryVarTempResult_ = (handler_.newNewExpression(newBegin
, ctorExpr, args, isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
10981 }
10982 } else if (tt == TokenKind::Super) {
10983 NameNodeType thisName;
10984 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
10985 MOZ_TRY_VAR(lhs, handler_.newSuperBase(thisName, pos()))do { auto mozTryVarTempResult_ = (handler_.newSuperBase(thisName
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (lhs
) = mozTryVarTempResult_.unwrap(); } while (0)
;
10986 } else if (tt == TokenKind::Import) {
10987 MOZ_TRY_VAR(lhs, importExpr(yieldHandling, allowCallSyntax))do { auto mozTryVarTempResult_ = (importExpr(yieldHandling, allowCallSyntax
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
10988 } else {
10989 MOZ_TRY_VAR(lhs, primaryExpr(yieldHandling, tripledotHandling, tt,do { auto mozTryVarTempResult_ = (primaryExpr(yieldHandling, tripledotHandling
, tt, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
10990 possibleError, invoked))do { auto mozTryVarTempResult_ = (primaryExpr(yieldHandling, tripledotHandling
, tt, possibleError, invoked)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (lhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
10991 }
10992
10993 MOZ_ASSERT_IF(handler_.isSuperBase(lhs),do { if (handler_.isSuperBase(lhs)) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Super))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Super)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Super)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10994); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Super)"
")"); do { *((volatile int*)__null) = 10994; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
10994 anyChars.isCurrentTokenType(TokenKind::Super))do { if (handler_.isSuperBase(lhs)) { do { static_assert( mozilla
::detail::AssertionConditionType<decltype(anyChars.isCurrentTokenType
(TokenKind::Super))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
TokenKind::Super)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(TokenKind::Super)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 10994); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Super)"
")"); do { *((volatile int*)__null) = 10994; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false); } } while
(false)
;
10995
10996 while (true) {
10997 if (!tokenStream.getToken(&tt)) {
10998 return errorResult();
10999 }
11000 if (tt == TokenKind::Eof) {
11001 anyChars.ungetToken();
11002 break;
11003 }
11004
11005 Node nextMember;
11006 if (tt == TokenKind::Dot) {
11007 if (!tokenStream.getToken(&tt)) {
11008 return errorResult();
11009 }
11010
11011 if (TokenKindIsPossibleIdentifierName(tt)) {
11012 MOZ_TRY_VAR(nextMember, memberPropertyAccess(lhs))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nextMember)
= mozTryVarTempResult_.unwrap(); } while (0)
;
11013 } else if (tt == TokenKind::PrivateName) {
11014 MOZ_TRY_VAR(nextMember, memberPrivateAccess(lhs))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (nextMember) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11015 } else {
11016 error(JSMSG_NAME_AFTER_DOT);
11017 return errorResult();
11018 }
11019 } else if (tt == TokenKind::LeftBracket) {
11020 MOZ_TRY_VAR(nextMember, memberElemAccess(lhs, yieldHandling))do { auto mozTryVarTempResult_ = (memberElemAccess(lhs, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11021 } else if ((allowCallSyntax && tt == TokenKind::LeftParen) ||
11022 tt == TokenKind::TemplateHead ||
11023 tt == TokenKind::NoSubsTemplate) {
11024 if (handler_.isSuperBase(lhs)) {
11025 if (!pc_->sc()->allowSuperCall()) {
11026 error(JSMSG_BAD_SUPERCALL);
11027 return errorResult();
11028 }
11029
11030 if (tt != TokenKind::LeftParen) {
11031 error(JSMSG_BAD_SUPER);
11032 return errorResult();
11033 }
11034
11035 MOZ_TRY_VAR(nextMember, memberSuperCall(lhs, yieldHandling))do { auto mozTryVarTempResult_ = (memberSuperCall(lhs, yieldHandling
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11036
11037 if (!noteUsedName(
11038 TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
11039 return errorResult();
11040 }
11041#ifdef ENABLE_DECORATORS
11042 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
11043 dot_instanceExtraInitializers_())) {
11044 return null();
11045 }
11046#endif
11047 } else {
11048 MOZ_TRY_VAR(nextMember,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
11049 memberCall(tt, lhs, yieldHandling, possibleError))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, possibleError)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (nextMember) = mozTryVarTempResult_.unwrap(); } while (0)
;
11050 }
11051 } else {
11052 anyChars.ungetToken();
11053 if (handler_.isSuperBase(lhs)) {
11054 break;
11055 }
11056 return lhs;
11057 }
11058
11059 lhs = nextMember;
11060 }
11061
11062 if (handler_.isSuperBase(lhs)) {
11063 error(JSMSG_BAD_SUPER);
11064 return errorResult();
11065 }
11066
11067 return lhs;
11068}
11069
11070template <class ParseHandler, typename Unit>
11071typename ParseHandler::NodeResult
11072GeneralParser<ParseHandler, Unit>::decoratorExpr(YieldHandling yieldHandling,
11073 TokenKind tt) {
11074 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11074); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 11074; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11075
11076 AutoCheckRecursionLimit recursion(this->fc_);
11077 if (!recursion.check(this->fc_)) {
11078 return errorResult();
11079 }
11080
11081 if (tt == TokenKind::LeftParen) {
11082 // DecoratorParenthesizedExpression
11083 Node expr;
11084 MOZ_TRY_VAR(expr, exprInParens(InAllowed, yieldHandling, TripledotAllowed,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (expr) = mozTryVarTempResult_.unwrap(); } while (0)
11085 /* possibleError*/ nullptr))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (expr) = mozTryVarTempResult_.unwrap(); } while (0)
;
11086 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_DECORATOR)) {
11087 return errorResult();
11088 }
11089
11090 return handler_.parenthesize(expr);
11091 }
11092
11093 if (!TokenKindIsPossibleIdentifier(tt)) {
11094 error(JSMSG_DECORATOR_NAME_EXPECTED);
11095 return errorResult();
11096 }
11097
11098 TaggedParserAtomIndex name = identifierReference(yieldHandling);
11099 if (!name) {
11100 return errorResult();
11101 }
11102
11103 Node lhs;
11104 MOZ_TRY_VAR(lhs, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11105
11106 while (true) {
11107 if (!tokenStream.getToken(&tt)) {
11108 return errorResult();
11109 }
11110 if (tt == TokenKind::Eof) {
11111 anyChars.ungetToken();
11112 break;
11113 }
11114
11115 Node nextMember;
11116 if (tt == TokenKind::Dot) {
11117 if (!tokenStream.getToken(&tt)) {
11118 return errorResult();
11119 }
11120
11121 if (TokenKindIsPossibleIdentifierName(tt)) {
11122 MOZ_TRY_VAR(nextMember, memberPropertyAccess(lhs))do { auto mozTryVarTempResult_ = (memberPropertyAccess(lhs));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nextMember)
= mozTryVarTempResult_.unwrap(); } while (0)
;
11123 } else if (tt == TokenKind::PrivateName) {
11124 MOZ_TRY_VAR(nextMember, memberPrivateAccess(lhs))do { auto mozTryVarTempResult_ = (memberPrivateAccess(lhs)); if
((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (nextMember) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11125 } else {
11126 error(JSMSG_NAME_AFTER_DOT);
11127 return errorResult();
11128 }
11129 } else if (tt == TokenKind::LeftParen) {
11130 MOZ_TRY_VAR(nextMember, memberCall(tt, lhs, yieldHandling,do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
11131 /* possibleError */ nullptr))do { auto mozTryVarTempResult_ = (memberCall(tt, lhs, yieldHandling
, nullptr)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (nextMember
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11132 lhs = nextMember;
11133 // This is a `DecoratorCallExpression` and it's defined at the top level
11134 // of `Decorator`, no other `DecoratorMemberExpression` is allowed to
11135 // follow after the arguments.
11136 break;
11137 } else {
11138 anyChars.ungetToken();
11139 break;
11140 }
11141
11142 lhs = nextMember;
11143 }
11144
11145 return lhs;
11146}
11147
11148template <class ParseHandler>
11149inline typename ParseHandler::NameNodeResult
11150PerHandlerParser<ParseHandler>::newName(TaggedParserAtomIndex name) {
11151 return newName(name, pos());
11152}
11153
11154template <class ParseHandler>
11155inline typename ParseHandler::NameNodeResult
11156PerHandlerParser<ParseHandler>::newName(TaggedParserAtomIndex name,
11157 TokenPos pos) {
11158 if (name == TaggedParserAtomIndex::WellKnown::arguments()) {
11159 this->pc_->numberOfArgumentsNames++;
11160 }
11161 return handler_.newName(name, pos);
11162}
11163
11164template <class ParseHandler>
11165inline typename ParseHandler::NameNodeResult
11166PerHandlerParser<ParseHandler>::newPrivateName(TaggedParserAtomIndex name) {
11167 return handler_.newPrivateName(name, pos());
11168}
11169
11170template <class ParseHandler, typename Unit>
11171typename ParseHandler::NodeResult
11172GeneralParser<ParseHandler, Unit>::memberPropertyAccess(
11173 Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11174 MOZ_ASSERT(TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11175); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11175; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
11175 anyChars.currentToken().type == TokenKind::PrivateName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(TokenKindIsPossibleIdentifierName(anyChars.currentToken
().type) || anyChars.currentToken().type == TokenKind::PrivateName
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11175); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(anyChars.currentToken().type) || anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11175; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11176 TaggedParserAtomIndex field = anyChars.currentName();
11177 if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
11178 error(JSMSG_BAD_SUPERPROP, "property");
11179 return errorResult();
11180 }
11181
11182 NameNodeType name;
11183 MOZ_TRY_VAR(name, handler_.newPropertyName(field, pos()))do { auto mozTryVarTempResult_ = (handler_.newPropertyName(field
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (name
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11184
11185 if (optionalKind == OptionalKind::Optional) {
11186 MOZ_ASSERT(!handler_.isSuperBase(lhs))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!handler_.isSuperBase(lhs))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!handler_.isSuperBase(lhs)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!handler_.isSuperBase(lhs)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11186); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11186; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11187 return handler_.newOptionalPropertyAccess(lhs, name);
11188 }
11189
11190 if (handler_.isArgumentsName(lhs) && handler_.isLengthName(name)) {
11191 MOZ_ASSERT(pc_->numberOfArgumentsNames > 0)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->numberOfArgumentsNames > 0)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(pc_->numberOfArgumentsNames > 0))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("pc_->numberOfArgumentsNames > 0"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11191); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->numberOfArgumentsNames > 0"
")"); do { *((volatile int*)__null) = 11191; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11192 pc_->numberOfArgumentsNames--;
11193 // Currently when resuming Generators don't get their argument length set
11194 // in the interpreter frame (see InterpreterStack::resumeGeneratorCallFrame,
11195 // and its call to initCallFrame).
11196 if (pc_->isGeneratorOrAsync()) {
11197 pc_->sc()->setIneligibleForArgumentsLength();
11198 }
11199 return handler_.newArgumentsLength(lhs, name);
11200 }
11201
11202 return handler_.newPropertyAccess(lhs, name);
11203}
11204
11205template <class ParseHandler, typename Unit>
11206typename ParseHandler::NodeResult
11207GeneralParser<ParseHandler, Unit>::memberPrivateAccess(
11208 Node lhs, OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11209 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::PrivateName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::PrivateName
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::PrivateName
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"anyChars.currentToken().type == TokenKind::PrivateName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11209); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::PrivateName"
")"); do { *((volatile int*)__null) = 11209; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11210
11211 TaggedParserAtomIndex field = anyChars.currentName();
11212 // Cannot access private fields on super.
11213 if (handler_.isSuperBase(lhs)) {
11214 error(JSMSG_BAD_SUPERPRIVATE);
11215 return errorResult();
11216 }
11217
11218 NameNodeType privateName;
11219 MOZ_TRY_VAR(privateName, privateNameReference(field))do { auto mozTryVarTempResult_ = (privateNameReference(field)
); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)
)) { return mozTryVarTempResult_.propagateErr(); } (privateName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11220
11221 if (optionalKind == OptionalKind::Optional) {
11222 MOZ_ASSERT(!handler_.isSuperBase(lhs))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!handler_.isSuperBase(lhs))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!handler_.isSuperBase(lhs)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!handler_.isSuperBase(lhs)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11222); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11222; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11223 return handler_.newOptionalPrivateMemberAccess(lhs, privateName, pos().end);
11224 }
11225 return handler_.newPrivateMemberAccess(lhs, privateName, pos().end);
11226}
11227
11228template <class ParseHandler, typename Unit>
11229typename ParseHandler::NodeResult
11230GeneralParser<ParseHandler, Unit>::memberElemAccess(
11231 Node lhs, YieldHandling yieldHandling,
11232 OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11233 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::LeftBracket)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::LeftBracket
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::LeftBracket
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"anyChars.currentToken().type == TokenKind::LeftBracket", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11233); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::LeftBracket"
")"); do { *((volatile int*)__null) = 11233; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11234 Node propExpr;
11235 MOZ_TRY_VAR(propExpr, expr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
11236
11237 if (!mustMatchToken(TokenKind::RightBracket, JSMSG_BRACKET_IN_INDEX)) {
11238 return errorResult();
11239 }
11240
11241 if (handler_.isSuperBase(lhs) && !checkAndMarkSuperScope()) {
11242 error(JSMSG_BAD_SUPERPROP, "member");
11243 return errorResult();
11244 }
11245 if (optionalKind == OptionalKind::Optional) {
11246 MOZ_ASSERT(!handler_.isSuperBase(lhs))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!handler_.isSuperBase(lhs))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!handler_.isSuperBase(lhs)))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!handler_.isSuperBase(lhs)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11246); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!handler_.isSuperBase(lhs)"
")"); do { *((volatile int*)__null) = 11246; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11247 return handler_.newOptionalPropertyByValue(lhs, propExpr, pos().end);
11248 }
11249 return handler_.newPropertyByValue(lhs, propExpr, pos().end);
11250}
11251
11252template <class ParseHandler, typename Unit>
11253typename ParseHandler::NodeResult
11254GeneralParser<ParseHandler, Unit>::memberSuperCall(
11255 Node lhs, YieldHandling yieldHandling) {
11256 MOZ_ASSERT(anyChars.currentToken().type == TokenKind::LeftParen)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.currentToken().type == TokenKind::LeftParen
)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.currentToken().type == TokenKind::LeftParen
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"anyChars.currentToken().type == TokenKind::LeftParen", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11256); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::LeftParen"
")"); do { *((volatile int*)__null) = 11256; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11257 // Despite the fact that it's impossible to have |super()| in a
11258 // generator, we still inherit the yieldHandling of the
11259 // memberExpression, per spec. Curious.
11260 bool isSpread = false;
11261 ListNodeType args;
11262 MOZ_TRY_VAR(args, argumentList(yieldHandling, &isSpread))do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (args) = mozTryVarTempResult_.unwrap(); } while (0)
;
11263
11264 CallNodeType superCall;
11265 MOZ_TRY_VAR(superCall, handler_.newSuperCall(lhs, args, isSpread))do { auto mozTryVarTempResult_ = (handler_.newSuperCall(lhs, args
, isSpread)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (superCall
) = mozTryVarTempResult_.unwrap(); } while (0)
;
11266
11267 // |super()| implicitly reads |new.target|.
11268 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_newTarget_())) {
11269 return errorResult();
11270 }
11271
11272 NameNodeType thisName;
11273 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
11274
11275 return handler_.newSetThis(thisName, superCall);
11276}
11277
11278template <class ParseHandler, typename Unit>
11279typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::memberCall(
11280 TokenKind tt, Node lhs, YieldHandling yieldHandling,
11281 PossibleError* possibleError /* = nullptr */,
11282 OptionalKind optionalKind /* = OptionalKind::NonOptional */) {
11283 if (options().selfHostingMode &&
11284 (handler_.isPropertyOrPrivateMemberAccess(lhs) ||
11285 handler_.isOptionalPropertyOrPrivateMemberAccess(lhs))) {
11286 error(JSMSG_SELFHOSTED_METHOD_CALL);
11287 return errorResult();
11288 }
11289
11290 MOZ_ASSERT(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead
|| tt == TokenKind::NoSubsTemplate)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::LeftParen ||
tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
" (" "Unexpected token kind for member call" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11292); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11292; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
11291 tt == TokenKind::NoSubsTemplate,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead
|| tt == TokenKind::NoSubsTemplate)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::LeftParen ||
tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
" (" "Unexpected token kind for member call" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11292); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11292; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
11292 "Unexpected token kind for member call")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead
|| tt == TokenKind::NoSubsTemplate)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(tt == TokenKind::LeftParen ||
tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
" (" "Unexpected token kind for member call" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11292); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftParen || tt == TokenKind::TemplateHead || tt == TokenKind::NoSubsTemplate"
") (" "Unexpected token kind for member call" ")"); do { *((
volatile int*)__null) = 11292; __attribute__((nomerge)) ::abort
(); } while (false); } } while (false)
;
11293
11294 JSOp op = JSOp::Call;
11295 bool maybeAsyncArrow = false;
11296 if (tt == TokenKind::LeftParen && optionalKind == OptionalKind::NonOptional) {
11297 if (handler_.isAsyncKeyword(lhs)) {
11298 // |async (| can be the start of an async arrow
11299 // function, so we need to defer reporting possible
11300 // errors from destructuring syntax. To give better
11301 // error messages, we only allow the AsyncArrowHead
11302 // part of the CoverCallExpressionAndAsyncArrowHead
11303 // syntax when the initial name is "async".
11304 maybeAsyncArrow = true;
11305 } else if (handler_.isEvalName(lhs)) {
11306 // Select the right Eval op and flag pc_ as having a
11307 // direct eval.
11308 op = pc_->sc()->strict() ? JSOp::StrictEval : JSOp::Eval;
11309 pc_->sc()->setBindingsAccessedDynamically();
11310 pc_->sc()->setHasDirectEval();
11311
11312 // In non-strict mode code, direct calls to eval can
11313 // add variables to the call object.
11314 if (pc_->isFunctionBox() && !pc_->sc()->strict()) {
11315 pc_->functionBox()->setFunHasExtensibleScope();
11316 }
11317
11318 // If we're in a method, mark the method as requiring
11319 // support for 'super', since direct eval code can use
11320 // it. (If we're not in a method, that's fine, so
11321 // ignore the return value.)
11322 checkAndMarkSuperScope();
11323 }
11324 }
11325
11326 if (tt == TokenKind::LeftParen) {
11327 bool isSpread = false;
11328 PossibleError* asyncPossibleError =
11329 maybeAsyncArrow ? possibleError : nullptr;
11330 ListNodeType args;
11331 MOZ_TRY_VAR(args,do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread, asyncPossibleError)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (args) = mozTryVarTempResult_.unwrap(); } while
(0)
11332 argumentList(yieldHandling, &isSpread, asyncPossibleError))do { auto mozTryVarTempResult_ = (argumentList(yieldHandling,
&isSpread, asyncPossibleError)); if ((__builtin_expect(!
!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (args) = mozTryVarTempResult_.unwrap(); } while
(0)
;
11333 if (isSpread) {
11334 if (op == JSOp::Eval) {
11335 op = JSOp::SpreadEval;
11336 } else if (op == JSOp::StrictEval) {
11337 op = JSOp::StrictSpreadEval;
11338 } else {
11339 op = JSOp::SpreadCall;
11340 }
11341 }
11342
11343 if (optionalKind == OptionalKind::Optional) {
11344 return handler_.newOptionalCall(lhs, args, op);
11345 }
11346 return handler_.newCall(lhs, args, op);
11347 }
11348
11349 ListNodeType args;
11350 MOZ_TRY_VAR(args, handler_.newArguments(pos()))do { auto mozTryVarTempResult_ = (handler_.newArguments(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (args) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11351
11352 if (!taggedTemplate(yieldHandling, args, tt)) {
11353 return errorResult();
11354 }
11355
11356 if (optionalKind == OptionalKind::Optional) {
11357 error(JSMSG_BAD_OPTIONAL_TEMPLATE);
11358 return errorResult();
11359 }
11360
11361 return handler_.newTaggedTemplate(lhs, args, op);
11362}
11363
11364template <class ParseHandler, typename Unit>
11365bool GeneralParser<ParseHandler, Unit>::checkLabelOrIdentifierReference(
11366 TaggedParserAtomIndex ident, uint32_t offset, YieldHandling yieldHandling,
11367 TokenKind hint /* = TokenKind::Limit */) {
11368 TokenKind tt;
11369 if (hint == TokenKind::Limit) {
11370 tt = ReservedWordTokenKind(ident);
11371 } else {
11372 // All non-reserved word kinds are folded into TokenKind::Limit in
11373 // ReservedWordTokenKind and the following code.
11374 if (hint == TokenKind::Name || hint == TokenKind::PrivateName) {
11375 hint = TokenKind::Limit;
11376 }
11377 MOZ_ASSERT(hint == ReservedWordTokenKind(ident),do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hint == ReservedWordTokenKind(ident))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hint == ReservedWordTokenKind
(ident)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("hint == ReservedWordTokenKind(ident)" " (" "hint doesn't match actual token kind"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11378); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hint == ReservedWordTokenKind(ident)"
") (" "hint doesn't match actual token kind" ")"); do { *((volatile
int*)__null) = 11378; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
11378 "hint doesn't match actual token kind")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(hint == ReservedWordTokenKind(ident))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(hint == ReservedWordTokenKind
(ident)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("hint == ReservedWordTokenKind(ident)" " (" "hint doesn't match actual token kind"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11378); AnnotateMozCrashReason("MOZ_ASSERT" "(" "hint == ReservedWordTokenKind(ident)"
") (" "hint doesn't match actual token kind" ")"); do { *((volatile
int*)__null) = 11378; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
11379 tt = hint;
11380 }
11381
11382 if (!pc_->sc()->allowArguments() &&
11383 ident == TaggedParserAtomIndex::WellKnown::arguments()) {
11384 error(JSMSG_BAD_ARGUMENTS);
11385 return false;
11386 }
11387
11388 if (tt == TokenKind::Limit) {
11389 // Either TokenKind::Name or TokenKind::PrivateName
11390 return true;
11391 }
11392 if (TokenKindIsContextualKeyword(tt)) {
11393 if (tt == TokenKind::Yield) {
11394 if (yieldHandling == YieldIsKeyword) {
11395 errorAt(offset, JSMSG_RESERVED_ID, "yield");
11396 return false;
11397 }
11398 if (pc_->sc()->strict()) {
11399 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "yield")) {
11400 return false;
11401 }
11402 }
11403 return true;
11404 }
11405 if (tt == TokenKind::Await) {
11406 if (awaitIsKeyword() || awaitIsDisallowed()) {
11407 errorAt(offset, JSMSG_RESERVED_ID, "await");
11408 return false;
11409 }
11410 return true;
11411 }
11412 if (pc_->sc()->strict()) {
11413 if (tt == TokenKind::Let) {
11414 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "let")) {
11415 return false;
11416 }
11417 return true;
11418 }
11419 if (tt == TokenKind::Static) {
11420 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID, "static")) {
11421 return false;
11422 }
11423 return true;
11424 }
11425 }
11426 return true;
11427 }
11428 if (TokenKindIsStrictReservedWord(tt)) {
11429 if (pc_->sc()->strict()) {
11430 if (!strictModeErrorAt(offset, JSMSG_RESERVED_ID,
11431 ReservedWordToCharZ(tt))) {
11432 return false;
11433 }
11434 }
11435 return true;
11436 }
11437 if (TokenKindIsKeyword(tt) || TokenKindIsReservedWordLiteral(tt)) {
11438 errorAt(offset, JSMSG_INVALID_ID, ReservedWordToCharZ(tt));
11439 return false;
11440 }
11441 if (TokenKindIsFutureReservedWord(tt)) {
11442 errorAt(offset, JSMSG_RESERVED_ID, ReservedWordToCharZ(tt));
11443 return false;
11444 }
11445 MOZ_ASSERT_UNREACHABLE("Unexpected reserved word kind.")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(false)>::isValid, "invalid assertion condition");
if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while (
false); MOZ_ReportAssertionFailure("false" " (" "MOZ_ASSERT_UNREACHABLE: "
"Unexpected reserved word kind." ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11445); AnnotateMozCrashReason("MOZ_ASSERT" "(" "false" ") ("
"MOZ_ASSERT_UNREACHABLE: " "Unexpected reserved word kind." ")"
); do { *((volatile int*)__null) = 11445; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
11446 return false;
11447}
11448
11449template <class ParseHandler, typename Unit>
11450bool GeneralParser<ParseHandler, Unit>::checkBindingIdentifier(
11451 TaggedParserAtomIndex ident, uint32_t offset, YieldHandling yieldHandling,
11452 TokenKind hint /* = TokenKind::Limit */) {
11453 if (pc_->sc()->strict()) {
11454 if (ident == TaggedParserAtomIndex::WellKnown::arguments()) {
11455 if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "arguments")) {
11456 return false;
11457 }
11458 return true;
11459 }
11460
11461 if (ident == TaggedParserAtomIndex::WellKnown::eval()) {
11462 if (!strictModeErrorAt(offset, JSMSG_BAD_STRICT_ASSIGN, "eval")) {
11463 return false;
11464 }
11465 return true;
11466 }
11467 }
11468
11469 return checkLabelOrIdentifierReference(ident, offset, yieldHandling, hint);
11470}
11471
11472template <class ParseHandler, typename Unit>
11473TaggedParserAtomIndex
11474GeneralParser<ParseHandler, Unit>::labelOrIdentifierReference(
11475 YieldHandling yieldHandling) {
11476 // ES 2017 draft 12.1.1.
11477 // StringValue of IdentifierName normalizes any Unicode escape sequences
11478 // in IdentifierName hence such escapes cannot be used to write an
11479 // Identifier whose code point sequence is the same as a ReservedWord.
11480 //
11481 // Use const ParserName* instead of TokenKind to reflect the normalization.
11482
11483 // Unless the name contains escapes, we can reuse the current TokenKind
11484 // to determine if the name is a restricted identifier.
11485 TokenKind hint = !anyChars.currentNameHasEscapes(this->parserAtoms())
11486 ? anyChars.currentToken().type
11487 : TokenKind::Limit;
11488 TaggedParserAtomIndex ident = anyChars.currentName();
11489 if (!checkLabelOrIdentifierReference(ident, pos().begin, yieldHandling,
11490 hint)) {
11491 return TaggedParserAtomIndex::null();
11492 }
11493 return ident;
11494}
11495
11496template <class ParseHandler, typename Unit>
11497TaggedParserAtomIndex GeneralParser<ParseHandler, Unit>::bindingIdentifier(
11498 YieldHandling yieldHandling) {
11499 TokenKind hint = !anyChars.currentNameHasEscapes(this->parserAtoms())
11500 ? anyChars.currentToken().type
11501 : TokenKind::Limit;
11502 TaggedParserAtomIndex ident = anyChars.currentName();
11503 if (!checkBindingIdentifier(ident, pos().begin, yieldHandling, hint)) {
11504 return TaggedParserAtomIndex::null();
11505 }
11506 return ident;
11507}
11508
11509template <class ParseHandler>
11510typename ParseHandler::NameNodeResult
11511PerHandlerParser<ParseHandler>::identifierReference(
11512 TaggedParserAtomIndex name) {
11513 NameNodeType id;
11514 MOZ_TRY_VAR(id, newName(name))do { auto mozTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (id) = mozTryVarTempResult_.unwrap(); } while
(0)
;
11515
11516 if (!noteUsedName(name)) {
11517 return errorResult();
11518 }
11519
11520 return id;
11521}
11522
11523template <class ParseHandler>
11524typename ParseHandler::NameNodeResult
11525PerHandlerParser<ParseHandler>::privateNameReference(
11526 TaggedParserAtomIndex name) {
11527 NameNodeType id;
11528 MOZ_TRY_VAR(id, newPrivateName(name))do { auto mozTryVarTempResult_ = (newPrivateName(name)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (id) = mozTryVarTempResult_
.unwrap(); } while (0)
;
11529
11530 if (!noteUsedName(name, NameVisibility::Private, Some(pos()))) {
11531 return errorResult();
11532 }
11533
11534 return id;
11535}
11536
11537template <class ParseHandler>
11538typename ParseHandler::NameNodeResult
11539PerHandlerParser<ParseHandler>::stringLiteral() {
11540 return handler_.newStringLiteral(anyChars.currentToken().atom(), pos());
11541}
11542
11543template <class ParseHandler>
11544typename ParseHandler::NodeResult
11545PerHandlerParser<ParseHandler>::noSubstitutionTaggedTemplate() {
11546 if (anyChars.hasInvalidTemplateEscape()) {
11547 anyChars.clearInvalidTemplateEscape();
11548 return handler_.newRawUndefinedLiteral(pos());
11549 }
11550
11551 return handler_.newTemplateStringLiteral(anyChars.currentToken().atom(),
11552 pos());
11553}
11554
11555template <class ParseHandler, typename Unit>
11556typename ParseHandler::NameNodeResult
11557GeneralParser<ParseHandler, Unit>::noSubstitutionUntaggedTemplate() {
11558 if (!tokenStream.checkForInvalidTemplateEscapeError()) {
11559 return errorResult();
11560 }
11561
11562 return handler_.newTemplateStringLiteral(anyChars.currentToken().atom(),
11563 pos());
11564}
11565
11566template <typename Unit>
11567FullParseHandler::RegExpLiteralResult
11568Parser<FullParseHandler, Unit>::newRegExp() {
11569 MOZ_ASSERT(!options().selfHostingMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!options().selfHostingMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!options().selfHostingMode))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!options().selfHostingMode"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11569); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 11569; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11570
11571 // Create the regexp and check its syntax.
11572 const auto& chars = tokenStream.getCharBuffer();
11573 mozilla::Range<const char16_t> range(chars.begin(), chars.length());
11574 RegExpFlags flags = anyChars.currentToken().regExpFlags();
11575
11576 uint32_t offset = anyChars.currentToken().pos.begin;
11577 uint32_t line;
11578 JS::LimitedColumnNumberOneOrigin column;
11579 tokenStream.computeLineAndColumn(offset, &line, &column);
11580
11581 if (!handler_.reuseRegexpSyntaxParse()) {
11582 // Verify that the Regexp will syntax parse when the time comes to
11583 // instantiate it. If we have already done a syntax parse, we can
11584 // skip this.
11585 if (!irregexp::CheckPatternSyntax(
11586 this->alloc_, this->fc_->stackLimit(), anyChars, range, flags,
11587 Some(line), Some(JS::ColumnNumberOneOrigin(column)))) {
11588 return errorResult();
11589 }
11590 }
11591
11592 auto atom =
11593 this->parserAtoms().internChar16(fc_, chars.begin(), chars.length());
11594 if (!atom) {
11595 return errorResult();
11596 }
11597 // RegExp patterm must be atomized.
11598 this->parserAtoms().markUsedByStencil(atom, ParserAtom::Atomize::Yes);
11599
11600 RegExpIndex index(this->compilationState_.regExpData.length());
11601 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
11602 ReportAllocationOverflow(fc_);
11603 return errorResult();
11604 }
11605 if (!this->compilationState_.regExpData.emplaceBack(atom, flags)) {
11606 js::ReportOutOfMemory(this->fc_);
11607 return errorResult();
11608 }
11609
11610 return handler_.newRegExp(index, pos());
11611}
11612
11613template <typename Unit>
11614SyntaxParseHandler::RegExpLiteralResult
11615Parser<SyntaxParseHandler, Unit>::newRegExp() {
11616 MOZ_ASSERT(!options().selfHostingMode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!options().selfHostingMode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!options().selfHostingMode))
), 0))) { do { } while (false); MOZ_ReportAssertionFailure("!options().selfHostingMode"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!options().selfHostingMode"
")"); do { *((volatile int*)__null) = 11616; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11617
11618 // Only check the regexp's syntax, but don't create a regexp object.
11619 const auto& chars = tokenStream.getCharBuffer();
11620 RegExpFlags flags = anyChars.currentToken().regExpFlags();
11621
11622 uint32_t offset = anyChars.currentToken().pos.begin;
11623 uint32_t line;
11624 JS::LimitedColumnNumberOneOrigin column;
11625 tokenStream.computeLineAndColumn(offset, &line, &column);
11626
11627 mozilla::Range<const char16_t> source(chars.begin(), chars.length());
11628 if (!irregexp::CheckPatternSyntax(this->alloc_, this->fc_->stackLimit(),
11629 anyChars, source, flags, Some(line),
11630 Some(JS::ColumnNumberOneOrigin(column)))) {
11631 return errorResult();
11632 }
11633
11634 return handler_.newRegExp(SyntaxParseHandler::Node::NodeGeneric, pos());
11635}
11636
11637template <class ParseHandler, typename Unit>
11638typename ParseHandler::RegExpLiteralResult
11639GeneralParser<ParseHandler, Unit>::newRegExp() {
11640 return asFinalParser()->newRegExp();
11641}
11642
11643template <typename Unit>
11644FullParseHandler::BigIntLiteralResult
11645Parser<FullParseHandler, Unit>::newBigInt() {
11646 // The token's charBuffer contains the DecimalIntegerLiteral or
11647 // NonDecimalIntegerLiteral production, and as such does not include the
11648 // BigIntLiteralSuffix (the trailing "n"). Note that NonDecimalIntegerLiteral
11649 // productions start with 0[bBoOxX], indicating binary/octal/hex.
11650 const auto& chars = tokenStream.getCharBuffer();
11651 if (chars.length() > UINT32_MAX(4294967295U)) {
11652 ReportAllocationOverflow(fc_);
11653 return errorResult();
11654 }
11655
11656 BigIntIndex index(this->bigInts().length());
11657 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
11658 ReportAllocationOverflow(fc_);
11659 return errorResult();
11660 }
11661 if (!this->bigInts().emplaceBack()) {
11662 js::ReportOutOfMemory(this->fc_);
11663 return errorResult();
11664 }
11665
11666 if (!this->bigInts()[index].init(this->fc_, this->stencilAlloc(), chars)) {
11667 return errorResult();
11668 }
11669
11670 // Should the operations below fail, the buffer held by data will
11671 // be cleaned up by the CompilationState destructor.
11672 return handler_.newBigInt(index, pos());
11673}
11674
11675template <typename Unit>
11676SyntaxParseHandler::BigIntLiteralResult
11677Parser<SyntaxParseHandler, Unit>::newBigInt() {
11678 // The tokenizer has already checked the syntax of the bigint.
11679
11680 return handler_.newBigInt();
11681}
11682
11683template <class ParseHandler, typename Unit>
11684typename ParseHandler::BigIntLiteralResult
11685GeneralParser<ParseHandler, Unit>::newBigInt() {
11686 return asFinalParser()->newBigInt();
11687}
11688
11689// |exprPossibleError| is the PossibleError state within |expr|,
11690// |possibleError| is the surrounding PossibleError state.
11691template <class ParseHandler, typename Unit>
11692bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentTarget(
11693 Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
11694 PossibleError* possibleError, TargetBehavior behavior) {
11695 // Report any pending expression error if we're definitely not in a
11696 // destructuring context or the possible destructuring target is a
11697 // property accessor.
11698 if (!possibleError || handler_.isPropertyOrPrivateMemberAccess(expr)) {
11699 return exprPossibleError->checkForExpressionError();
11700 }
11701
11702 // |expr| may end up as a destructuring assignment target, so we need to
11703 // validate it's either a name or can be parsed as a nested destructuring
11704 // pattern. Property accessors are also valid assignment targets, but
11705 // those are already handled above.
11706
11707 exprPossibleError->transferErrorsTo(possibleError);
11708
11709 // Return early if a pending destructuring error is already present.
11710 if (possibleError->hasPendingDestructuringError()) {
11711 return true;
11712 }
11713
11714 if (handler_.isName(expr)) {
11715 checkDestructuringAssignmentName(handler_.asNameNode(expr), exprPos,
11716 possibleError);
11717 return true;
11718 }
11719
11720 if (handler_.isUnparenthesizedDestructuringPattern(expr)) {
11721 if (behavior == TargetBehavior::ForbidAssignmentPattern) {
11722 possibleError->setPendingDestructuringErrorAt(exprPos,
11723 JSMSG_BAD_DESTRUCT_TARGET);
11724 }
11725 return true;
11726 }
11727
11728 // Parentheses are forbidden around destructuring *patterns* (but allowed
11729 // around names). Use our nicer error message for parenthesized, nested
11730 // patterns if nested destructuring patterns are allowed.
11731 if (handler_.isParenthesizedDestructuringPattern(expr) &&
11732 behavior != TargetBehavior::ForbidAssignmentPattern) {
11733 possibleError->setPendingDestructuringErrorAt(exprPos,
11734 JSMSG_BAD_DESTRUCT_PARENS);
11735 } else {
11736 possibleError->setPendingDestructuringErrorAt(exprPos,
11737 JSMSG_BAD_DESTRUCT_TARGET);
11738 }
11739
11740 return true;
11741}
11742
11743template <class ParseHandler, typename Unit>
11744void GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentName(
11745 NameNodeType name, TokenPos namePos, PossibleError* possibleError) {
11746#ifdef DEBUG1
11747 // GCC 8.0.1 crashes if this is a one-liner.
11748 bool isName = handler_.isName(name);
11749 MOZ_ASSERT(isName)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(isName)>::isValid, "invalid assertion condition")
; if ((__builtin_expect(!!(!(!!(isName))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("isName", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11749); AnnotateMozCrashReason("MOZ_ASSERT" "(" "isName" ")"
); do { *((volatile int*)__null) = 11749; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
11750#endif
11751
11752 // Return early if a pending destructuring error is already present.
11753 if (possibleError->hasPendingDestructuringError()) {
11754 return;
11755 }
11756
11757 if (handler_.isArgumentsLength(name)) {
11758 pc_->sc()->setIneligibleForArgumentsLength();
11759 }
11760
11761 if (pc_->sc()->strict()) {
11762 if (handler_.isArgumentsName(name)) {
11763 if (pc_->sc()->strict()) {
11764 possibleError->setPendingDestructuringErrorAt(
11765 namePos, JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
11766 } else {
11767 possibleError->setPendingDestructuringWarningAt(
11768 namePos, JSMSG_BAD_STRICT_ASSIGN_ARGUMENTS);
11769 }
11770 return;
11771 }
11772
11773 if (handler_.isEvalName(name)) {
11774 if (pc_->sc()->strict()) {
11775 possibleError->setPendingDestructuringErrorAt(
11776 namePos, JSMSG_BAD_STRICT_ASSIGN_EVAL);
11777 } else {
11778 possibleError->setPendingDestructuringWarningAt(
11779 namePos, JSMSG_BAD_STRICT_ASSIGN_EVAL);
11780 }
11781 return;
11782 }
11783 }
11784}
11785
11786template <class ParseHandler, typename Unit>
11787bool GeneralParser<ParseHandler, Unit>::checkDestructuringAssignmentElement(
11788 Node expr, TokenPos exprPos, PossibleError* exprPossibleError,
11789 PossibleError* possibleError) {
11790 // ES2018 draft rev 0719f44aab93215ed9a626b2f45bd34f36916834
11791 // 12.15.5 Destructuring Assignment
11792 //
11793 // AssignmentElement[Yield, Await]:
11794 // DestructuringAssignmentTarget[?Yield, ?Await]
11795 // DestructuringAssignmentTarget[?Yield, ?Await] Initializer[+In,
11796 // ?Yield,
11797 // ?Await]
11798
11799 // If |expr| is an assignment element with an initializer expression, its
11800 // destructuring assignment target was already validated in assignExpr().
11801 // Otherwise we need to check that |expr| is a valid destructuring target.
11802 if (handler_.isUnparenthesizedAssignment(expr)) {
11803 // Report any pending expression error if we're definitely not in a
11804 // destructuring context.
11805 if (!possibleError) {
11806 return exprPossibleError->checkForExpressionError();
11807 }
11808
11809 exprPossibleError->transferErrorsTo(possibleError);
11810 return true;
11811 }
11812 return checkDestructuringAssignmentTarget(expr, exprPos, exprPossibleError,
11813 possibleError);
11814}
11815
11816template <class ParseHandler, typename Unit>
11817typename ParseHandler::ListNodeResult
11818GeneralParser<ParseHandler, Unit>::arrayInitializer(
11819 YieldHandling yieldHandling, PossibleError* possibleError) {
11820 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 11820); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 11820; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
11821
11822 uint32_t begin = pos().begin;
11823 ListNodeType literal;
11824 MOZ_TRY_VAR(literal, handler_.newArrayLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newArrayLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
11825
11826 TokenKind tt;
11827 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
11828 return errorResult();
11829 }
11830
11831 if (tt == TokenKind::RightBracket) {
11832 /*
11833 * Mark empty arrays as non-constant, since we cannot easily
11834 * determine their type.
11835 */
11836 handler_.setListHasNonConstInitializer(literal);
11837 } else {
11838 anyChars.ungetToken();
11839
11840 for (uint32_t index = 0;; index++) {
11841 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
11842 error(JSMSG_ARRAY_INIT_TOO_BIG);
11843 return errorResult();
11844 }
11845
11846 TokenKind tt;
11847 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
11848 return errorResult();
11849 }
11850 if (tt == TokenKind::RightBracket) {
11851 break;
11852 }
11853
11854 if (tt == TokenKind::Comma) {
11855 tokenStream.consumeKnownToken(TokenKind::Comma,
11856 TokenStream::SlashIsRegExp);
11857 if (!handler_.addElision(literal, pos())) {
11858 return errorResult();
11859 }
11860 continue;
11861 }
11862
11863 if (tt == TokenKind::TripleDot) {
11864 tokenStream.consumeKnownToken(TokenKind::TripleDot,
11865 TokenStream::SlashIsRegExp);
11866 uint32_t begin = pos().begin;
11867
11868 TokenPos innerPos;
11869 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
11870 return errorResult();
11871 }
11872
11873 PossibleError possibleErrorInner(*this);
11874 Node inner;
11875 MOZ_TRY_VAR(inner,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
11876 assignExpr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
11877 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
;
11878 if (!checkDestructuringAssignmentTarget(
11879 inner, innerPos, &possibleErrorInner, possibleError)) {
11880 return errorResult();
11881 }
11882
11883 if (!handler_.addSpreadElement(literal, begin, inner)) {
11884 return errorResult();
11885 }
11886 } else {
11887 TokenPos elementPos;
11888 if (!tokenStream.peekTokenPos(&elementPos,
11889 TokenStream::SlashIsRegExp)) {
11890 return errorResult();
11891 }
11892
11893 PossibleError possibleErrorInner(*this);
11894 Node element;
11895 MOZ_TRY_VAR(element,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (element) = mozTryVarTempResult_.unwrap();
} while (0)
11896 assignExpr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (element) = mozTryVarTempResult_.unwrap();
} while (0)
11897 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (element) = mozTryVarTempResult_.unwrap();
} while (0)
;
11898 if (!checkDestructuringAssignmentElement(
11899 element, elementPos, &possibleErrorInner, possibleError)) {
11900 return errorResult();
11901 }
11902 handler_.addArrayElement(literal, element);
11903 }
11904
11905 bool matched;
11906 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
11907 TokenStream::SlashIsRegExp)) {
11908 return errorResult();
11909 }
11910 if (!matched) {
11911 break;
11912 }
11913
11914 if (tt == TokenKind::TripleDot && possibleError) {
11915 possibleError->setPendingDestructuringErrorAt(pos(),
11916 JSMSG_REST_WITH_COMMA);
11917 }
11918 }
11919
11920 if (!mustMatchToken(
11921 TokenKind::RightBracket, [this, begin](TokenKind actual) {
11922 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
11923 JSMSG_BRACKET_OPENED, begin);
11924 })) {
11925 return errorResult();
11926 }
11927 }
11928
11929 handler_.setEndPosition(literal, pos().end);
11930 return literal;
11931}
11932
11933template <class ParseHandler, typename Unit>
11934typename ParseHandler::NodeResult
11935GeneralParser<ParseHandler, Unit>::propertyName(
11936 YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
11937 const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
11938 TaggedParserAtomIndex* propAtomOut) {
11939 // PropertyName[Yield, Await]:
11940 // LiteralPropertyName
11941 // ComputedPropertyName[?Yield, ?Await]
11942 //
11943 // LiteralPropertyName:
11944 // IdentifierName
11945 // StringLiteral
11946 // NumericLiteral
11947 TokenKind ltok = anyChars.currentToken().type;
11948
11949 *propAtomOut = TaggedParserAtomIndex::null();
11950 switch (ltok) {
11951 case TokenKind::Number: {
11952 auto numAtom = NumberToParserAtom(fc_, this->parserAtoms(),
11953 anyChars.currentToken().number());
11954 if (!numAtom) {
11955 return errorResult();
11956 }
11957 *propAtomOut = numAtom;
11958 return newNumber(anyChars.currentToken());
11959 }
11960
11961 case TokenKind::BigInt: {
11962 Node biNode;
11963 MOZ_TRY_VAR(biNode, newBigInt())do { auto mozTryVarTempResult_ = (newBigInt()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (biNode) = mozTryVarTempResult_.unwrap(); }
while (0)
;
11964 return handler_.newSyntheticComputedName(biNode, pos().begin, pos().end);
11965 }
11966 case TokenKind::String: {
11967 auto str = anyChars.currentToken().atom();
11968 *propAtomOut = str;
11969 uint32_t index;
11970 if (this->parserAtoms().isIndex(str, &index)) {
11971 return handler_.newNumber(index, NoDecimal, pos());
11972 }
11973 return stringLiteral();
11974 }
11975
11976 case TokenKind::LeftBracket:
11977 return computedPropertyName(yieldHandling, maybeDecl, propertyNameContext,
11978 propList);
11979
11980 case TokenKind::PrivateName: {
11981 if (propertyNameContext != PropertyNameContext::PropertyNameInClass) {
11982 error(JSMSG_ILLEGAL_PRIVATE_FIELD);
11983 return errorResult();
11984 }
11985
11986 TaggedParserAtomIndex propName = anyChars.currentName();
11987 *propAtomOut = propName;
11988 return privateNameReference(propName);
11989 }
11990
11991 default: {
11992 if (!TokenKindIsPossibleIdentifierName(ltok)) {
11993 error(JSMSG_UNEXPECTED_TOKEN, "property name", TokenKindToDesc(ltok));
11994 return errorResult();
11995 }
11996
11997 TaggedParserAtomIndex name = anyChars.currentName();
11998 *propAtomOut = name;
11999 return handler_.newObjectLiteralPropertyName(name, pos());
12000 }
12001 }
12002}
12003
12004// True if `kind` can be the first token of a PropertyName.
12005static bool TokenKindCanStartPropertyName(TokenKind tt) {
12006 return TokenKindIsPossibleIdentifierName(tt) || tt == TokenKind::String ||
12007 tt == TokenKind::Number || tt == TokenKind::LeftBracket ||
12008 tt == TokenKind::BigInt || tt == TokenKind::PrivateName;
12009}
12010
12011template <class ParseHandler, typename Unit>
12012typename ParseHandler::NodeResult
12013GeneralParser<ParseHandler, Unit>::propertyOrMethodName(
12014 YieldHandling yieldHandling, PropertyNameContext propertyNameContext,
12015 const Maybe<DeclarationKind>& maybeDecl, ListNodeType propList,
12016 PropertyType* propType, TaggedParserAtomIndex* propAtomOut) {
12017 // We're parsing an object literal, class, or destructuring pattern;
12018 // propertyNameContext tells which one. This method parses any of the
12019 // following, storing the corresponding PropertyType in `*propType` to tell
12020 // the caller what we parsed:
12021 //
12022 // async [no LineTerminator here] PropertyName
12023 // ==> PropertyType::AsyncMethod
12024 // async [no LineTerminator here] * PropertyName
12025 // ==> PropertyType::AsyncGeneratorMethod
12026 // * PropertyName ==> PropertyType::GeneratorMethod
12027 // get PropertyName ==> PropertyType::Getter
12028 // set PropertyName ==> PropertyType::Setter
12029 // accessor PropertyName ==> PropertyType::FieldWithAccessor
12030 // PropertyName : ==> PropertyType::Normal
12031 // PropertyName ==> see below
12032 //
12033 // In the last case, where there's not a `:` token to consume, we peek at
12034 // (but don't consume) the next token to decide how to set `*propType`.
12035 //
12036 // `,` or `}` ==> PropertyType::Shorthand
12037 // `(` ==> PropertyType::Method
12038 // `=`, not in a class ==> PropertyType::CoverInitializedName
12039 // '=', in a class ==> PropertyType::Field
12040 // any token, in a class ==> PropertyType::Field (ASI)
12041 //
12042 // The caller must check `*propType` and throw if whatever we parsed isn't
12043 // allowed here (for example, a getter in a destructuring pattern).
12044 //
12045 // This method does *not* match `static` (allowed in classes) or `...`
12046 // (allowed in object literals and patterns). The caller must take care of
12047 // those before calling this method.
12048
12049 TokenKind ltok;
12050 if (!tokenStream.getToken(&ltok, TokenStream::SlashIsInvalid)) {
12051 return errorResult();
12052 }
12053
12054 MOZ_ASSERT(ltok != TokenKind::RightCurly,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ltok != TokenKind::RightCurly)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(ltok != TokenKind::RightCurly
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"ltok != TokenKind::RightCurly" " (" "caller should have handled TokenKind::RightCurly"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12055); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ltok != TokenKind::RightCurly"
") (" "caller should have handled TokenKind::RightCurly" ")"
); do { *((volatile int*)__null) = 12055; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
12055 "caller should have handled TokenKind::RightCurly")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(ltok != TokenKind::RightCurly)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(ltok != TokenKind::RightCurly
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"ltok != TokenKind::RightCurly" " (" "caller should have handled TokenKind::RightCurly"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12055); AnnotateMozCrashReason("MOZ_ASSERT" "(" "ltok != TokenKind::RightCurly"
") (" "caller should have handled TokenKind::RightCurly" ")"
); do { *((volatile int*)__null) = 12055; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
12056
12057 // Accept `async` and/or `*`, indicating an async or generator method;
12058 // or `get` or `set` or `accessor`, indicating an accessor.
12059 bool isGenerator = false;
12060 bool isAsync = false;
12061 bool isGetter = false;
12062 bool isSetter = false;
12063#ifdef ENABLE_DECORATORS
12064 bool hasAccessor = false;
12065#endif
12066
12067 if (ltok == TokenKind::Async) {
12068 // `async` is also a PropertyName by itself (it's a conditional keyword),
12069 // so peek at the next token to see if we're really looking at a method.
12070 TokenKind tt = TokenKind::Eof;
12071 if (!tokenStream.peekTokenSameLine(&tt)) {
12072 return errorResult();
12073 }
12074 if (TokenKindCanStartPropertyName(tt) || tt == TokenKind::Mul) {
12075 isAsync = true;
12076 tokenStream.consumeKnownToken(tt);
12077 ltok = tt;
12078 }
12079 }
12080
12081 if (ltok == TokenKind::Mul) {
12082 isGenerator = true;
12083 if (!tokenStream.getToken(&ltok)) {
12084 return errorResult();
12085 }
12086 }
12087
12088 if (!isAsync && !isGenerator &&
12089 (ltok == TokenKind::Get || ltok == TokenKind::Set)) {
12090 // We have parsed |get| or |set|. Look for an accessor property
12091 // name next.
12092 TokenKind tt;
12093 if (!tokenStream.peekToken(&tt)) {
12094 return errorResult();
12095 }
12096 if (TokenKindCanStartPropertyName(tt)) {
12097 tokenStream.consumeKnownToken(tt);
12098 isGetter = (ltok == TokenKind::Get);
12099 isSetter = (ltok == TokenKind::Set);
12100 }
12101 }
12102
12103#ifdef ENABLE_DECORATORS
12104 if (!isGenerator && !isAsync && propertyNameContext == PropertyNameInClass &&
12105 ltok == TokenKind::Accessor) {
12106 MOZ_ASSERT(!isGetter && !isSetter)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!isGetter && !isSetter)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!isGetter && !isSetter
))), 0))) { do { } while (false); MOZ_ReportAssertionFailure(
"!isGetter && !isSetter", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12106); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!isGetter && !isSetter"
")"); do { *((volatile int*)__null) = 12106; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12107 TokenKind tt;
12108 if (!tokenStream.peekTokenSameLine(&tt)) {
12109 return errorResult();
12110 }
12111
12112 // The target rule is `accessor [no LineTerminator here]
12113 // ClassElementName[?Yield, ?Await] Initializer[+In, ?Yield, ?Await]opt`
12114 if (TokenKindCanStartPropertyName(tt)) {
12115 tokenStream.consumeKnownToken(tt);
12116 hasAccessor = true;
12117 }
12118 }
12119#endif
12120
12121 Node propName;
12122 MOZ_TRY_VAR(propName, propertyName(yieldHandling, propertyNameContext,do { auto mozTryVarTempResult_ = (propertyName(yieldHandling,
propertyNameContext, maybeDecl, propList, propAtomOut)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propName) = mozTryVarTempResult_
.unwrap(); } while (0)
12123 maybeDecl, propList, propAtomOut))do { auto mozTryVarTempResult_ = (propertyName(yieldHandling,
propertyNameContext, maybeDecl, propList, propAtomOut)); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (propName) = mozTryVarTempResult_
.unwrap(); } while (0)
;
12124
12125 // Grab the next token following the property/method name.
12126 // (If this isn't a colon, we're going to either put it back or throw.)
12127 TokenKind tt;
12128 if (!tokenStream.getToken(&tt)) {
12129 return errorResult();
12130 }
12131
12132 if (tt == TokenKind::Colon) {
12133 if (isGenerator || isAsync || isGetter || isSetter
12134#ifdef ENABLE_DECORATORS
12135 || hasAccessor
12136#endif
12137 ) {
12138 error(JSMSG_BAD_PROP_ID);
12139 return errorResult();
12140 }
12141 *propType = PropertyType::Normal;
12142 return propName;
12143 }
12144
12145 if (propertyNameContext != PropertyNameInClass &&
12146 TokenKindIsPossibleIdentifierName(ltok) &&
12147 (tt == TokenKind::Comma || tt == TokenKind::RightCurly ||
12148 tt == TokenKind::Assign)) {
12149#ifdef ENABLE_DECORATORS
12150 MOZ_ASSERT(!hasAccessor)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!hasAccessor)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!hasAccessor))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("!hasAccessor", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12150); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!hasAccessor"
")"); do { *((volatile int*)__null) = 12150; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12151#endif
12152 if (isGenerator || isAsync || isGetter || isSetter) {
12153 error(JSMSG_BAD_PROP_ID);
12154 return errorResult();
12155 }
12156
12157 anyChars.ungetToken();
12158 *propType = tt == TokenKind::Assign ? PropertyType::CoverInitializedName
12159 : PropertyType::Shorthand;
12160 return propName;
12161 }
12162
12163 if (tt == TokenKind::LeftParen) {
12164 anyChars.ungetToken();
12165
12166#ifdef ENABLE_RECORD_TUPLE
12167 if (propertyNameContext == PropertyNameInRecord) {
12168 // Record & Tuple proposal, section 7.1.1:
12169 // RecordPropertyDefinition doesn't cover methods
12170 error(JSMSG_BAD_PROP_ID);
12171 return errorResult();
12172 }
12173#endif
12174
12175#ifdef ENABLE_DECORATORS
12176 if (hasAccessor) {
12177 error(JSMSG_BAD_PROP_ID);
12178 return errorResult();
12179 }
12180#endif
12181
12182 if (isGenerator && isAsync) {
12183 *propType = PropertyType::AsyncGeneratorMethod;
12184 } else if (isGenerator) {
12185 *propType = PropertyType::GeneratorMethod;
12186 } else if (isAsync) {
12187 *propType = PropertyType::AsyncMethod;
12188 } else if (isGetter) {
12189 *propType = PropertyType::Getter;
12190 } else if (isSetter) {
12191 *propType = PropertyType::Setter;
12192 } else {
12193 *propType = PropertyType::Method;
12194 }
12195 return propName;
12196 }
12197
12198 if (propertyNameContext == PropertyNameInClass) {
12199 if (isGenerator || isAsync || isGetter || isSetter) {
12200 error(JSMSG_BAD_PROP_ID);
12201 return errorResult();
12202 }
12203 anyChars.ungetToken();
12204#ifdef ENABLE_DECORATORS
12205 if (!hasAccessor) {
12206 *propType = PropertyType::Field;
12207 } else {
12208 *propType = PropertyType::FieldWithAccessor;
12209 }
12210#else
12211 *propType = PropertyType::Field;
12212#endif
12213 return propName;
12214 }
12215
12216 error(JSMSG_COLON_AFTER_ID);
12217 return errorResult();
12218}
12219
12220template <class ParseHandler, typename Unit>
12221typename ParseHandler::UnaryNodeResult
12222GeneralParser<ParseHandler, Unit>::computedPropertyName(
12223 YieldHandling yieldHandling, const Maybe<DeclarationKind>& maybeDecl,
12224 PropertyNameContext propertyNameContext, ListNodeType literal) {
12225 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12225); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 12225; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12226
12227 uint32_t begin = pos().begin;
12228
12229 if (maybeDecl) {
12230 if (*maybeDecl == DeclarationKind::FormalParameter) {
12231 pc_->functionBox()->hasParameterExprs = true;
12232 }
12233 } else if (propertyNameContext ==
12234 PropertyNameContext::PropertyNameInLiteral) {
12235 handler_.setListHasNonConstInitializer(literal);
12236 }
12237
12238 Node assignNode;
12239 MOZ_TRY_VAR(assignNode,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assignNode) = mozTryVarTempResult_.unwrap(); } while (0)
12240 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (assignNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
12241
12242 if (!mustMatchToken(TokenKind::RightBracket, JSMSG_COMP_PROP_UNTERM_EXPR)) {
12243 return errorResult();
12244 }
12245 return handler_.newComputedName(assignNode, begin, pos().end);
12246}
12247
12248template <class ParseHandler, typename Unit>
12249typename ParseHandler::ListNodeResult
12250GeneralParser<ParseHandler, Unit>::objectLiteral(YieldHandling yieldHandling,
12251 PossibleError* possibleError) {
12252 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12252); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 12252; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12253
12254 uint32_t openedPos = pos().begin;
12255
12256 ListNodeType literal;
12257 MOZ_TRY_VAR(literal, handler_.newObjectLiteral(pos().begin))do { auto mozTryVarTempResult_ = (handler_.newObjectLiteral(pos
().begin)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (literal
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12258
12259 bool seenPrototypeMutation = false;
12260 bool seenCoverInitializedName = false;
12261 Maybe<DeclarationKind> declKind = Nothing();
12262 TaggedParserAtomIndex propAtom;
12263 for (;;) {
12264 TokenKind tt;
12265 if (!tokenStream.peekToken(&tt)) {
12266 return errorResult();
12267 }
12268 if (tt == TokenKind::RightCurly) {
12269 break;
12270 }
12271
12272 if (tt == TokenKind::TripleDot) {
12273 tokenStream.consumeKnownToken(TokenKind::TripleDot);
12274 uint32_t begin = pos().begin;
12275
12276 TokenPos innerPos;
12277 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12278 return errorResult();
12279 }
12280
12281 PossibleError possibleErrorInner(*this);
12282 Node inner;
12283 MOZ_TRY_VAR(inner, assignExpr(InAllowed, yieldHandling,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
12284 TripledotProhibited, &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (inner) = mozTryVarTempResult_.unwrap(); }
while (0)
;
12285 if (!checkDestructuringAssignmentTarget(
12286 inner, innerPos, &possibleErrorInner, possibleError,
12287 TargetBehavior::ForbidAssignmentPattern)) {
12288 return errorResult();
12289 }
12290 if (!handler_.addSpreadProperty(literal, begin, inner)) {
12291 return errorResult();
12292 }
12293 } else {
12294 TokenPos namePos = anyChars.nextToken().pos;
12295
12296 PropertyType propType;
12297 Node propName;
12298 MOZ_TRY_VAR(propName, propertyOrMethodName(do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInLiteral, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12299 yieldHandling, PropertyNameInLiteral, declKind,do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInLiteral, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12300 literal, &propType, &propAtom))do { auto mozTryVarTempResult_ = (propertyOrMethodName( yieldHandling
, PropertyNameInLiteral, declKind, literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12301
12302 if (propType == PropertyType::Normal) {
12303 TokenPos exprPos;
12304 if (!tokenStream.peekTokenPos(&exprPos, TokenStream::SlashIsRegExp)) {
12305 return errorResult();
12306 }
12307
12308 PossibleError possibleErrorInner(*this);
12309 Node propExpr;
12310 MOZ_TRY_VAR(propExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
12311 assignExpr(InAllowed, yieldHandling, TripledotProhibited,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
12312 &possibleErrorInner))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited, &possibleErrorInner)); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (propExpr) = mozTryVarTempResult_.unwrap()
; } while (0)
;
12313
12314 if (!checkDestructuringAssignmentElement(
12315 propExpr, exprPos, &possibleErrorInner, possibleError)) {
12316 return errorResult();
12317 }
12318
12319 if (propAtom == TaggedParserAtomIndex::WellKnown::proto_()) {
12320 if (seenPrototypeMutation) {
12321 // Directly report the error when we're definitely not
12322 // in a destructuring context.
12323 if (!possibleError) {
12324 errorAt(namePos.begin, JSMSG_DUPLICATE_PROTO_PROPERTY);
12325 return errorResult();
12326 }
12327
12328 // Otherwise delay error reporting until we've
12329 // determined whether or not we're destructuring.
12330 possibleError->setPendingExpressionErrorAt(
12331 namePos, JSMSG_DUPLICATE_PROTO_PROPERTY);
12332 }
12333 seenPrototypeMutation = true;
12334
12335 // This occurs *only* if we observe PropertyType::Normal!
12336 // Only |__proto__: v| mutates [[Prototype]]. Getters,
12337 // setters, method/generator definitions, computed
12338 // property name versions of all of these, and shorthands
12339 // do not.
12340 if (!handler_.addPrototypeMutation(literal, namePos.begin,
12341 propExpr)) {
12342 return errorResult();
12343 }
12344 } else {
12345 BinaryNodeType propDef;
12346 MOZ_TRY_VAR(propDef,do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
12347 handler_.newPropertyDefinition(propName, propExpr))do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
;
12348
12349 handler_.addPropertyDefinition(literal, propDef);
12350 }
12351 } else if (propType == PropertyType::Shorthand) {
12352 /*
12353 * Support, e.g., |({x, y} = o)| as destructuring shorthand
12354 * for |({x: x, y: y} = o)|, and |var o = {x, y}| as
12355 * initializer shorthand for |var o = {x: x, y: y}|.
12356 */
12357 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12358 if (!name) {
12359 return errorResult();
12360 }
12361
12362 NameNodeType nameExpr;
12363 MOZ_TRY_VAR(nameExpr, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nameExpr) =
mozTryVarTempResult_.unwrap(); } while (0)
;
12364
12365 if (possibleError) {
12366 checkDestructuringAssignmentName(nameExpr, namePos, possibleError);
12367 }
12368
12369 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
12370 nameExpr)) {
12371 return errorResult();
12372 }
12373 } else if (propType == PropertyType::CoverInitializedName) {
12374 /*
12375 * Support, e.g., |({x=1, y=2} = o)| as destructuring
12376 * shorthand with default values, as per ES6 12.14.5
12377 */
12378 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12379 if (!name) {
12380 return errorResult();
12381 }
12382
12383 Node lhs;
12384 MOZ_TRY_VAR(lhs, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (lhs) = mozTryVarTempResult_
.unwrap(); } while (0)
;
12385
12386 tokenStream.consumeKnownToken(TokenKind::Assign);
12387
12388 if (!seenCoverInitializedName) {
12389 // "shorthand default" or "CoverInitializedName" syntax is
12390 // only valid in the case of destructuring.
12391 seenCoverInitializedName = true;
12392
12393 if (!possibleError) {
12394 // Destructuring defaults are definitely not allowed
12395 // in this object literal, because of something the
12396 // caller knows about the preceding code. For example,
12397 // maybe the preceding token is an operator:
12398 // |x + {y=z}|.
12399 error(JSMSG_COLON_AFTER_ID);
12400 return errorResult();
12401 }
12402
12403 // Here we set a pending error so that later in the parse,
12404 // once we've determined whether or not we're
12405 // destructuring, the error can be reported or ignored
12406 // appropriately.
12407 possibleError->setPendingExpressionErrorAt(pos(),
12408 JSMSG_COLON_AFTER_ID);
12409 }
12410
12411 if (const char* chars = nameIsArgumentsOrEval(lhs)) {
12412 // |chars| is "arguments" or "eval" here.
12413 if (!strictModeErrorAt(namePos.begin, JSMSG_BAD_STRICT_ASSIGN,
12414 chars)) {
12415 return errorResult();
12416 }
12417 }
12418
12419 if (handler_.isArgumentsLength(lhs)) {
12420 pc_->sc()->setIneligibleForArgumentsLength();
12421 }
12422
12423 Node rhs;
12424 MOZ_TRY_VAR(rhs,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
12425 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (rhs) = mozTryVarTempResult_.unwrap(); } while (0)
;
12426
12427 BinaryNodeType propExpr;
12428 MOZ_TRY_VAR(propExpr, handler_.newAssignment(ParseNodeKind::AssignExpr,do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
12429 lhs, rhs))do { auto mozTryVarTempResult_ = (handler_.newAssignment(ParseNodeKind
::AssignExpr, lhs, rhs)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
12430
12431 if (!handler_.addPropertyDefinition(literal, propName, propExpr)) {
12432 return errorResult();
12433 }
12434 } else {
12435 TaggedParserAtomIndex funName;
12436 bool hasStaticName =
12437 !anyChars.isCurrentTokenType(TokenKind::RightBracket) && propAtom;
12438 if (hasStaticName) {
12439 funName = propAtom;
12440
12441 if (propType == PropertyType::Getter ||
12442 propType == PropertyType::Setter) {
12443 funName = prefixAccessorName(propType, propAtom);
12444 if (!funName) {
12445 return errorResult();
12446 }
12447 }
12448 }
12449
12450 FunctionNodeType funNode;
12451 MOZ_TRY_VAR(funNode,do { auto mozTryVarTempResult_ = (methodDefinition(namePos.begin
, propType, funName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
12452 methodDefinition(namePos.begin, propType, funName))do { auto mozTryVarTempResult_ = (methodDefinition(namePos.begin
, propType, funName)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (funNode) = mozTryVarTempResult_.unwrap(); } while (0)
;
12453
12454 AccessorType atype = ToAccessorType(propType);
12455 if (!handler_.addObjectMethodDefinition(literal, propName, funNode,
12456 atype)) {
12457 return errorResult();
12458 }
12459
12460 if (possibleError) {
12461 possibleError->setPendingDestructuringErrorAt(
12462 namePos, JSMSG_BAD_DESTRUCT_TARGET);
12463 }
12464 }
12465 }
12466
12467 bool matched;
12468 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12469 TokenStream::SlashIsInvalid)) {
12470 return errorResult();
12471 }
12472 if (!matched) {
12473 break;
12474 }
12475 if (tt == TokenKind::TripleDot && possibleError) {
12476 possibleError->setPendingDestructuringErrorAt(pos(),
12477 JSMSG_REST_WITH_COMMA);
12478 }
12479 }
12480
12481 if (!mustMatchToken(
12482 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
12483 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
12484 JSMSG_CURLY_OPENED, openedPos);
12485 })) {
12486 return errorResult();
12487 }
12488
12489 handler_.setEndPosition(literal, pos().end);
12490 return literal;
12491}
12492
12493#ifdef ENABLE_RECORD_TUPLE
12494template <class ParseHandler, typename Unit>
12495typename ParseHandler::ListNodeResult
12496GeneralParser<ParseHandler, Unit>::recordLiteral(YieldHandling yieldHandling) {
12497 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::HashCurly))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::HashCurly))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::HashCurly))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::HashCurly)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12497); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::HashCurly)"
")"); do { *((volatile int*)__null) = 12497; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12498
12499 uint32_t openedPos = pos().begin;
12500
12501 ListNodeType literal;
12502 MOZ_TRY_VAR(literal, handler_.newRecordLiteral(pos().begin))do { auto mozTryVarTempResult_ = (handler_.newRecordLiteral(pos
().begin)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (literal
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12503
12504 TaggedParserAtomIndex propAtom;
12505 for (;;) {
12506 TokenKind tt;
12507 if (!tokenStream.peekToken(&tt)) {
12508 return errorResult();
12509 }
12510 if (tt == TokenKind::RightCurly) {
12511 break;
12512 }
12513
12514 if (tt == TokenKind::TripleDot) {
12515 tokenStream.consumeKnownToken(TokenKind::TripleDot);
12516 uint32_t begin = pos().begin;
12517
12518 TokenPos innerPos;
12519 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12520 return errorResult();
12521 }
12522
12523 Node inner;
12524 MOZ_TRY_VAR(inner,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
12525 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
;
12526
12527 if (!handler_.addSpreadProperty(literal, begin, inner)) {
12528 return errorResult();
12529 }
12530 } else {
12531 TokenPos namePos = anyChars.nextToken().pos;
12532
12533 PropertyType propType;
12534 Node propName;
12535 MOZ_TRY_VAR(propName,do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12536 propertyOrMethodName(yieldHandling, PropertyNameInRecord,do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12537 /* maybeDecl */ Nothing(), literal,do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
12538 &propType, &propAtom))do { auto mozTryVarTempResult_ = (propertyOrMethodName(yieldHandling
, PropertyNameInRecord, Nothing(), literal, &propType, &
propAtom)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (propName
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12539
12540 if (propType == PropertyType::Normal) {
12541 TokenPos exprPos;
12542 if (!tokenStream.peekTokenPos(&exprPos, TokenStream::SlashIsRegExp)) {
12543 return errorResult();
12544 }
12545
12546 Node propExpr;
12547 MOZ_TRY_VAR(propExpr,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
12548 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propExpr) = mozTryVarTempResult_.unwrap(); } while (0)
;
12549
12550 if (propAtom == TaggedParserAtomIndex::WellKnown::proto_()) {
12551 errorAt(namePos.begin, JSMSG_RECORD_NO_PROTO);
12552 return errorResult();
12553 }
12554
12555 BinaryNodeType propDef;
12556 MOZ_TRY_VAR(propDef,do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
12557 handler_.newPropertyDefinition(propName, propExpr))do { auto mozTryVarTempResult_ = (handler_.newPropertyDefinition
(propName, propExpr)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (propDef) = mozTryVarTempResult_.unwrap(); } while (0)
;
12558
12559 handler_.addPropertyDefinition(literal, propDef);
12560 } else if (propType == PropertyType::Shorthand) {
12561 /*
12562 * Support |var o = #{x, y}| as initializer shorthand for
12563 * |var o = #{x: x, y: y}|.
12564 */
12565 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12566 if (!name) {
12567 return errorResult();
12568 }
12569
12570 NameNodeType nameExpr;
12571 MOZ_TRY_VAR(nameExpr, identifierReference(name))do { auto mozTryVarTempResult_ = (identifierReference(name));
if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0)))
{ return mozTryVarTempResult_.propagateErr(); } (nameExpr) =
mozTryVarTempResult_.unwrap(); } while (0)
;
12572
12573 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
12574 nameExpr)) {
12575 return errorResult();
12576 }
12577 } else {
12578 error(JSMSG_BAD_PROP_ID);
12579 return errorResult();
12580 }
12581 }
12582
12583 bool matched;
12584 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12585 TokenStream::SlashIsInvalid)) {
12586 return errorResult();
12587 }
12588 if (!matched) {
12589 break;
12590 }
12591 }
12592
12593 if (!mustMatchToken(
12594 TokenKind::RightCurly, [this, openedPos](TokenKind actual) {
12595 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST,
12596 JSMSG_CURLY_OPENED, openedPos);
12597 })) {
12598 return errorResult();
12599 }
12600
12601 handler_.setEndPosition(literal, pos().end);
12602 return literal;
12603}
12604
12605template <class ParseHandler, typename Unit>
12606typename ParseHandler::ListNodeResult
12607GeneralParser<ParseHandler, Unit>::tupleLiteral(YieldHandling yieldHandling) {
12608 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::HashBracket))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::HashBracket))
>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::HashBracket))
)), 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::HashBracket)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12608); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::HashBracket)"
")"); do { *((volatile int*)__null) = 12608; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12609
12610 uint32_t begin = pos().begin;
12611 ListNodeType literal;
12612 MOZ_TRY_VAR(literal, handler_.newTupleLiteral(begin))do { auto mozTryVarTempResult_ = (handler_.newTupleLiteral(begin
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
12613
12614 for (uint32_t index = 0;; index++) {
12615 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
12616 error(JSMSG_ARRAY_INIT_TOO_BIG);
12617 return errorResult();
12618 }
12619
12620 TokenKind tt;
12621 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
12622 return errorResult();
12623 }
12624 if (tt == TokenKind::RightBracket) {
12625 break;
12626 }
12627
12628 if (tt == TokenKind::TripleDot) {
12629 tokenStream.consumeKnownToken(TokenKind::TripleDot,
12630 TokenStream::SlashIsRegExp);
12631 uint32_t begin = pos().begin;
12632
12633 TokenPos innerPos;
12634 if (!tokenStream.peekTokenPos(&innerPos, TokenStream::SlashIsRegExp)) {
12635 return errorResult();
12636 }
12637
12638 Node inner;
12639 MOZ_TRY_VAR(inner,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
12640 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (inner) = mozTryVarTempResult_.unwrap(); } while (0)
;
12641
12642 if (!handler_.addSpreadElement(literal, begin, inner)) {
12643 return errorResult();
12644 }
12645 } else {
12646 TokenPos elementPos;
12647 if (!tokenStream.peekTokenPos(&elementPos, TokenStream::SlashIsRegExp)) {
12648 return errorResult();
12649 }
12650
12651 Node element;
12652 MOZ_TRY_VAR(element,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (element) = mozTryVarTempResult_.unwrap(); } while (0)
12653 assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (element) = mozTryVarTempResult_.unwrap(); } while (0)
;
12654 handler_.addArrayElement(literal, element);
12655 }
12656
12657 bool matched;
12658 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
12659 TokenStream::SlashIsRegExp)) {
12660 return errorResult();
12661 }
12662 if (!matched) {
12663 break;
12664 }
12665 }
12666
12667 if (!mustMatchToken(TokenKind::RightBracket, [this, begin](TokenKind actual) {
12668 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
12669 JSMSG_BRACKET_OPENED, begin);
12670 })) {
12671 return errorResult();
12672 }
12673
12674 handler_.setEndPosition(literal, pos().end);
12675 return literal;
12676}
12677#endif
12678
12679template <class ParseHandler, typename Unit>
12680typename ParseHandler::FunctionNodeResult
12681GeneralParser<ParseHandler, Unit>::methodDefinition(
12682 uint32_t toStringStart, PropertyType propType,
12683 TaggedParserAtomIndex funName) {
12684 FunctionSyntaxKind syntaxKind;
12685 switch (propType) {
12686 case PropertyType::Getter:
12687 syntaxKind = FunctionSyntaxKind::Getter;
12688 break;
12689
12690 case PropertyType::Setter:
12691 syntaxKind = FunctionSyntaxKind::Setter;
12692 break;
12693
12694 case PropertyType::Method:
12695 case PropertyType::GeneratorMethod:
12696 case PropertyType::AsyncMethod:
12697 case PropertyType::AsyncGeneratorMethod:
12698 syntaxKind = FunctionSyntaxKind::Method;
12699 break;
12700
12701 case PropertyType::Constructor:
12702 syntaxKind = FunctionSyntaxKind::ClassConstructor;
12703 break;
12704
12705 case PropertyType::DerivedConstructor:
12706 syntaxKind = FunctionSyntaxKind::DerivedClassConstructor;
12707 break;
12708
12709 default:
12710 MOZ_CRASH("unexpected property type")do { do { } while (false); MOZ_ReportCrash("" "unexpected property type"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12710); AnnotateMozCrashReason("MOZ_CRASH(" "unexpected property type"
")"); do { *((volatile int*)__null) = 12710; __attribute__((
nomerge)) ::abort(); } while (false); } while (false)
;
12711 }
12712
12713 GeneratorKind generatorKind = (propType == PropertyType::GeneratorMethod ||
12714 propType == PropertyType::AsyncGeneratorMethod)
12715 ? GeneratorKind::Generator
12716 : GeneratorKind::NotGenerator;
12717
12718 FunctionAsyncKind asyncKind = (propType == PropertyType::AsyncMethod ||
12719 propType == PropertyType::AsyncGeneratorMethod)
12720 ? FunctionAsyncKind::AsyncFunction
12721 : FunctionAsyncKind::SyncFunction;
12722
12723 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
12724
12725 FunctionNodeType funNode;
12726 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12727
12728 return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
12729 funName, syntaxKind, generatorKind, asyncKind);
12730}
12731
12732template <class ParseHandler, typename Unit>
12733bool GeneralParser<ParseHandler, Unit>::tryNewTarget(
12734 NewTargetNodeType* newTarget) {
12735 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::New))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::New))>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(anyChars.isCurrentTokenType(TokenKind::New)))), 0))) { do {
} while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::New)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12735); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::New)"
")"); do { *((volatile int*)__null) = 12735; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12736
12737 *newTarget = null();
12738
12739 NullaryNodeType newHolder;
12740 MOZ_TRY_VAR_OR_RETURN(newHolder, handler_.newPosHolder(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newPosHolder(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (newHolder) = parserTryVarTempResult_
.unwrap(); } while (0)
;
12741
12742 uint32_t begin = pos().begin;
12743
12744 // |new| expects to look for an operand, so we will honor that.
12745 TokenKind next;
12746 if (!tokenStream.getToken(&next, TokenStream::SlashIsRegExp)) {
12747 return false;
12748 }
12749
12750 // Don't unget the token, since lookahead cannot handle someone calling
12751 // getToken() with a different modifier. Callers should inspect
12752 // currentToken().
12753 if (next != TokenKind::Dot) {
12754 return true;
12755 }
12756
12757 if (!tokenStream.getToken(&next)) {
12758 return false;
12759 }
12760 if (next != TokenKind::Target) {
12761 error(JSMSG_UNEXPECTED_TOKEN, "target", TokenKindToDesc(next));
12762 return false;
12763 }
12764
12765 if (!pc_->sc()->allowNewTarget()) {
12766 errorAt(begin, JSMSG_BAD_NEWTARGET);
12767 return false;
12768 }
12769
12770 NullaryNodeType targetHolder;
12771 MOZ_TRY_VAR_OR_RETURN(targetHolder, handler_.newPosHolder(pos()), false)do { auto parserTryVarTempResult_ = (handler_.newPosHolder(pos
())); if ((__builtin_expect(!!(parserTryVarTempResult_.isErr(
)), 0))) { return (false); } (targetHolder) = parserTryVarTempResult_
.unwrap(); } while (0)
;
12772
12773 NameNodeType newTargetName;
12774 MOZ_TRY_VAR_OR_RETURN(newTargetName, newNewTargetName(), false)do { auto parserTryVarTempResult_ = (newNewTargetName()); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (newTargetName) = parserTryVarTempResult_.
unwrap(); } while (0)
;
12775
12776 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (handler_.newNewTarget(newHolder
, targetHolder, newTargetName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*newTarget) = parserTryVarTempResult_
.unwrap(); } while (0)
12777 *newTarget, handler_.newNewTarget(newHolder, targetHolder, newTargetName),do { auto parserTryVarTempResult_ = (handler_.newNewTarget(newHolder
, targetHolder, newTargetName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*newTarget) = parserTryVarTempResult_
.unwrap(); } while (0)
12778 false)do { auto parserTryVarTempResult_ = (handler_.newNewTarget(newHolder
, targetHolder, newTargetName)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (*newTarget) = parserTryVarTempResult_
.unwrap(); } while (0)
;
12779
12780 return true;
12781}
12782
12783template <class ParseHandler, typename Unit>
12784typename ParseHandler::BinaryNodeResult
12785GeneralParser<ParseHandler, Unit>::importExpr(YieldHandling yieldHandling,
12786 bool allowCallSyntax) {
12787 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::Import))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::Import))>::
isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::Import)))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::Import)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12787); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 12787; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12788
12789 NullaryNodeType importHolder;
12790 MOZ_TRY_VAR(importHolder, handler_.newPosHolder(pos()))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (importHolder
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12791
12792 TokenKind next;
12793 if (!tokenStream.getToken(&next)) {
12794 return errorResult();
12795 }
12796
12797 if (next == TokenKind::Dot) {
12798 if (!tokenStream.getToken(&next)) {
12799 return errorResult();
12800 }
12801 if (next != TokenKind::Meta) {
12802 error(JSMSG_UNEXPECTED_TOKEN, "meta", TokenKindToDesc(next));
12803 return errorResult();
12804 }
12805
12806 if (parseGoal() != ParseGoal::Module) {
12807 errorAt(pos().begin, JSMSG_IMPORT_META_OUTSIDE_MODULE);
12808 return errorResult();
12809 }
12810
12811 NullaryNodeType metaHolder;
12812 MOZ_TRY_VAR(metaHolder, handler_.newPosHolder(pos()))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(pos()
)); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (metaHolder
) = mozTryVarTempResult_.unwrap(); } while (0)
;
12813
12814 return handler_.newImportMeta(importHolder, metaHolder);
12815 }
12816
12817 if (next == TokenKind::LeftParen && allowCallSyntax) {
12818 Node arg;
12819 MOZ_TRY_VAR(arg, assignExpr(InAllowed, yieldHandling, TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (arg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12820
12821 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12822 return errorResult();
12823 }
12824
12825 Node optionalArg;
12826 if (options().importAttributes()) {
12827 if (next == TokenKind::Comma) {
12828 tokenStream.consumeKnownToken(TokenKind::Comma,
12829 TokenStream::SlashIsRegExp);
12830
12831 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12832 return errorResult();
12833 }
12834
12835 if (next != TokenKind::RightParen) {
12836 MOZ_TRY_VAR(optionalArg, assignExpr(InAllowed, yieldHandling,do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12837 TripledotProhibited))do { auto mozTryVarTempResult_ = (assignExpr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12838
12839 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12840 return errorResult();
12841 }
12842
12843 if (next == TokenKind::Comma) {
12844 tokenStream.consumeKnownToken(TokenKind::Comma,
12845 TokenStream::SlashIsRegExp);
12846 }
12847 } else {
12848 MOZ_TRY_VAR(optionalArg,do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12849 handler_.newPosHolder(TokenPos(pos().end, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12850 }
12851 } else {
12852 MOZ_TRY_VAR(optionalArg,do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12853 handler_.newPosHolder(TokenPos(pos().end, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12854 }
12855 } else {
12856 MOZ_TRY_VAR(optionalArg,do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
12857 handler_.newPosHolder(TokenPos(pos().end, pos().end)))do { auto mozTryVarTempResult_ = (handler_.newPosHolder(TokenPos
(pos().end, pos().end))); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (optionalArg) = mozTryVarTempResult_.unwrap(); } while (0)
;
12858 }
12859
12860 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_ARGS)) {
12861 return errorResult();
12862 }
12863
12864 Node spec;
12865 MOZ_TRY_VAR(spec, handler_.newCallImportSpec(arg, optionalArg))do { auto mozTryVarTempResult_ = (handler_.newCallImportSpec(
arg, optionalArg)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (spec) = mozTryVarTempResult_.unwrap(); } while (0)
;
12866
12867 return handler_.newCallImport(importHolder, spec);
12868 }
12869
12870 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(next));
12871 return errorResult();
12872}
12873
12874template <class ParseHandler, typename Unit>
12875typename ParseHandler::NodeResult
12876GeneralParser<ParseHandler, Unit>::primaryExpr(
12877 YieldHandling yieldHandling, TripledotHandling tripledotHandling,
12878 TokenKind tt, PossibleError* possibleError, InvokedPrediction invoked) {
12879 MOZ_ASSERT(anyChars.isCurrentTokenType(tt))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(tt))>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(anyChars.isCurrentTokenType(
tt)))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("anyChars.isCurrentTokenType(tt)", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 12879); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 12879; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
12880 AutoCheckRecursionLimit recursion(this->fc_);
12881 if (!recursion.check(this->fc_)) {
12882 return errorResult();
12883 }
12884
12885 switch (tt) {
12886 case TokenKind::Function:
12887 return functionExpr(pos().begin, invoked,
12888 FunctionAsyncKind::SyncFunction);
12889
12890 case TokenKind::Class:
12891 return classDefinition(yieldHandling, ClassExpression, NameRequired);
12892
12893 case TokenKind::LeftBracket:
12894 return arrayInitializer(yieldHandling, possibleError);
12895
12896 case TokenKind::LeftCurly:
12897 return objectLiteral(yieldHandling, possibleError);
12898
12899#ifdef ENABLE_RECORD_TUPLE
12900 case TokenKind::HashCurly:
12901 return recordLiteral(yieldHandling);
12902
12903 case TokenKind::HashBracket:
12904 return tupleLiteral(yieldHandling);
12905#endif
12906
12907#ifdef ENABLE_DECORATORS
12908 case TokenKind::At:
12909 return classDefinition(yieldHandling, ClassExpression, NameRequired);
12910#endif
12911
12912 case TokenKind::LeftParen: {
12913 TokenKind next;
12914 if (!tokenStream.peekToken(&next, TokenStream::SlashIsRegExp)) {
12915 return errorResult();
12916 }
12917
12918 if (next == TokenKind::RightParen) {
12919 // Not valid expression syntax, but this is valid in an arrow function
12920 // with no params: `() => body`.
12921 tokenStream.consumeKnownToken(TokenKind::RightParen,
12922 TokenStream::SlashIsRegExp);
12923
12924 if (!tokenStream.peekToken(&next)) {
12925 return errorResult();
12926 }
12927 if (next != TokenKind::Arrow) {
12928 error(JSMSG_UNEXPECTED_TOKEN, "expression",
12929 TokenKindToDesc(TokenKind::RightParen));
12930 return errorResult();
12931 }
12932
12933 // Now just return something that will allow parsing to continue.
12934 // It doesn't matter what; when we reach the =>, we will rewind and
12935 // reparse the whole arrow function. See Parser::assignExpr.
12936 return handler_.newNullLiteral(pos());
12937 }
12938
12939 // Pass |possibleError| to support destructuring in arrow parameters.
12940 Node expr;
12941 MOZ_TRY_VAR(expr, exprInParens(InAllowed, yieldHandling, TripledotAllowed,do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, possibleError)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
12942 possibleError))do { auto mozTryVarTempResult_ = (exprInParens(InAllowed, yieldHandling
, TripledotAllowed, possibleError)); if ((__builtin_expect(!!
(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (expr) = mozTryVarTempResult_.unwrap(); } while
(0)
;
12943 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_IN_PAREN)) {
12944 return errorResult();
12945 }
12946 return handler_.parenthesize(expr);
12947 }
12948
12949 case TokenKind::TemplateHead:
12950 return templateLiteral(yieldHandling);
12951
12952 case TokenKind::NoSubsTemplate:
12953 return noSubstitutionUntaggedTemplate();
12954
12955 case TokenKind::String:
12956 return stringLiteral();
12957
12958 default: {
12959 if (!TokenKindIsPossibleIdentifier(tt)) {
12960 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
12961 return errorResult();
12962 }
12963
12964 if (tt == TokenKind::Async) {
12965 TokenKind nextSameLine = TokenKind::Eof;
12966 if (!tokenStream.peekTokenSameLine(&nextSameLine)) {
12967 return errorResult();
12968 }
12969
12970 if (nextSameLine == TokenKind::Function) {
12971 uint32_t toStringStart = pos().begin;
12972 tokenStream.consumeKnownToken(TokenKind::Function);
12973 return functionExpr(toStringStart, PredictUninvoked,
12974 FunctionAsyncKind::AsyncFunction);
12975 }
12976 }
12977
12978 TaggedParserAtomIndex name = identifierReference(yieldHandling);
12979 if (!name) {
12980 return errorResult();
12981 }
12982
12983 return identifierReference(name);
12984 }
12985
12986 case TokenKind::RegExp:
12987 return newRegExp();
12988
12989 case TokenKind::Number:
12990 return newNumber(anyChars.currentToken());
12991
12992 case TokenKind::BigInt:
12993 return newBigInt();
12994
12995 case TokenKind::True:
12996 return handler_.newBooleanLiteral(true, pos());
12997 case TokenKind::False:
12998 return handler_.newBooleanLiteral(false, pos());
12999 case TokenKind::This: {
13000 NameNodeType thisName = null();
13001 if (pc_->sc()->hasFunctionThisBinding()) {
13002 MOZ_TRY_VAR(thisName, newThisName())do { auto mozTryVarTempResult_ = (newThisName()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (thisName) = mozTryVarTempResult_.unwrap()
; } while (0)
;
13003 }
13004 return handler_.newThisLiteral(pos(), thisName);
13005 }
13006 case TokenKind::Null:
13007 return handler_.newNullLiteral(pos());
13008
13009 case TokenKind::TripleDot: {
13010 // This isn't valid expression syntax, but it's valid in an arrow
13011 // function as a trailing rest param: `(a, b, ...rest) => body`. Check
13012 // if it's directly under
13013 // CoverParenthesizedExpressionAndArrowParameterList, and check for a
13014 // name, closing parenthesis, and arrow, and allow it only if all are
13015 // present.
13016 if (tripledotHandling != TripledotAllowed) {
13017 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
13018 return errorResult();
13019 }
13020
13021 TokenKind next;
13022 if (!tokenStream.getToken(&next)) {
13023 return errorResult();
13024 }
13025
13026 if (next == TokenKind::LeftBracket || next == TokenKind::LeftCurly) {
13027 // Validate, but don't store the pattern right now. The whole arrow
13028 // function is reparsed in functionFormalParametersAndBody().
13029 MOZ_TRY(destructuringDeclaration(DeclarationKind::CoverArrowParameter,do { auto mozTryTempResult_ = ::mozilla::ToResult(destructuringDeclaration
(DeclarationKind::CoverArrowParameter, yieldHandling, next));
if ((__builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return
mozTryTempResult_.propagateErr(); } } while (0)
13030 yieldHandling, next))do { auto mozTryTempResult_ = ::mozilla::ToResult(destructuringDeclaration
(DeclarationKind::CoverArrowParameter, yieldHandling, next));
if ((__builtin_expect(!!(mozTryTempResult_.isErr()), 0))) { return
mozTryTempResult_.propagateErr(); } } while (0)
;
13031 } else {
13032 // This doesn't check that the provided name is allowed, e.g. if
13033 // the enclosing code is strict mode code, any of "let", "yield",
13034 // or "arguments" should be prohibited. Argument-parsing code
13035 // handles that.
13036 if (!TokenKindIsPossibleIdentifier(next)) {
13037 error(JSMSG_UNEXPECTED_TOKEN, "rest argument name",
13038 TokenKindToDesc(next));
13039 return errorResult();
13040 }
13041 }
13042
13043 if (!tokenStream.getToken(&next)) {
13044 return errorResult();
13045 }
13046 if (next != TokenKind::RightParen) {
13047 error(JSMSG_UNEXPECTED_TOKEN, "closing parenthesis",
13048 TokenKindToDesc(next));
13049 return errorResult();
13050 }
13051
13052 if (!tokenStream.peekToken(&next)) {
13053 return errorResult();
13054 }
13055 if (next != TokenKind::Arrow) {
13056 // Advance the scanner for proper error location reporting.
13057 tokenStream.consumeKnownToken(next);
13058 error(JSMSG_UNEXPECTED_TOKEN, "'=>' after argument list",
13059 TokenKindToDesc(next));
13060 return errorResult();
13061 }
13062
13063 anyChars.ungetToken(); // put back right paren
13064
13065 // Return an arbitrary expression node. See case TokenKind::RightParen
13066 // above.
13067 return handler_.newNullLiteral(pos());
13068 }
13069 }
13070}
13071
13072template <class ParseHandler, typename Unit>
13073typename ParseHandler::NodeResult
13074GeneralParser<ParseHandler, Unit>::exprInParens(
13075 InHandling inHandling, YieldHandling yieldHandling,
13076 TripledotHandling tripledotHandling,
13077 PossibleError* possibleError /* = nullptr */) {
13078 MOZ_ASSERT(anyChars.isCurrentTokenType(TokenKind::LeftParen))do { static_assert( mozilla::detail::AssertionConditionType<
decltype(anyChars.isCurrentTokenType(TokenKind::LeftParen))>
::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(anyChars.isCurrentTokenType(TokenKind::LeftParen))))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("anyChars.isCurrentTokenType(TokenKind::LeftParen)"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 13078); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftParen)"
")"); do { *((volatile int*)__null) = 13078; __attribute__((
nomerge)) ::abort(); } while (false); } } while (false)
;
13079 return expr(inHandling, yieldHandling, tripledotHandling, possibleError,
13080 PredictInvoked);
13081}
13082
13083template class PerHandlerParser<FullParseHandler>;
13084template class PerHandlerParser<SyntaxParseHandler>;
13085template class GeneralParser<FullParseHandler, Utf8Unit>;
13086template class GeneralParser<SyntaxParseHandler, Utf8Unit>;
13087template class GeneralParser<FullParseHandler, char16_t>;
13088template class GeneralParser<SyntaxParseHandler, char16_t>;
13089template class Parser<FullParseHandler, Utf8Unit>;
13090template class Parser<SyntaxParseHandler, Utf8Unit>;
13091template class Parser<FullParseHandler, char16_t>;
13092template class Parser<SyntaxParseHandler, char16_t>;
13093
13094} // namespace js::frontend

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

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