Bug Summary

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

Annotated Source Code

Press '?' to see keyboard shortcuts

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

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

1/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7/*
8 * JS parser.
9 *
10 * This is a recursive-descent parser for the JavaScript language specified by
11 * "The ECMAScript Language Specification" (Standard ECMA-262). It uses
12 * lexical and semantic feedback to disambiguate non-LL(1) structures. It
13 * generates trees of nodes induced by the recursive parsing (not precise
14 * syntax trees, see Parser.h). After tree construction, it rewrites trees to
15 * fold constants and evaluate compile-time expressions.
16 *
17 * This parser attempts no error recovery.
18 */
19
20#include "frontend/Parser.h"
21
22#include "mozilla/ArrayUtils.h"
23#include "mozilla/Assertions.h"
24#include "mozilla/Casting.h"
25#include "mozilla/Range.h"
26#include "mozilla/Sprintf.h"
27#include "mozilla/Try.h" // MOZ_TRY*
28#include "mozilla/Utf8.h"
29#include "mozilla/Variant.h"
30
31#include <memory>
32#include <new>
33#include <type_traits>
34
35#include "jsnum.h"
36#include "jstypes.h"
37
38#include "frontend/FoldConstants.h"
39#include "frontend/FunctionSyntaxKind.h" // FunctionSyntaxKind
40#include "frontend/ModuleSharedContext.h"
41#include "frontend/ParseNode.h"
42#include "frontend/ParseNodeVerify.h"
43#include "frontend/Parser-macros.h" // MOZ_TRY_VAR_OR_RETURN
44#include "frontend/ParserAtom.h" // TaggedParserAtomIndex, ParserAtomsTable, ParserAtom
45#include "frontend/ScriptIndex.h" // ScriptIndex
46#include "frontend/TokenStream.h" // IsKeyword, ReservedWordTokenKind, ReservedWordToCharZ, DeprecatedContent, *TokenStream*, CharBuffer, TokenKindToDesc
47#include "irregexp/RegExpAPI.h"
48#include "js/ColumnNumber.h" // JS::LimitedColumnNumberOneOrigin, JS::ColumnNumberOneOrigin
49#include "js/ErrorReport.h" // JSErrorBase
50#include "js/friend/ErrorMessages.h" // js::GetErrorMessage, JSMSG_*
51#include "js/HashTable.h"
52#include "js/RegExpFlags.h" // JS::RegExpFlags
53#include "js/Stack.h" // JS::NativeStackLimit
54#include "util/StringBuffer.h" // StringBuffer
55#include "vm/BytecodeUtil.h"
56#include "vm/FunctionFlags.h" // js::FunctionFlags
57#include "vm/GeneratorAndAsyncKind.h" // js::GeneratorKind, js::FunctionAsyncKind
58#include "vm/JSContext.h"
59#include "vm/JSScript.h"
60#include "vm/ModuleBuilder.h" // js::ModuleBuilder
61#include "vm/Scope.h" // GetScopeDataTrailingNames
62#include "wasm/AsmJS.h"
63
64#include "frontend/ParseContext-inl.h"
65#include "frontend/SharedContext-inl.h"
66
67using namespace js;
68
69using mozilla::AssertedCast;
70using mozilla::AsVariant;
71using mozilla::Maybe;
72using mozilla::Nothing;
73using mozilla::PointerRangeSize;
74using mozilla::Some;
75using mozilla::Utf8Unit;
76
77using JS::ReadOnlyCompileOptions;
78using JS::RegExpFlags;
79
80namespace js::frontend {
81
82using DeclaredNamePtr = ParseContext::Scope::DeclaredNamePtr;
83using AddDeclaredNamePtr = ParseContext::Scope::AddDeclaredNamePtr;
84using BindingIter = ParseContext::Scope::BindingIter;
85using UsedNamePtr = UsedNameTracker::UsedNameMap::Ptr;
86
87using ParserBindingNameVector = Vector<ParserBindingName, 6>;
88
89static inline void PropagateTransitiveParseFlags(const FunctionBox* inner,
90 SharedContext* outer) {
91 if (inner->bindingsAccessedDynamically()) {
92 outer->setBindingsAccessedDynamically();
93 }
94 if (inner->hasDirectEval()) {
95 outer->setHasDirectEval();
96 }
97}
98
99static bool StatementKindIsBraced(StatementKind kind) {
100 return kind == StatementKind::Block || kind == StatementKind::Switch ||
101 kind == StatementKind::Try || kind == StatementKind::Catch ||
102 kind == StatementKind::Finally;
103}
104
105template <class ParseHandler, typename Unit>
106inline typename GeneralParser<ParseHandler, Unit>::FinalParser*
107GeneralParser<ParseHandler, Unit>::asFinalParser() {
108 static_assert(
109 std::is_base_of_v<GeneralParser<ParseHandler, Unit>, FinalParser>,
110 "inheritance relationship required by the static_cast<> below");
111
112 return static_cast<FinalParser*>(this);
113}
114
115template <class ParseHandler, typename Unit>
116inline const typename GeneralParser<ParseHandler, Unit>::FinalParser*
117GeneralParser<ParseHandler, Unit>::asFinalParser() const {
118 static_assert(
119 std::is_base_of_v<GeneralParser<ParseHandler, Unit>, FinalParser>,
120 "inheritance relationship required by the static_cast<> below");
121
122 return static_cast<const FinalParser*>(this);
123}
124
125template <class ParseHandler, typename Unit>
126template <typename ConditionT, typename ErrorReportT>
127bool GeneralParser<ParseHandler, Unit>::mustMatchTokenInternal(
128 ConditionT condition, ErrorReportT errorReport) {
129 MOZ_ASSERT(condition(TokenKind::Div) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::Div) == false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(condition(TokenKind::Div) ==
false))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("condition(TokenKind::Div) == false", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::Div) == false"
")"); do { *((volatile int*)__null) = 129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
130 MOZ_ASSERT(condition(TokenKind::DivAssign) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::DivAssign) == false)>::isValid
, "invalid assertion condition"); if ((__builtin_expect(!!(!(
!!(condition(TokenKind::DivAssign) == false))), 0))) { do { }
while (false); MOZ_ReportAssertionFailure("condition(TokenKind::DivAssign) == false"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 130); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::DivAssign) == false"
")"); do { *((volatile int*)__null) = 130; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
131 MOZ_ASSERT(condition(TokenKind::RegExp) == false)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(condition(TokenKind::RegExp) == false)>::isValid,
"invalid assertion condition"); if ((__builtin_expect(!!(!(!
!(condition(TokenKind::RegExp) == false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("condition(TokenKind::RegExp) == false"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 131); AnnotateMozCrashReason("MOZ_ASSERT" "(" "condition(TokenKind::RegExp) == false"
")"); do { *((volatile int*)__null) = 131; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
132
133 TokenKind actual;
134 if (!tokenStream.getToken(&actual, TokenStream::SlashIsInvalid)) {
135 return false;
136 }
137 if (!condition(actual)) {
138 errorReport(actual);
139 return false;
140 }
141 return true;
142}
143
144ParserSharedBase::ParserSharedBase(FrontendContext* fc,
145 CompilationState& compilationState,
146 Kind kind)
147 : fc_(fc),
148 alloc_(compilationState.parserAllocScope.alloc()),
149 compilationState_(compilationState),
150 pc_(nullptr),
151 usedNames_(compilationState.usedNames) {
152 fc_->nameCollectionPool().addActiveCompilation();
153}
154
155ParserSharedBase::~ParserSharedBase() {
156 fc_->nameCollectionPool().removeActiveCompilation();
157}
158
159#if defined(DEBUG1) || defined(JS_JITSPEW1)
160void ParserSharedBase::dumpAtom(TaggedParserAtomIndex index) const {
161 parserAtoms().dump(index);
162}
163#endif
164
165ParserBase::ParserBase(FrontendContext* fc,
166 const ReadOnlyCompileOptions& options,
167 bool foldConstants, CompilationState& compilationState)
168 : ParserSharedBase(fc, compilationState, ParserSharedBase::Kind::Parser),
169 anyChars(fc, options, this),
170 ss(nullptr),
171 foldConstants_(foldConstants),
172#ifdef DEBUG1
173 checkOptionsCalled_(false),
174#endif
175 isUnexpectedEOF_(false),
176 awaitHandling_(AwaitIsName),
177 inParametersOfAsyncFunction_(false) {
178}
179
180bool ParserBase::checkOptions() {
181#ifdef DEBUG1
182 checkOptionsCalled_ = true;
183#endif
184
185 return anyChars.checkOptions();
186}
187
188ParserBase::~ParserBase() { MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 188); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 188; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
; }
189
190JSAtom* ParserBase::liftParserAtomToJSAtom(TaggedParserAtomIndex index) {
191 JSContext* cx = fc_->maybeCurrentJSContext();
192 MOZ_ASSERT(cx)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(cx)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(cx))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("cx", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 192); AnnotateMozCrashReason("MOZ_ASSERT" "(" "cx" ")"); do
{ *((volatile int*)__null) = 192; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
193 return parserAtoms().toJSAtom(cx, fc_, index,
194 compilationState_.input.atomCache);
195}
196
197template <class ParseHandler>
198PerHandlerParser<ParseHandler>::PerHandlerParser(
199 FrontendContext* fc, const ReadOnlyCompileOptions& options,
200 bool foldConstants, CompilationState& compilationState,
201 void* internalSyntaxParser)
202 : ParserBase(fc, options, foldConstants, compilationState),
203 handler_(fc, compilationState),
204 internalSyntaxParser_(internalSyntaxParser) {
205 MOZ_ASSERT(compilationState.isInitialStencil() ==do { static_assert( mozilla::detail::AssertionConditionType<
decltype(compilationState.isInitialStencil() == compilationState
.input.isInitialStencil())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(compilationState.isInitialStencil
() == compilationState.input.isInitialStencil()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 206); AnnotateMozCrashReason("MOZ_ASSERT" "(" "compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
")"); do { *((volatile int*)__null) = 206; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
206 compilationState.input.isInitialStencil())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(compilationState.isInitialStencil() == compilationState
.input.isInitialStencil())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(compilationState.isInitialStencil
() == compilationState.input.isInitialStencil()))), 0))) { do
{ } while (false); MOZ_ReportAssertionFailure("compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 206); AnnotateMozCrashReason("MOZ_ASSERT" "(" "compilationState.isInitialStencil() == compilationState.input.isInitialStencil()"
")"); do { *((volatile int*)__null) = 206; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
207}
208
209template <class ParseHandler, typename Unit>
210GeneralParser<ParseHandler, Unit>::GeneralParser(
211 FrontendContext* fc, const ReadOnlyCompileOptions& options,
212 const Unit* units, size_t length, bool foldConstants,
213 CompilationState& compilationState, SyntaxParser* syntaxParser)
214 : Base(fc, options, foldConstants, compilationState, syntaxParser),
215 tokenStream(fc, &compilationState.parserAtoms, options, units, length) {}
216
217template <typename Unit>
218void Parser<SyntaxParseHandler, Unit>::setAwaitHandling(
219 AwaitHandling awaitHandling) {
220 this->awaitHandling_ = awaitHandling;
221}
222
223template <typename Unit>
224void Parser<FullParseHandler, Unit>::setAwaitHandling(
225 AwaitHandling awaitHandling) {
226 this->awaitHandling_ = awaitHandling;
227 if (SyntaxParser* syntaxParser = getSyntaxParser()) {
228 syntaxParser->setAwaitHandling(awaitHandling);
229 }
230}
231
232template <class ParseHandler, typename Unit>
233inline void GeneralParser<ParseHandler, Unit>::setAwaitHandling(
234 AwaitHandling awaitHandling) {
235 asFinalParser()->setAwaitHandling(awaitHandling);
236}
237
238template <typename Unit>
239void Parser<SyntaxParseHandler, Unit>::setInParametersOfAsyncFunction(
240 bool inParameters) {
241 this->inParametersOfAsyncFunction_ = inParameters;
242}
243
244template <typename Unit>
245void Parser<FullParseHandler, Unit>::setInParametersOfAsyncFunction(
246 bool inParameters) {
247 this->inParametersOfAsyncFunction_ = inParameters;
248 if (SyntaxParser* syntaxParser = getSyntaxParser()) {
249 syntaxParser->setInParametersOfAsyncFunction(inParameters);
250 }
251}
252
253template <class ParseHandler, typename Unit>
254inline void GeneralParser<ParseHandler, Unit>::setInParametersOfAsyncFunction(
255 bool inParameters) {
256 asFinalParser()->setInParametersOfAsyncFunction(inParameters);
257}
258
259template <class ParseHandler>
260FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
261 FunctionNodeType funNode, TaggedParserAtomIndex explicitName,
262 FunctionFlags flags, uint32_t toStringStart, Directives inheritedDirectives,
263 GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
264 MOZ_ASSERT(funNode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funNode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funNode))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("funNode", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 264); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funNode" ")"
); do { *((volatile int*)__null) = 264; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
265
266 ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
267 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
268 ReportAllocationOverflow(fc_);
269 return nullptr;
270 }
271 if (!compilationState_.appendScriptStencilAndData(fc_)) {
272 return nullptr;
273 }
274
275 bool isInitialStencil = compilationState_.isInitialStencil();
276
277 // This source extent will be further filled in during the remainder of parse.
278 SourceExtent extent;
279 extent.toStringStart = toStringStart;
280
281 FunctionBox* funbox = alloc_.new_<FunctionBox>(
282 fc_, extent, compilationState_, inheritedDirectives, generatorKind,
283 asyncKind, isInitialStencil, explicitName, flags, index);
284 if (!funbox) {
285 ReportOutOfMemory(fc_);
286 return nullptr;
287 }
288
289 handler_.setFunctionBox(funNode, funbox);
290
291 return funbox;
292}
293
294template <class ParseHandler>
295FunctionBox* PerHandlerParser<ParseHandler>::newFunctionBox(
296 FunctionNodeType funNode, const ScriptStencil& cachedScriptData,
297 const ScriptStencilExtra& cachedScriptExtra) {
298 MOZ_ASSERT(funNode)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(funNode)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(funNode))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("funNode", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 298); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funNode" ")"
); do { *((volatile int*)__null) = 298; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
299
300 ScriptIndex index = ScriptIndex(compilationState_.scriptData.length());
301 if (uint32_t(index) >= TaggedScriptThingIndex::IndexLimit) {
302 ReportAllocationOverflow(fc_);
303 return nullptr;
304 }
305 if (!compilationState_.appendScriptStencilAndData(fc_)) {
306 return nullptr;
307 }
308
309 FunctionBox* funbox = alloc_.new_<FunctionBox>(
310 fc_, cachedScriptExtra.extent, compilationState_,
311 Directives(/* strict = */ false), cachedScriptExtra.generatorKind(),
312 cachedScriptExtra.asyncKind(), compilationState_.isInitialStencil(),
313 cachedScriptData.functionAtom, cachedScriptData.functionFlags, index);
314 if (!funbox) {
315 ReportOutOfMemory(fc_);
316 return nullptr;
317 }
318
319 handler_.setFunctionBox(funNode, funbox);
320 funbox->initFromScriptStencilExtra(cachedScriptExtra);
321
322 return funbox;
323}
324
325bool ParserBase::setSourceMapInfo() {
326 // If support for source pragmas have been fully disabled, we can skip
327 // processing of all of these values.
328 if (!options().sourcePragmas()) {
329 return true;
330 }
331
332 // Not all clients initialize ss. Can't update info to an object that isn't
333 // there.
334 if (!ss) {
335 return true;
336 }
337
338 if (anyChars.hasDisplayURL()) {
339 if (!ss->setDisplayURL(fc_, anyChars.displayURL())) {
340 return false;
341 }
342 }
343
344 if (anyChars.hasSourceMapURL()) {
345 MOZ_ASSERT(!ss->hasSourceMapURL())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(!ss->hasSourceMapURL())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(!ss->hasSourceMapURL())))
, 0))) { do { } while (false); MOZ_ReportAssertionFailure("!ss->hasSourceMapURL()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 345); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!ss->hasSourceMapURL()"
")"); do { *((volatile int*)__null) = 345; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
346 if (!ss->setSourceMapURL(fc_, anyChars.sourceMapURL())) {
347 return false;
348 }
349 }
350
351 /*
352 * Source map URLs passed as a compile option (usually via a HTTP source map
353 * header) override any source map urls passed as comment pragmas.
354 */
355 if (options().sourceMapURL()) {
356 // Warn about the replacement, but use the new one.
357 if (ss->hasSourceMapURL()) {
358 if (!warningNoOffset(JSMSG_ALREADY_HAS_PRAGMA, ss->filename(),
359 "//# sourceMappingURL")) {
360 return false;
361 }
362 }
363
364 if (!ss->setSourceMapURL(fc_, options().sourceMapURL())) {
365 return false;
366 }
367 }
368
369 return true;
370}
371
372/*
373 * Parse a top-level JS script.
374 */
375template <class ParseHandler, typename Unit>
376typename ParseHandler::ListNodeResult
377GeneralParser<ParseHandler, Unit>::parse() {
378 MOZ_ASSERT(checkOptionsCalled_)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(checkOptionsCalled_)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(checkOptionsCalled_))), 0)))
{ do { } while (false); MOZ_ReportAssertionFailure("checkOptionsCalled_"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 378); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 378; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
379
380 SourceExtent extent = SourceExtent::makeGlobalExtent(
381 /* len = */ 0, options().lineno,
382 JS::LimitedColumnNumberOneOrigin::fromUnlimited(
383 JS::ColumnNumberOneOrigin(options().column)));
384 Directives directives(options().forceStrictMode());
385 GlobalSharedContext globalsc(this->fc_, ScopeKind::Global, options(),
386 directives, extent);
387 SourceParseContext globalpc(this, &globalsc, /* newDirectives = */ nullptr);
388 if (!globalpc.init()) {
389 return errorResult();
390 }
391
392 ParseContext::VarScope varScope(this);
393 if (!varScope.init(pc_)) {
394 return errorResult();
395 }
396
397 ListNodeType stmtList;
398 MOZ_TRY_VAR(stmtList, statementList(YieldIsName))do { auto mozTryVarTempResult_ = (statementList(YieldIsName))
; if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))
) { return mozTryVarTempResult_.propagateErr(); } (stmtList) =
mozTryVarTempResult_.unwrap(); } while (0)
;
399
400 TokenKind tt;
401 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
402 return errorResult();
403 }
404 if (tt != TokenKind::Eof) {
405 error(JSMSG_GARBAGE_AFTER_INPUT, "script", TokenKindToDesc(tt));
406 return errorResult();
407 }
408
409 if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
410 return errorResult();
411 }
412
413 if (foldConstants_) {
414 Node node = stmtList;
415 // Don't constant-fold inside "use asm" code, as this could create a parse
416 // tree that doesn't type-check as asm.js.
417 if (!pc_->useAsmOrInsideUseAsm()) {
418 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
419 return errorResult();
420 }
421 }
422 stmtList = handler_.asListNode(node);
423 }
424
425 return stmtList;
426}
427
428/*
429 * Strict mode forbids introducing new definitions for 'eval', 'arguments',
430 * 'let', 'static', 'yield', or for any strict mode reserved word.
431 */
432bool ParserBase::isValidStrictBinding(TaggedParserAtomIndex name) {
433 TokenKind tt = ReservedWordTokenKind(name);
434 if (tt == TokenKind::Limit) {
435 return name != TaggedParserAtomIndex::WellKnown::eval() &&
436 name != TaggedParserAtomIndex::WellKnown::arguments();
437 }
438 return tt != TokenKind::Let && tt != TokenKind::Static &&
439 tt != TokenKind::Yield && !TokenKindIsStrictReservedWord(tt);
440}
441
442/*
443 * Returns true if all parameter names are valid strict mode binding names and
444 * no duplicate parameter names are present.
445 */
446bool ParserBase::hasValidSimpleStrictParameterNames() {
447 MOZ_ASSERT(pc_->isFunctionBox() &&do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox() && pc_->functionBox
()->hasSimpleParameterList())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox() &&
pc_->functionBox()->hasSimpleParameterList()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
")"); do { *((volatile int*)__null) = 448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
448 pc_->functionBox()->hasSimpleParameterList())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->isFunctionBox() && pc_->functionBox
()->hasSimpleParameterList())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->isFunctionBox() &&
pc_->functionBox()->hasSimpleParameterList()))), 0))) {
do { } while (false); MOZ_ReportAssertionFailure("pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 448); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox() && pc_->functionBox()->hasSimpleParameterList()"
")"); do { *((volatile int*)__null) = 448; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
449
450 if (pc_->functionBox()->hasDuplicateParameters) {
451 return false;
452 }
453
454 for (auto name : pc_->positionalFormalParameterNames()) {
455 MOZ_ASSERT(name)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(name)>::isValid, "invalid assertion condition"); if
((__builtin_expect(!!(!(!!(name))), 0))) { do { } while (false
); MOZ_ReportAssertionFailure("name", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 455); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name" ")"); do
{ *((volatile int*)__null) = 455; __attribute__((nomerge)) ::
abort(); } while (false); } } while (false)
;
456 if (!isValidStrictBinding(name)) {
457 return false;
458 }
459 }
460 return true;
461}
462
463template <class ParseHandler, typename Unit>
464void GeneralParser<ParseHandler, Unit>::reportMissingClosing(
465 unsigned errorNumber, unsigned noteNumber, uint32_t openedPos) {
466 auto notes = MakeUnique<JSErrorNotes>();
467 if (!notes) {
468 ReportOutOfMemory(this->fc_);
469 return;
470 }
471
472 uint32_t line;
473 JS::LimitedColumnNumberOneOrigin column;
474 tokenStream.computeLineAndColumn(openedPos, &line, &column);
475
476 const size_t MaxWidth = sizeof("4294967295");
477 char columnNumber[MaxWidth];
478 SprintfLiteral(columnNumber, "%" PRIu32"u", column.oneOriginValue());
479 char lineNumber[MaxWidth];
480 SprintfLiteral(lineNumber, "%" PRIu32"u", line);
481
482 if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
483 JS::ColumnNumberOneOrigin(column), GetErrorMessage,
484 nullptr, noteNumber, lineNumber, columnNumber)) {
485 return;
486 }
487
488 errorWithNotes(std::move(notes), errorNumber);
489}
490
491template <class ParseHandler, typename Unit>
492void GeneralParser<ParseHandler, Unit>::reportRedeclarationHelper(
493 TaggedParserAtomIndex& name, DeclarationKind& prevKind, TokenPos& pos,
494 uint32_t& prevPos, const unsigned& errorNumber,
495 const unsigned& noteErrorNumber) {
496 UniqueChars bytes = this->parserAtoms().toPrintableString(name);
497 if (!bytes) {
498 ReportOutOfMemory(this->fc_);
499 return;
500 }
501
502 if (prevPos == DeclaredNameInfo::npos) {
503 errorAt(pos.begin, errorNumber, DeclarationKindString(prevKind),
504 bytes.get());
505 return;
506 }
507
508 auto notes = MakeUnique<JSErrorNotes>();
509 if (!notes) {
510 ReportOutOfMemory(this->fc_);
511 return;
512 }
513
514 uint32_t line;
515 JS::LimitedColumnNumberOneOrigin column;
516 tokenStream.computeLineAndColumn(prevPos, &line, &column);
517
518 const size_t MaxWidth = sizeof("4294967295");
519 char columnNumber[MaxWidth];
520 SprintfLiteral(columnNumber, "%" PRIu32"u", column.oneOriginValue());
521 char lineNumber[MaxWidth];
522 SprintfLiteral(lineNumber, "%" PRIu32"u", line);
523
524 if (!notes->addNoteASCII(this->fc_, getFilename().c_str(), 0, line,
525 JS::ColumnNumberOneOrigin(column), GetErrorMessage,
526 nullptr, noteErrorNumber, lineNumber,
527 columnNumber)) {
528 return;
529 }
530
531 errorWithNotesAt(std::move(notes), pos.begin, errorNumber,
532 DeclarationKindString(prevKind), bytes.get());
533}
534
535template <class ParseHandler, typename Unit>
536void GeneralParser<ParseHandler, Unit>::reportRedeclaration(
537 TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
538 uint32_t prevPos) {
539 reportRedeclarationHelper(name, prevKind, pos, prevPos, JSMSG_REDECLARED_VAR,
540 JSMSG_PREV_DECLARATION);
541}
542
543template <class ParseHandler, typename Unit>
544void GeneralParser<ParseHandler, Unit>::reportMismatchedPlacement(
545 TaggedParserAtomIndex name, DeclarationKind prevKind, TokenPos pos,
546 uint32_t prevPos) {
547 reportRedeclarationHelper(name, prevKind, pos, prevPos,
548 JSMSG_MISMATCHED_PLACEMENT, JSMSG_PREV_DECLARATION);
549}
550
551// notePositionalFormalParameter is called for both the arguments of a regular
552// function definition and the arguments specified by the Function
553// constructor.
554//
555// The 'disallowDuplicateParams' bool indicates whether the use of another
556// feature (destructuring or default arguments) disables duplicate arguments.
557// (ECMA-262 requires us to support duplicate parameter names, but, for newer
558// features, we consider the code to have "opted in" to higher standards and
559// forbid duplicates.)
560template <class ParseHandler, typename Unit>
561bool GeneralParser<ParseHandler, Unit>::notePositionalFormalParameter(
562 FunctionNodeType funNode, TaggedParserAtomIndex name, uint32_t beginPos,
563 bool disallowDuplicateParams, bool* duplicatedParam) {
564 if (AddDeclaredNamePtr p =
565 pc_->functionScope().lookupDeclaredNameForAdd(name)) {
566 if (disallowDuplicateParams) {
567 error(JSMSG_BAD_DUP_ARGS);
568 return false;
569 }
570
571 // Strict-mode disallows duplicate args. We may not know whether we are
572 // in strict mode or not (since the function body hasn't been parsed).
573 // In such cases, report will queue up the potential error and return
574 // 'true'.
575 if (pc_->sc()->strict()) {
576 UniqueChars bytes = this->parserAtoms().toPrintableString(name);
577 if (!bytes) {
578 ReportOutOfMemory(this->fc_);
579 return false;
580 }
581 if (!strictModeError(JSMSG_DUPLICATE_FORMAL, bytes.get())) {
582 return false;
583 }
584 }
585
586 *duplicatedParam = true;
587 } else {
588 DeclarationKind kind = DeclarationKind::PositionalFormalParameter;
589 if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, beginPos)) {
590 return false;
591 }
592 }
593
594 if (!pc_->positionalFormalParameterNames().append(
595 TrivialTaggedParserAtomIndex::from(name))) {
596 ReportOutOfMemory(this->fc_);
597 return false;
598 }
599
600 NameNodeType paramNode;
601 MOZ_TRY_VAR_OR_RETURN(paramNode, newName(name), false)do { auto parserTryVarTempResult_ = (newName(name)); if ((__builtin_expect
(!!(parserTryVarTempResult_.isErr()), 0))) { return (false); }
(paramNode) = parserTryVarTempResult_.unwrap(); } while (0)
;
602
603 handler_.addFunctionFormalParameter(funNode, paramNode);
604 return true;
605}
606
607template <class ParseHandler>
608bool PerHandlerParser<ParseHandler>::noteDestructuredPositionalFormalParameter(
609 FunctionNodeType funNode, Node destruct) {
610 // Append an empty name to the positional formals vector to keep track of
611 // argument slots when making FunctionScope::ParserData.
612 if (!pc_->positionalFormalParameterNames().append(
613 TrivialTaggedParserAtomIndex::null())) {
614 ReportOutOfMemory(fc_);
615 return false;
616 }
617
618 handler_.addFunctionFormalParameter(funNode, destruct);
619 return true;
620}
621
622template <class ParseHandler, typename Unit>
623bool GeneralParser<ParseHandler, Unit>::noteDeclaredName(
624 TaggedParserAtomIndex name, DeclarationKind kind, TokenPos pos,
625 ClosedOver isClosedOver) {
626 // The asm.js validator does all its own symbol-table management so, as an
627 // optimization, avoid doing any work here.
628 if (pc_->useAsmOrInsideUseAsm()) {
629 return true;
630 }
631
632 switch (kind) {
633 case DeclarationKind::Var:
634 case DeclarationKind::BodyLevelFunction: {
635 Maybe<DeclarationKind> redeclaredKind;
636 uint32_t prevPos;
637 if (!pc_->tryDeclareVar(name, this, kind, pos.begin, &redeclaredKind,
638 &prevPos)) {
639 return false;
640 }
641
642 if (redeclaredKind) {
643 reportRedeclaration(name, *redeclaredKind, pos, prevPos);
644 return false;
645 }
646
647 break;
648 }
649
650 case DeclarationKind::ModuleBodyLevelFunction: {
651 MOZ_ASSERT(pc_->atModuleLevel())do { static_assert( mozilla::detail::AssertionConditionType<
decltype(pc_->atModuleLevel())>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(pc_->atModuleLevel()))), 0
))) { do { } while (false); MOZ_ReportAssertionFailure("pc_->atModuleLevel()"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->atModuleLevel()"
")"); do { *((volatile int*)__null) = 651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
652
653 AddDeclaredNamePtr p = pc_->varScope().lookupDeclaredNameForAdd(name);
654 if (p) {
655 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
656 return false;
657 }
658
659 if (!pc_->varScope().addDeclaredName(pc_, p, name, kind, pos.begin,
660 isClosedOver)) {
661 return false;
662 }
663
664 // Body-level functions in modules are always closed over.
665 pc_->varScope().lookupDeclaredName(name)->value()->setClosedOver();
666
667 break;
668 }
669
670 case DeclarationKind::FormalParameter: {
671 // It is an early error if any non-positional formal parameter name
672 // (e.g., destructuring formal parameter) is duplicated.
673
674 AddDeclaredNamePtr p =
675 pc_->functionScope().lookupDeclaredNameForAdd(name);
676 if (p) {
677 error(JSMSG_BAD_DUP_ARGS);
678 return false;
679 }
680
681 if (!pc_->functionScope().addDeclaredName(pc_, p, name, kind, pos.begin,
682 isClosedOver)) {
683 return false;
684 }
685
686 break;
687 }
688
689 case DeclarationKind::LexicalFunction:
690 case DeclarationKind::PrivateName:
691 case DeclarationKind::Synthetic:
692 case DeclarationKind::PrivateMethod: {
693 ParseContext::Scope* scope = pc_->innermostScope();
694 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
695 if (p) {
696 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
697 return false;
698 }
699
700 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
701 isClosedOver)) {
702 return false;
703 }
704
705 break;
706 }
707
708 case DeclarationKind::SloppyLexicalFunction: {
709 // Functions in block have complex allowances in sloppy mode for being
710 // labelled that other lexical declarations do not have. Those checks
711 // are done in functionStmt.
712
713 ParseContext::Scope* scope = pc_->innermostScope();
714 if (AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name)) {
715 // It is usually an early error if there is another declaration
716 // with the same name in the same scope.
717 //
718 // Sloppy lexical functions may redeclare other sloppy lexical
719 // functions for web compatibility reasons.
720 if (p->value()->kind() != DeclarationKind::SloppyLexicalFunction) {
721 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
722 return false;
723 }
724 } else {
725 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
726 isClosedOver)) {
727 return false;
728 }
729 }
730
731 break;
732 }
733
734 case DeclarationKind::Let:
735 case DeclarationKind::Const:
736 case DeclarationKind::Class:
737 // The BoundNames of LexicalDeclaration and ForDeclaration must not
738 // contain 'let'. (CatchParameter is the only lexical binding form
739 // without this restriction.)
740 if (name == TaggedParserAtomIndex::WellKnown::let()) {
741 errorAt(pos.begin, JSMSG_LEXICAL_DECL_DEFINES_LET);
742 return false;
743 }
744
745 // For body-level lexically declared names in a function, it is an
746 // early error if there is a formal parameter of the same name. This
747 // needs a special check if there is an extra var scope due to
748 // parameter expressions.
749 if (pc_->isFunctionExtraBodyVarScopeInnermost()) {
750 DeclaredNamePtr p = pc_->functionScope().lookupDeclaredName(name);
751 if (p && DeclarationKindIsParameter(p->value()->kind())) {
752 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
753 return false;
754 }
755 }
756
757 [[fallthrough]];
758
759 case DeclarationKind::Import:
760 // Module code is always strict, so 'let' is always a keyword and never a
761 // name.
762 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"
, 762); AnnotateMozCrashReason("MOZ_ASSERT" "(" "name != TaggedParserAtomIndex::WellKnown::let()"
")"); do { *((volatile int*)__null) = 762; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
763 [[fallthrough]];
764
765 case DeclarationKind::SimpleCatchParameter:
766 case DeclarationKind::CatchParameter: {
767 ParseContext::Scope* scope = pc_->innermostScope();
768
769 // It is an early error if there is another declaration with the same
770 // name in the same scope.
771 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
772 if (p) {
773 reportRedeclaration(name, p->value()->kind(), pos, p->value()->pos());
774 return false;
775 }
776
777 if (!scope->addDeclaredName(pc_, p, name, kind, pos.begin,
778 isClosedOver)) {
779 return false;
780 }
781
782 break;
783 }
784
785 case DeclarationKind::CoverArrowParameter:
786 // CoverArrowParameter is only used as a placeholder declaration kind.
787 break;
788
789 case DeclarationKind::PositionalFormalParameter:
790 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"
, 792); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 792; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
791 "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"
, 792); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 792; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
792 "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"
, 792); AnnotateMozCrashReason("MOZ_CRASH(" "Positional formal parameter names should use "
"notePositionalFormalParameter" ")"); do { *((volatile int*)
__null) = 792; __attribute__((nomerge)) ::abort(); } while (false
); } while (false)
;
793 break;
794
795 case DeclarationKind::VarForAnnexBLexicalFunction:
796 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"
, 799); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 799; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
797 "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"
, 799); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 799; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
798 "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"
, 799); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 799; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
799 "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"
, 799); AnnotateMozCrashReason("MOZ_CRASH(" "Synthesized Annex B vars should go through "
"addPossibleAnnexBFunctionBox, and " "propagateAndMarkAnnexBFunctionBoxes"
")"); do { *((volatile int*)__null) = 799; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
800 break;
801 }
802
803 return true;
804}
805
806template <class ParseHandler, typename Unit>
807bool GeneralParser<ParseHandler, Unit>::noteDeclaredPrivateName(
808 Node nameNode, TaggedParserAtomIndex name, PropertyType propType,
809 FieldPlacement placement, TokenPos pos) {
810 ParseContext::Scope* scope = pc_->innermostScope();
811 AddDeclaredNamePtr p = scope->lookupDeclaredNameForAdd(name);
812
813 DeclarationKind declKind = DeclarationKind::PrivateName;
814
815 // Our strategy for enabling debugger functionality is to mark names as closed
816 // over, even if they don't necessarily need to be, to ensure that they are
817 // included in the environment object. This allows us to easily look them up
818 // by name when needed, even if there is no corresponding property on an
819 // object, as is the case with getter, setters and private methods.
820 ClosedOver closedOver = ClosedOver::Yes;
821 PrivateNameKind kind;
822 switch (propType) {
823 case PropertyType::Field:
824 kind = PrivateNameKind::Field;
825 closedOver = ClosedOver::No;
826 break;
827 case PropertyType::FieldWithAccessor:
828 // In this case, we create a new private field for the underlying storage,
829 // and use the current name for the getter and setter.
830 kind = PrivateNameKind::GetterSetter;
831 break;
832 case PropertyType::Method:
833 case PropertyType::GeneratorMethod:
834 case PropertyType::AsyncMethod:
835 case PropertyType::AsyncGeneratorMethod:
836 if (placement == FieldPlacement::Instance) {
837 // Optimized private method. Non-optimized paths still get
838 // DeclarationKind::Synthetic.
839 declKind = DeclarationKind::PrivateMethod;
840 }
841 kind = PrivateNameKind::Method;
842 break;
843 case PropertyType::Getter:
844 kind = PrivateNameKind::Getter;
845 break;
846 case PropertyType::Setter:
847 kind = PrivateNameKind::Setter;
848 break;
849 default:
850 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"
, 850); AnnotateMozCrashReason("MOZ_CRASH(" "Invalid Property Type for noteDeclarePrivateName"
")"); do { *((volatile int*)__null) = 850; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
851 }
852
853 if (p) {
854 PrivateNameKind prevKind = p->value()->privateNameKind();
855 if ((prevKind == PrivateNameKind::Getter &&
856 kind == PrivateNameKind::Setter) ||
857 (prevKind == PrivateNameKind::Setter &&
858 kind == PrivateNameKind::Getter)) {
859 // Private methods demands that
860 //
861 // class A {
862 // static set #x(_) {}
863 // get #x() { }
864 // }
865 //
866 // Report a SyntaxError.
867 if (placement == p->value()->placement()) {
868 p->value()->setPrivateNameKind(PrivateNameKind::GetterSetter);
869 handler_.setPrivateNameKind(nameNode, PrivateNameKind::GetterSetter);
870 return true;
871 }
872 }
873
874 reportMismatchedPlacement(name, p->value()->kind(), pos, p->value()->pos());
875 return false;
876 }
877
878 if (!scope->addDeclaredName(pc_, p, name, declKind, pos.begin, closedOver)) {
879 return false;
880 }
881
882 DeclaredNamePtr declared = scope->lookupDeclaredName(name);
883 declared->value()->setPrivateNameKind(kind);
884 declared->value()->setFieldPlacement(placement);
885 handler_.setPrivateNameKind(nameNode, kind);
886
887 return true;
888}
889
890bool ParserBase::noteUsedNameInternal(TaggedParserAtomIndex name,
891 NameVisibility visibility,
892 mozilla::Maybe<TokenPos> tokenPosition) {
893 // The asm.js validator does all its own symbol-table management so, as an
894 // optimization, avoid doing any work here.
895 if (pc_->useAsmOrInsideUseAsm()) {
896 return true;
897 }
898
899 // Global bindings are properties and not actual bindings; we don't need
900 // to know if they are closed over. So no need to track used name at the
901 // global scope. It is not incorrect to track them, this is an
902 // optimization.
903 //
904 // Exceptions:
905 // (a) Track private name references, as the used names tracker is used to
906 // provide early errors for undeclared private name references
907 // (b) If the script has extra bindings, track all references to detect
908 // references to extra bindings
909 ParseContext::Scope* scope = pc_->innermostScope();
910 if (pc_->sc()->isGlobalContext() && scope == &pc_->varScope() &&
911 visibility == NameVisibility::Public &&
912 !this->compilationState_.input.hasExtraBindings()) {
913 return true;
914 }
915
916 return usedNames_.noteUse(fc_, name, visibility, pc_->scriptId(), scope->id(),
917 tokenPosition);
918}
919
920template <class ParseHandler>
921bool PerHandlerParser<ParseHandler>::
922 propagateFreeNamesAndMarkClosedOverBindings(ParseContext::Scope& scope) {
923 // Now that we have all the declared names in the scope, check which
924 // functions should exhibit Annex B semantics.
925 if (!scope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
926 return false;
927 }
928
929 if (handler_.reuseClosedOverBindings()) {
930 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"
, 930); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isOutermostOfCurrentCompile()"
")"); do { *((volatile int*)__null) = 930; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
931
932 // Closed over bindings for all scopes are stored in a contiguous array, in
933 // the same order as the order in which scopes are visited, and seprated by
934 // TaggedParserAtomIndex::null().
935 uint32_t slotCount = scope.declaredCount();
936 while (auto parserAtom = handler_.nextLazyClosedOverBinding()) {
937 scope.lookupDeclaredName(parserAtom)->value()->setClosedOver();
938 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"
, 938); AnnotateMozCrashReason("MOZ_ASSERT" "(" "slotCount > 0"
")"); do { *((volatile int*)__null) = 938; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
939 slotCount--;
940 }
941
942 if (pc_->isGeneratorOrAsync()) {
943 scope.setOwnStackSlotCount(slotCount);
944 }
945 return true;
946 }
947
948 constexpr bool isSyntaxParser =
949 std::is_same_v<ParseHandler, SyntaxParseHandler>;
950 uint32_t scriptId = pc_->scriptId();
951 uint32_t scopeId = scope.id();
952
953 uint32_t slotCount = 0;
954 for (BindingIter bi = scope.bindings(pc_); bi; bi++) {
955 bool closedOver = false;
956 if (UsedNamePtr p = usedNames_.lookup(bi.name())) {
957 p->value().noteBoundInScope(scriptId, scopeId, &closedOver);
958 if (closedOver) {
959 bi.setClosedOver();
960
961 if constexpr (isSyntaxParser) {
962 if (!pc_->closedOverBindingsForLazy().append(
963 TrivialTaggedParserAtomIndex::from(bi.name()))) {
964 ReportOutOfMemory(fc_);
965 return false;
966 }
967 }
968 }
969 }
970
971 if constexpr (!isSyntaxParser) {
972 if (!closedOver) {
973 slotCount++;
974 }
975 }
976 }
977 if constexpr (!isSyntaxParser) {
978 if (pc_->isGeneratorOrAsync()) {
979 scope.setOwnStackSlotCount(slotCount);
980 }
981 }
982
983 // Append a nullptr to denote end-of-scope.
984 if constexpr (isSyntaxParser) {
985 if (!pc_->closedOverBindingsForLazy().append(
986 TrivialTaggedParserAtomIndex::null())) {
987 ReportOutOfMemory(fc_);
988 return false;
989 }
990 }
991
992 return true;
993}
994
995template <typename Unit>
996bool Parser<FullParseHandler, Unit>::checkStatementsEOF() {
997 // This is designed to be paired with parsing a statement list at the top
998 // level.
999 //
1000 // The statementList() call breaks on TokenKind::RightCurly, so make sure
1001 // we've reached EOF here.
1002 TokenKind tt;
1003 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
1004 return false;
1005 }
1006 if (tt != TokenKind::Eof) {
1007 error(JSMSG_UNEXPECTED_TOKEN, "expression", TokenKindToDesc(tt));
1008 return false;
1009 }
1010 return true;
1011}
1012
1013template <typename ScopeT>
1014typename ScopeT::ParserData* NewEmptyBindingData(FrontendContext* fc,
1015 LifoAlloc& alloc,
1016 uint32_t numBindings) {
1017 using Data = typename ScopeT::ParserData;
1018 size_t allocSize = SizeOfScopeData<Data>(numBindings);
1019 auto* bindings = alloc.newWithSize<Data>(allocSize, numBindings);
1020 if (!bindings) {
1021 ReportOutOfMemory(fc);
1022 }
1023 return bindings;
1024}
1025
1026GlobalScope::ParserData* NewEmptyGlobalScopeData(FrontendContext* fc,
1027 LifoAlloc& alloc,
1028 uint32_t numBindings) {
1029 return NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
1030}
1031
1032LexicalScope::ParserData* NewEmptyLexicalScopeData(FrontendContext* fc,
1033 LifoAlloc& alloc,
1034 uint32_t numBindings) {
1035 return NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
1036}
1037
1038FunctionScope::ParserData* NewEmptyFunctionScopeData(FrontendContext* fc,
1039 LifoAlloc& alloc,
1040 uint32_t numBindings) {
1041 return NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
1042}
1043
1044namespace detail {
1045
1046template <class SlotInfo>
1047static MOZ_ALWAYS_INLINEinline ParserBindingName* InitializeIndexedBindings(
1048 SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor) {
1049 return cursor;
1050}
1051
1052template <class SlotInfo, typename UnsignedInteger, typename... Step>
1053static MOZ_ALWAYS_INLINEinline ParserBindingName* InitializeIndexedBindings(
1054 SlotInfo& slotInfo, ParserBindingName* start, ParserBindingName* cursor,
1055 UnsignedInteger SlotInfo::*field, const ParserBindingNameVector& bindings,
1056 Step&&... step) {
1057 slotInfo.*field =
1058 AssertedCast<UnsignedInteger>(PointerRangeSize(start, cursor));
1059
1060 ParserBindingName* newCursor =
1061 std::uninitialized_copy(bindings.begin(), bindings.end(), cursor);
1062
1063 return InitializeIndexedBindings(slotInfo, start, newCursor,
1064 std::forward<Step>(step)...);
1065}
1066
1067} // namespace detail
1068
1069// Initialize the trailing name bindings of |data|, then set |data->length| to
1070// the count of bindings added (which must equal |count|).
1071//
1072// First, |firstBindings| are added to the trailing names. Then any
1073// "steps" present are performed first to last. Each step is 1) a pointer to a
1074// member of |data| to be set to the current number of bindings added, and 2) a
1075// vector of |ParserBindingName|s to then copy into |data->trailingNames|.
1076// (Thus each |data| member field indicates where the corresponding vector's
1077// names start.)
1078template <class Data, typename... Step>
1079static MOZ_ALWAYS_INLINEinline void InitializeBindingData(
1080 Data* data, uint32_t count, const ParserBindingNameVector& firstBindings,
1081 Step&&... step) {
1082 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"
, 1082); AnnotateMozCrashReason("MOZ_ASSERT" "(" "data->length == 0"
") (" "data shouldn't be filled yet" ")"); do { *((volatile int
*)__null) = 1082; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1083
1084 ParserBindingName* start = GetScopeDataTrailingNamesPointer(data);
1085 ParserBindingName* cursor = std::uninitialized_copy(
1086 firstBindings.begin(), firstBindings.end(), start);
1087
1088#ifdef DEBUG1
1089 ParserBindingName* end =
1090#endif
1091 detail::InitializeIndexedBindings(data->slotInfo, start, cursor,
1092 std::forward<Step>(step)...);
1093
1094 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"
, 1094); AnnotateMozCrashReason("MOZ_ASSERT" "(" "PointerRangeSize(start, end) == count"
")"); do { *((volatile int*)__null) = 1094; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1095 data->length = count;
1096}
1097
1098static Maybe<GlobalScope::ParserData*> NewGlobalScopeData(
1099 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1100 ParseContext* pc) {
1101 ParserBindingNameVector vars(fc);
1102 ParserBindingNameVector lets(fc);
1103 ParserBindingNameVector consts(fc);
1104
1105 bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver();
1106 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1107 bool closedOver = allBindingsClosedOver || bi.closedOver();
1108
1109 switch (bi.kind()) {
1110 case BindingKind::Var: {
1111 bool isTopLevelFunction =
1112 bi.declarationKind() == DeclarationKind::BodyLevelFunction;
1113
1114 ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
1115 if (!vars.append(binding)) {
1116 return Nothing();
1117 }
1118 break;
1119 }
1120 case BindingKind::Let: {
1121 ParserBindingName binding(bi.name(), closedOver);
1122 if (!lets.append(binding)) {
1123 return Nothing();
1124 }
1125 break;
1126 }
1127 case BindingKind::Const: {
1128 ParserBindingName binding(bi.name(), closedOver);
1129 if (!consts.append(binding)) {
1130 return Nothing();
1131 }
1132 break;
1133 }
1134 default:
1135 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"
, 1135); AnnotateMozCrashReason("MOZ_CRASH(" "Bad global scope BindingKind"
")"); do { *((volatile int*)__null) = 1135; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1136 }
1137 }
1138
1139 GlobalScope::ParserData* bindings = nullptr;
1140 uint32_t numBindings = vars.length() + lets.length() + consts.length();
1141
1142 if (numBindings > 0) {
1143 bindings = NewEmptyBindingData<GlobalScope>(fc, alloc, numBindings);
1144 if (!bindings) {
1145 return Nothing();
1146 }
1147
1148 // The ordering here is important. See comments in GlobalScope.
1149 InitializeBindingData(bindings, numBindings, vars,
1150 &ParserGlobalScopeSlotInfo::letStart, lets,
1151 &ParserGlobalScopeSlotInfo::constStart, consts);
1152 }
1153
1154 return Some(bindings);
1155}
1156
1157Maybe<GlobalScope::ParserData*> ParserBase::newGlobalScopeData(
1158 ParseContext::Scope& scope) {
1159 return NewGlobalScopeData(fc_, scope, stencilAlloc(), pc_);
1160}
1161
1162static Maybe<ModuleScope::ParserData*> NewModuleScopeData(
1163 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1164 ParseContext* pc) {
1165 ParserBindingNameVector imports(fc);
1166 ParserBindingNameVector vars(fc);
1167 ParserBindingNameVector lets(fc);
1168 ParserBindingNameVector consts(fc);
1169
1170 bool allBindingsClosedOver =
1171 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1172
1173 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1174 // Imports are indirect bindings and must not be given known slots.
1175 ParserBindingName binding(bi.name(),
1176 (allBindingsClosedOver || bi.closedOver()) &&
1177 bi.kind() != BindingKind::Import);
1178 switch (bi.kind()) {
1179 case BindingKind::Import:
1180 if (!imports.append(binding)) {
1181 return Nothing();
1182 }
1183 break;
1184 case BindingKind::Var:
1185 if (!vars.append(binding)) {
1186 return Nothing();
1187 }
1188 break;
1189 case BindingKind::Let:
1190 if (!lets.append(binding)) {
1191 return Nothing();
1192 }
1193 break;
1194 case BindingKind::Const:
1195 if (!consts.append(binding)) {
1196 return Nothing();
1197 }
1198 break;
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 =
1206 imports.length() + vars.length() + lets.length() + consts.length();
1207
1208 if (numBindings > 0) {
1209 bindings = NewEmptyBindingData<ModuleScope>(fc, alloc, numBindings);
1210 if (!bindings) {
1211 return Nothing();
1212 }
1213
1214 // The ordering here is important. See comments in ModuleScope.
1215 InitializeBindingData(bindings, numBindings, imports,
1216 &ParserModuleScopeSlotInfo::varStart, vars,
1217 &ParserModuleScopeSlotInfo::letStart, lets,
1218 &ParserModuleScopeSlotInfo::constStart, consts);
1219 }
1220
1221 return Some(bindings);
1222}
1223
1224Maybe<ModuleScope::ParserData*> ParserBase::newModuleScopeData(
1225 ParseContext::Scope& scope) {
1226 return NewModuleScopeData(fc_, scope, stencilAlloc(), pc_);
1227}
1228
1229static Maybe<EvalScope::ParserData*> NewEvalScopeData(
1230 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1231 ParseContext* pc) {
1232 ParserBindingNameVector vars(fc);
1233
1234 // Treat all bindings as closed over in non-strict eval.
1235 bool allBindingsClosedOver =
1236 !pc->sc()->strict() || pc->sc()->allBindingsClosedOver();
1237 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1238 // Eval scopes only contain 'var' bindings.
1239 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"
, 1239); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Var"
")"); do { *((volatile int*)__null) = 1239; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1240 bool isTopLevelFunction =
1241 bi.declarationKind() == DeclarationKind::BodyLevelFunction;
1242 bool closedOver = allBindingsClosedOver || bi.closedOver();
1243
1244 ParserBindingName binding(bi.name(), closedOver, isTopLevelFunction);
1245 if (!vars.append(binding)) {
1246 return Nothing();
1247 }
1248 }
1249
1250 EvalScope::ParserData* bindings = nullptr;
1251 uint32_t numBindings = vars.length();
1252
1253 if (numBindings > 0) {
1254 bindings = NewEmptyBindingData<EvalScope>(fc, alloc, numBindings);
1255 if (!bindings) {
1256 return Nothing();
1257 }
1258
1259 InitializeBindingData(bindings, numBindings, vars);
1260 }
1261
1262 return Some(bindings);
1263}
1264
1265Maybe<EvalScope::ParserData*> ParserBase::newEvalScopeData(
1266 ParseContext::Scope& scope) {
1267 return NewEvalScopeData(fc_, scope, stencilAlloc(), pc_);
1268}
1269
1270static Maybe<FunctionScope::ParserData*> NewFunctionScopeData(
1271 FrontendContext* fc, ParseContext::Scope& scope, bool hasParameterExprs,
1272 LifoAlloc& alloc, ParseContext* pc) {
1273 ParserBindingNameVector positionalFormals(fc);
1274 ParserBindingNameVector formals(fc);
1275 ParserBindingNameVector vars(fc);
1276
1277 bool allBindingsClosedOver =
1278 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1279 bool argumentBindingsClosedOver =
1280 allBindingsClosedOver || pc->isGeneratorOrAsync();
1281 bool hasDuplicateParams = pc->functionBox()->hasDuplicateParameters;
1282
1283 // Positional parameter names must be added in order of appearance as they are
1284 // referenced using argument slots.
1285 for (size_t i = 0; i < pc->positionalFormalParameterNames().length(); i++) {
1286 TaggedParserAtomIndex name = pc->positionalFormalParameterNames()[i];
1287
1288 ParserBindingName bindName;
1289 if (name) {
1290 DeclaredNamePtr p = scope.lookupDeclaredName(name);
1291
1292 // Do not consider any positional formal parameters closed over if
1293 // there are parameter defaults. It is the binding in the defaults
1294 // scope that is closed over instead.
1295 bool closedOver =
1296 argumentBindingsClosedOver || (p && p->value()->closedOver());
1297
1298 // If the parameter name has duplicates, only the final parameter
1299 // name should be on the environment, as otherwise the environment
1300 // object would have multiple, same-named properties.
1301 if (hasDuplicateParams) {
1302 for (size_t j = pc->positionalFormalParameterNames().length() - 1;
1303 j > i; j--) {
1304 if (TaggedParserAtomIndex(pc->positionalFormalParameterNames()[j]) ==
1305 name) {
1306 closedOver = false;
1307 break;
1308 }
1309 }
1310 }
1311
1312 bindName = ParserBindingName(name, closedOver);
1313 }
1314
1315 if (!positionalFormals.append(bindName)) {
1316 return Nothing();
1317 }
1318 }
1319
1320 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1321 ParserBindingName binding(bi.name(),
1322 allBindingsClosedOver || bi.closedOver());
1323 switch (bi.kind()) {
1324 case BindingKind::FormalParameter:
1325 // Positional parameter names are already handled above.
1326 if (bi.declarationKind() == DeclarationKind::FormalParameter) {
1327 if (!formals.append(binding)) {
1328 return Nothing();
1329 }
1330 }
1331 break;
1332 case BindingKind::Var:
1333 // The only vars in the function scope when there are parameter
1334 // exprs, which induces a separate var environment, should be the
1335 // special bindings.
1336 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"
, 1337); AnnotateMozCrashReason("MOZ_ASSERT" "(" "FunctionScope::isSpecialName(bi.name())"
")"); do { *((volatile int*)__null) = 1337; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1337 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"
, 1337); AnnotateMozCrashReason("MOZ_ASSERT" "(" "FunctionScope::isSpecialName(bi.name())"
")"); do { *((volatile int*)__null) = 1337; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1338 if (!vars.append(binding)) {
1339 return Nothing();
1340 }
1341 break;
1342 case BindingKind::Let:
1343 case BindingKind::Const:
1344 break;
1345 default:
1346 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"
, 1346); AnnotateMozCrashReason("MOZ_CRASH(" "bad function scope BindingKind"
")"); do { *((volatile int*)__null) = 1346; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1347 break;
1348 }
1349 }
1350
1351 FunctionScope::ParserData* bindings = nullptr;
1352 uint32_t numBindings =
1353 positionalFormals.length() + formals.length() + vars.length();
1354
1355 if (numBindings > 0) {
1356 bindings = NewEmptyBindingData<FunctionScope>(fc, alloc, numBindings);
1357 if (!bindings) {
1358 return Nothing();
1359 }
1360
1361 // The ordering here is important. See comments in FunctionScope.
1362 InitializeBindingData(
1363 bindings, numBindings, positionalFormals,
1364 &ParserFunctionScopeSlotInfo::nonPositionalFormalStart, formals,
1365 &ParserFunctionScopeSlotInfo::varStart, vars);
1366 }
1367
1368 return Some(bindings);
1369}
1370
1371// Compute if `NewFunctionScopeData` would return any binding list with any
1372// entry marked as closed-over. This is done without the need to allocate the
1373// binding list. If true, an EnvironmentObject will be needed at runtime.
1374bool FunctionScopeHasClosedOverBindings(ParseContext* pc) {
1375 bool allBindingsClosedOver = pc->sc()->allBindingsClosedOver() ||
1376 pc->functionScope().tooBigToOptimize();
1377
1378 for (BindingIter bi = pc->functionScope().bindings(pc); bi; bi++) {
1379 switch (bi.kind()) {
1380 case BindingKind::FormalParameter:
1381 case BindingKind::Var:
1382 if (allBindingsClosedOver || bi.closedOver()) {
1383 return true;
1384 }
1385 break;
1386
1387 default:
1388 break;
1389 }
1390 }
1391
1392 return false;
1393}
1394
1395Maybe<FunctionScope::ParserData*> ParserBase::newFunctionScopeData(
1396 ParseContext::Scope& scope, bool hasParameterExprs) {
1397 return NewFunctionScopeData(fc_, scope, hasParameterExprs, stencilAlloc(),
1398 pc_);
1399}
1400
1401VarScope::ParserData* NewEmptyVarScopeData(FrontendContext* fc,
1402 LifoAlloc& alloc,
1403 uint32_t numBindings) {
1404 return NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
1405}
1406
1407static Maybe<VarScope::ParserData*> NewVarScopeData(FrontendContext* fc,
1408 ParseContext::Scope& scope,
1409 LifoAlloc& alloc,
1410 ParseContext* pc) {
1411 ParserBindingNameVector vars(fc);
1412
1413 bool allBindingsClosedOver =
1414 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1415
1416 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1417 if (bi.kind() == BindingKind::Var) {
1418 ParserBindingName binding(bi.name(),
1419 allBindingsClosedOver || bi.closedOver());
1420 if (!vars.append(binding)) {
1421 return Nothing();
1422 }
1423 } else {
1424 MOZ_ASSERT(do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1426); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1426; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1425 bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const,do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1426); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1426; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
1426 "bad var scope BindingKind")do { static_assert( mozilla::detail::AssertionConditionType<
decltype(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const)>::isValid, "invalid assertion condition"); if ((__builtin_expect
(!!(!(!!(bi.kind() == BindingKind::Let || bi.kind() == BindingKind
::Const))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
" (" "bad var scope BindingKind" ")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 1426); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bi.kind() == BindingKind::Let || bi.kind() == BindingKind::Const"
") (" "bad var scope BindingKind" ")"); do { *((volatile int
*)__null) = 1426; __attribute__((nomerge)) ::abort(); } while
(false); } } while (false)
;
1427 }
1428 }
1429
1430 VarScope::ParserData* bindings = nullptr;
1431 uint32_t numBindings = vars.length();
1432
1433 if (numBindings > 0) {
1434 bindings = NewEmptyBindingData<VarScope>(fc, alloc, numBindings);
1435 if (!bindings) {
1436 return Nothing();
1437 }
1438
1439 InitializeBindingData(bindings, numBindings, vars);
1440 }
1441
1442 return Some(bindings);
1443}
1444
1445// Compute if `NewVarScopeData` would return any binding list. This is done
1446// without allocate the binding list.
1447static bool VarScopeHasBindings(ParseContext* pc) {
1448 for (BindingIter bi = pc->varScope().bindings(pc); bi; bi++) {
1449 if (bi.kind() == BindingKind::Var) {
1450 return true;
1451 }
1452 }
1453
1454 return false;
1455}
1456
1457Maybe<VarScope::ParserData*> ParserBase::newVarScopeData(
1458 ParseContext::Scope& scope) {
1459 return NewVarScopeData(fc_, scope, stencilAlloc(), pc_);
1460}
1461
1462static Maybe<LexicalScope::ParserData*> NewLexicalScopeData(
1463 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1464 ParseContext* pc) {
1465 ParserBindingNameVector lets(fc);
1466 ParserBindingNameVector consts(fc);
1467
1468 bool allBindingsClosedOver =
1469 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1470
1471 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1472 ParserBindingName binding(bi.name(),
1473 allBindingsClosedOver || bi.closedOver());
1474 switch (bi.kind()) {
1475 case BindingKind::Let:
1476 if (!lets.append(binding)) {
1477 return Nothing();
1478 }
1479 break;
1480 case BindingKind::Const:
1481 if (!consts.append(binding)) {
1482 return Nothing();
1483 }
1484 break;
1485 case BindingKind::Var:
1486 case BindingKind::FormalParameter:
1487 break;
1488 default:
1489 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"
, 1489); AnnotateMozCrashReason("MOZ_CRASH(" "Bad lexical scope BindingKind"
")"); do { *((volatile int*)__null) = 1489; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1490 break;
1491 }
1492 }
1493
1494 LexicalScope::ParserData* bindings = nullptr;
1495 uint32_t numBindings = lets.length() + consts.length();
1496
1497 if (numBindings > 0) {
1498 bindings = NewEmptyBindingData<LexicalScope>(fc, alloc, numBindings);
1499 if (!bindings) {
1500 return Nothing();
1501 }
1502
1503 // The ordering here is important. See comments in LexicalScope.
1504 InitializeBindingData(bindings, numBindings, lets,
1505 &ParserLexicalScopeSlotInfo::constStart, consts);
1506 }
1507
1508 return Some(bindings);
1509}
1510
1511// Compute if `NewLexicalScopeData` would return any binding list with any entry
1512// marked as closed-over. This is done without the need to allocate the binding
1513// list. If true, an EnvironmentObject will be needed at runtime.
1514bool LexicalScopeHasClosedOverBindings(ParseContext* pc,
1515 ParseContext::Scope& scope) {
1516 bool allBindingsClosedOver =
1517 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
1518
1519 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
1520 switch (bi.kind()) {
1521 case BindingKind::Let:
1522 case BindingKind::Const:
1523 if (allBindingsClosedOver || bi.closedOver()) {
1524 return true;
1525 }
1526 break;
1527
1528 default:
1529 break;
1530 }
1531 }
1532
1533 return false;
1534}
1535
1536Maybe<LexicalScope::ParserData*> ParserBase::newLexicalScopeData(
1537 ParseContext::Scope& scope) {
1538 return NewLexicalScopeData(fc_, scope, stencilAlloc(), pc_);
1539}
1540
1541static Maybe<ClassBodyScope::ParserData*> NewClassBodyScopeData(
1542 FrontendContext* fc, ParseContext::Scope& scope, LifoAlloc& alloc,
1543 ParseContext* pc) {
1544 ParserBindingNameVector privateBrand(fc);
1545 ParserBindingNameVector synthetics(fc);
1546 ParserBindingNameVector privateMethods(fc);
1547
1548 bool allBindingsClosedOver =
1549 pc->sc()->allBindingsClosedOver() || scope.tooBigToOptimize();
5
Assuming the condition is false
1550
1551 for (BindingIter bi = scope.bindings(pc); bi; bi++) {
6
Loop condition is false. Execution continues on line 1582
1552 ParserBindingName binding(bi.name(),
1553 allBindingsClosedOver || bi.closedOver());
1554 switch (bi.kind()) {
1555 case BindingKind::Synthetic:
1556 if (bi.name() ==
1557 TaggedParserAtomIndex::WellKnown::dot_privateBrand_()) {
1558 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"
, 1558); AnnotateMozCrashReason("MOZ_ASSERT" "(" "privateBrand.empty()"
")"); do { *((volatile int*)__null) = 1558; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1559 if (!privateBrand.append(binding)) {
1560 return Nothing();
1561 }
1562 } else {
1563 if (!synthetics.append(binding)) {
1564 return Nothing();
1565 }
1566 }
1567 break;
1568
1569 case BindingKind::PrivateMethod:
1570 if (!privateMethods.append(binding)) {
1571 return Nothing();
1572 }
1573 break;
1574
1575 default:
1576 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"
, 1576); AnnotateMozCrashReason("MOZ_CRASH(" "bad class body scope BindingKind"
")"); do { *((volatile int*)__null) = 1576; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
1577 break;
1578 }
1579 }
1580
1581 // We should have zero or one private brands.
1582 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"
, 1582); AnnotateMozCrashReason("MOZ_ASSERT" "(" "privateBrand.length() == 0 || privateBrand.length() == 1"
")"); do { *((volatile int*)__null) = 1582; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
7
Assuming the condition is true
8
Taking false branch
9
Loop condition is false. Exiting loop
1583
1584 ClassBodyScope::ParserData* bindings = nullptr;
10
'bindings' initialized to a null pointer value
1585 uint32_t numBindings =
1586 privateBrand.length() + synthetics.length() + privateMethods.length();
1587
1588 if (numBindings > 0) {
11
Assuming 'numBindings' is <= 0
12
Taking false branch
1589 bindings = NewEmptyBindingData<ClassBodyScope>(fc, alloc, numBindings);
1590 if (!bindings) {
1591 return Nothing();
1592 }
1593 // To simplify initialization of the bindings, we concatenate the
1594 // synthetics+privateBrand vector such that the private brand is always the
1595 // first element, as ordering is important. See comments in ClassBodyScope.
1596 ParserBindingNameVector brandAndSynthetics(fc);
1597 if (!brandAndSynthetics.appendAll(privateBrand)) {
1598 return Nothing();
1599 }
1600 if (!brandAndSynthetics.appendAll(synthetics)) {
1601 return Nothing();
1602 }
1603
1604 // The ordering here is important. See comments in ClassBodyScope.
1605 InitializeBindingData(bindings, numBindings, brandAndSynthetics,
1606 &ParserClassBodyScopeSlotInfo::privateMethodStart,
1607 privateMethods);
1608 }
1609
1610 // `EmitterScope::lookupPrivate()` requires `.privateBrand` to be stored in a
1611 // predictable slot: the first slot available in the environment object,
1612 // `ClassBodyLexicalEnvironmentObject::privateBrandSlot()`. We assume that
1613 // if `.privateBrand` is first in the scope, it will be stored there.
1614 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"
, 1616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1616; __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>>'
1615 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"
, 1616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1616; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
1616 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"
, 1616); AnnotateMozCrashReason("MOZ_ASSERT" "(" "GetScopeDataTrailingNames(bindings)[0].name() == TaggedParserAtomIndex::WellKnown::dot_privateBrand_()"
")"); do { *((volatile int*)__null) = 1616; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
1617
1618 return Some(bindings);
1619}
1620
1621Maybe<ClassBodyScope::ParserData*> ParserBase::newClassBodyScopeData(
1622 ParseContext::Scope& scope) {
1623 return NewClassBodyScopeData(fc_, scope, stencilAlloc(), pc_);
4
Calling 'NewClassBodyScopeData'
1624}
1625
1626template <>
1627SyntaxParseHandler::LexicalScopeNodeResult
1628PerHandlerParser<SyntaxParseHandler>::finishLexicalScope(
1629 ParseContext::Scope& scope, Node body, ScopeKind kind) {
1630 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1631 return errorResult();
1632 }
1633
1634 return handler_.newLexicalScope(body);
1635}
1636
1637template <>
1638FullParseHandler::LexicalScopeNodeResult
1639PerHandlerParser<FullParseHandler>::finishLexicalScope(
1640 ParseContext::Scope& scope, ParseNode* body, ScopeKind kind) {
1641 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1642 return errorResult();
1643 }
1644
1645 Maybe<LexicalScope::ParserData*> bindings = newLexicalScopeData(scope);
1646 if (!bindings) {
1647 return errorResult();
1648 }
1649
1650 return handler_.newLexicalScope(*bindings, body, kind);
1651}
1652
1653template <>
1654SyntaxParseHandler::ClassBodyScopeNodeResult
1655PerHandlerParser<SyntaxParseHandler>::finishClassBodyScope(
1656 ParseContext::Scope& scope, ListNodeType body) {
1657 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1658 return errorResult();
1659 }
1660
1661 return handler_.newClassBodyScope(body);
1662}
1663
1664template <>
1665FullParseHandler::ClassBodyScopeNodeResult
1666PerHandlerParser<FullParseHandler>::finishClassBodyScope(
1667 ParseContext::Scope& scope, ListNode* body) {
1668 if (!propagateFreeNamesAndMarkClosedOverBindings(scope)) {
1
Assuming the condition is false
2
Taking false branch
1669 return errorResult();
1670 }
1671
1672 Maybe<ClassBodyScope::ParserData*> bindings = newClassBodyScopeData(scope);
3
Calling 'ParserBase::newClassBodyScopeData'
1673 if (!bindings) {
1674 return errorResult();
1675 }
1676
1677 return handler_.newClassBodyScope(*bindings, body);
1678}
1679
1680template <class ParseHandler>
1681bool PerHandlerParser<ParseHandler>::checkForUndefinedPrivateFields(
1682 EvalSharedContext* evalSc) {
1683 if (!this->compilationState_.isInitialStencil()) {
1684 // We're delazifying -- so we already checked private names during first
1685 // parse.
1686 return true;
1687 }
1688
1689 Vector<UnboundPrivateName, 8> unboundPrivateNames(fc_);
1690 if (!usedNames_.getUnboundPrivateNames(unboundPrivateNames)) {
1691 return false;
1692 }
1693
1694 // No unbound names, let's get out of here!
1695 if (unboundPrivateNames.empty()) {
1696 return true;
1697 }
1698
1699 // It is an early error if there's private name references unbound,
1700 // unless it's an eval, in which case we need to check the scope
1701 // chain.
1702 if (!evalSc) {
1703 // The unbound private names are sorted, so just grab the first one.
1704 UnboundPrivateName minimum = unboundPrivateNames[0];
1705 UniqueChars str = this->parserAtoms().toPrintableString(minimum.atom);
1706 if (!str) {
1707 ReportOutOfMemory(this->fc_);
1708 return false;
1709 }
1710
1711 errorAt(minimum.position.begin, JSMSG_MISSING_PRIVATE_DECL, str.get());
1712 return false;
1713 }
1714
1715 // It's important that the unbound private names are sorted, as we
1716 // want our errors to always be issued to the first textually.
1717 for (UnboundPrivateName unboundName : unboundPrivateNames) {
1718 // If the enclosingScope is non-syntactic, then we are in a
1719 // Debugger.Frame.prototype.eval call. In order to find the declared private
1720 // names, we must use the effective scope that was determined when creating
1721 // the scopeContext.
1722 if (!this->compilationState_.scopeContext
1723 .effectiveScopePrivateFieldCacheHas(unboundName.atom)) {
1724 UniqueChars str = this->parserAtoms().toPrintableString(unboundName.atom);
1725 if (!str) {
1726 ReportOutOfMemory(this->fc_);
1727 return false;
1728 }
1729 errorAt(unboundName.position.begin, JSMSG_MISSING_PRIVATE_DECL,
1730 str.get());
1731 return false;
1732 }
1733 }
1734
1735 return true;
1736}
1737
1738template <typename Unit>
1739FullParseHandler::LexicalScopeNodeResult
1740Parser<FullParseHandler, Unit>::evalBody(EvalSharedContext* evalsc) {
1741 SourceParseContext evalpc(this, evalsc, /* newDirectives = */ nullptr);
1742 if (!evalpc.init()) {
1743 return errorResult();
1744 }
1745
1746 ParseContext::VarScope varScope(this);
1747 if (!varScope.init(pc_)) {
1748 return errorResult();
1749 }
1750
1751 LexicalScopeNode* body;
1752 {
1753 // All evals have an implicit non-extensible lexical scope.
1754 ParseContext::Scope lexicalScope(this);
1755 if (!lexicalScope.init(pc_)) {
1756 return errorResult();
1757 }
1758
1759 ListNode* list;
1760 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)
;
1761
1762 if (!checkStatementsEOF()) {
1763 return errorResult();
1764 }
1765
1766 // Private names not lexically defined must trigger a syntax error.
1767 if (!checkForUndefinedPrivateFields(evalsc)) {
1768 return errorResult();
1769 }
1770
1771 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)
;
1772 }
1773
1774#ifdef DEBUG1
1775 if (evalpc.superScopeNeedsHomeObject() &&
1776 !this->compilationState_.input.enclosingScope.isNull()) {
1777 // If superScopeNeedsHomeObject_ is set and we are an entry-point
1778 // ParseContext, then we must be emitting an eval script, and the
1779 // outer function must already be marked as needing a home object
1780 // since it contains an eval.
1781 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"
, 1784); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1784; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1782 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"
, 1784); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1784; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1783 "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"
, 1784); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1784; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
1784 "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"
, 1784); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this->compilationState_.scopeContext.hasFunctionNeedsHomeObjectOnChain"
") (" "Eval must have found an enclosing function box scope that "
"allows super.property" ")"); do { *((volatile int*)__null) =
1784; __attribute__((nomerge)) ::abort(); } while (false); }
} while (false)
;
1785 }
1786#endif
1787
1788 if (!CheckParseTree(this->fc_, alloc_, body)) {
1789 return errorResult();
1790 }
1791
1792 ParseNode* node = body;
1793 // Don't constant-fold inside "use asm" code, as this could create a parse
1794 // tree that doesn't type-check as asm.js.
1795 if (!pc_->useAsmOrInsideUseAsm()) {
1796 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
1797 return errorResult();
1798 }
1799 }
1800 body = handler_.asLexicalScopeNode(node);
1801
1802 if (!this->setSourceMapInfo()) {
1803 return errorResult();
1804 }
1805
1806 if (pc_->sc()->strict()) {
1807 if (!propagateFreeNamesAndMarkClosedOverBindings(varScope)) {
1808 return errorResult();
1809 }
1810 } else {
1811 // For non-strict eval scripts, since all bindings are automatically
1812 // considered closed over, we don't need to call propagateFreeNames-
1813 // AndMarkClosedOverBindings. However, Annex B.3.3 functions still need to
1814 // be marked.
1815 if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
1816 return errorResult();
1817 }
1818 }
1819
1820 Maybe<EvalScope::ParserData*> bindings = newEvalScopeData(pc_->varScope());
1821 if (!bindings) {
1822 return errorResult();
1823 }
1824 evalsc->bindings = *bindings;
1825
1826 return body;
1827}
1828
1829template <typename Unit>
1830FullParseHandler::ListNodeResult Parser<FullParseHandler, Unit>::globalBody(
1831 GlobalSharedContext* globalsc) {
1832 SourceParseContext globalpc(this, globalsc, /* newDirectives = */ nullptr);
1833 if (!globalpc.init()) {
1834 return errorResult();
1835 }
1836
1837 ParseContext::VarScope varScope(this);
1838 if (!varScope.init(pc_)) {
1839 return errorResult();
1840 }
1841
1842 ListNode* body;
1843 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)
;
1844
1845 if (!checkStatementsEOF()) {
1846 return errorResult();
1847 }
1848
1849 if (!CheckParseTree(this->fc_, alloc_, body)) {
1850 return errorResult();
1851 }
1852
1853 if (!checkForUndefinedPrivateFields()) {
1854 return errorResult();
1855 }
1856
1857 ParseNode* node = body;
1858 // Don't constant-fold inside "use asm" code, as this could create a parse
1859 // tree that doesn't type-check as asm.js.
1860 if (!pc_->useAsmOrInsideUseAsm()) {
1861 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
1862 return errorResult();
1863 }
1864 }
1865 body = &node->as<ListNode>();
1866
1867 if (!this->setSourceMapInfo()) {
1868 return errorResult();
1869 }
1870
1871 // For global scripts, whether bindings are closed over or not doesn't
1872 // matter, so no need to call propagateFreeNamesAndMarkClosedOver-
1873 // Bindings. However, Annex B.3.3 functions still need to be marked.
1874 if (!varScope.propagateAndMarkAnnexBFunctionBoxes(pc_, this)) {
1875 return errorResult();
1876 }
1877
1878 Maybe<GlobalScope::ParserData*> bindings =
1879 newGlobalScopeData(pc_->varScope());
1880 if (!bindings) {
1881 return errorResult();
1882 }
1883 globalsc->bindings = *bindings;
1884
1885 return body;
1886}
1887
1888template <typename Unit>
1889FullParseHandler::ModuleNodeResult Parser<FullParseHandler, Unit>::moduleBody(
1890 ModuleSharedContext* modulesc) {
1891 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"
, 1891); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 1891; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1892
1893 this->compilationState_.moduleMetadata =
1894 fc_->getAllocator()->template new_<StencilModuleMetadata>();
1895 if (!this->compilationState_.moduleMetadata) {
1896 return errorResult();
1897 }
1898
1899 SourceParseContext modulepc(this, modulesc, nullptr);
1900 if (!modulepc.init()) {
1901 return errorResult();
1902 }
1903
1904 ParseContext::VarScope varScope(this);
1905 if (!varScope.init(pc_)) {
1906 return errorResult();
1907 }
1908
1909 ModuleNodeType moduleNode;
1910 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)
;
1911
1912 AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(
1913 this, AwaitIsModuleKeyword);
1914 ListNode* stmtList;
1915 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)
;
1916
1917 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"
, 1917); AnnotateMozCrashReason("MOZ_ASSERT" "(" "stmtList->isKind(ParseNodeKind::StatementList)"
")"); do { *((volatile int*)__null) = 1917; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
1918 moduleNode->setBody(&stmtList->template as<ListNode>());
1919
1920 if (pc_->isAsync()) {
1921 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_generator_())) {
1922 return errorResult();
1923 }
1924
1925 if (!pc_->declareTopLevelDotGeneratorName()) {
1926 return errorResult();
1927 }
1928 }
1929
1930 TokenKind tt;
1931 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
1932 return errorResult();
1933 }
1934 if (tt != TokenKind::Eof) {
1935 error(JSMSG_GARBAGE_AFTER_INPUT, "module", TokenKindToDesc(tt));
1936 return errorResult();
1937 }
1938
1939 // Set the module to async if an await keyword was found at the top level.
1940 if (pc_->isAsync()) {
1941 pc_->sc()->asModuleContext()->builder.noteAsync(
1942 *this->compilationState_.moduleMetadata);
1943 }
1944
1945 // Generate the Import/Export tables and store in CompilationState.
1946 if (!modulesc->builder.buildTables(*this->compilationState_.moduleMetadata)) {
1947 return errorResult();
1948 }
1949
1950 // Check exported local bindings exist and mark them as closed over.
1951 StencilModuleMetadata& moduleMetadata =
1952 *this->compilationState_.moduleMetadata;
1953 for (auto entry : moduleMetadata.localExportEntries) {
1954 DeclaredNamePtr p = modulepc.varScope().lookupDeclaredName(entry.localName);
1955 if (!p) {
1956 UniqueChars str = this->parserAtoms().toPrintableString(entry.localName);
1957 if (!str) {
1958 ReportOutOfMemory(this->fc_);
1959 return errorResult();
1960 }
1961
1962 errorNoOffset(JSMSG_MISSING_EXPORT, str.get());
1963 return errorResult();
1964 }
1965
1966 p->value()->setClosedOver();
1967 }
1968
1969 // Reserve an environment slot for a "*namespace*" psuedo-binding and mark as
1970 // closed-over. We do not know until module linking if this will be used.
1971 if (!noteDeclaredName(
1972 TaggedParserAtomIndex::WellKnown::star_namespace_star_(),
1973 DeclarationKind::Const, pos())) {
1974 return errorResult();
1975 }
1976 modulepc.varScope()
1977 .lookupDeclaredName(
1978 TaggedParserAtomIndex::WellKnown::star_namespace_star_())
1979 ->value()
1980 ->setClosedOver();
1981
1982 if (options().deoptimizeModuleGlobalVars) {
1983 for (BindingIter bi = modulepc.varScope().bindings(pc_); bi; bi++) {
1984 bi.setClosedOver();
1985 }
1986 }
1987
1988 if (!CheckParseTree(this->fc_, alloc_, stmtList)) {
1989 return errorResult();
1990 }
1991
1992 ParseNode* node = stmtList;
1993 // Don't constant-fold inside "use asm" code, as this could create a parse
1994 // tree that doesn't type-check as asm.js.
1995 if (!pc_->useAsmOrInsideUseAsm()) {
1996 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
1997 return errorResult();
1998 }
1999 }
2000 stmtList = &node->as<ListNode>();
2001
2002 if (!this->setSourceMapInfo()) {
2003 return errorResult();
2004 }
2005
2006 // Private names not lexically defined must trigger a syntax error.
2007 if (!checkForUndefinedPrivateFields()) {
2008 return errorResult();
2009 }
2010
2011 if (!propagateFreeNamesAndMarkClosedOverBindings(modulepc.varScope())) {
2012 return errorResult();
2013 }
2014
2015 Maybe<ModuleScope::ParserData*> bindings =
2016 newModuleScopeData(modulepc.varScope());
2017 if (!bindings) {
2018 return errorResult();
2019 }
2020
2021 modulesc->bindings = *bindings;
2022 return moduleNode;
2023}
2024
2025template <typename Unit>
2026SyntaxParseHandler::ModuleNodeResult
2027Parser<SyntaxParseHandler, Unit>::moduleBody(ModuleSharedContext* modulesc) {
2028 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 2028); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 2028; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
2029 return errorResult();
2030}
2031
2032template <class ParseHandler>
2033typename ParseHandler::NameNodeResult
2034PerHandlerParser<ParseHandler>::newInternalDotName(TaggedParserAtomIndex name) {
2035 NameNodeType nameNode;
2036 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)
;
2037 if (!noteUsedName(name)) {
2038 return errorResult();
2039 }
2040 return nameNode;
2041}
2042
2043template <class ParseHandler>
2044typename ParseHandler::NameNodeResult
2045PerHandlerParser<ParseHandler>::newThisName() {
2046 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_this_());
2047}
2048
2049template <class ParseHandler>
2050typename ParseHandler::NameNodeResult
2051PerHandlerParser<ParseHandler>::newNewTargetName() {
2052 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_newTarget_());
2053}
2054
2055template <class ParseHandler>
2056typename ParseHandler::NameNodeResult
2057PerHandlerParser<ParseHandler>::newDotGeneratorName() {
2058 return newInternalDotName(TaggedParserAtomIndex::WellKnown::dot_generator_());
2059}
2060
2061template <class ParseHandler>
2062bool PerHandlerParser<ParseHandler>::finishFunctionScopes(
2063 bool isStandaloneFunction) {
2064 FunctionBox* funbox = pc_->functionBox();
2065
2066 if (funbox->hasParameterExprs) {
2067 if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->functionScope())) {
2068 return false;
2069 }
2070
2071 // Functions with parameter expressions utilize the FunctionScope for vars
2072 // generated by sloppy-direct-evals, as well as arguments (which are
2073 // lexicals bindings). If the function body has var bindings (or has a
2074 // sloppy-direct-eval that might), then an extra VarScope must be created
2075 // for them.
2076 if (VarScopeHasBindings(pc_) ||
2077 funbox->needsExtraBodyVarEnvironmentRegardlessOfBindings()) {
2078 funbox->setFunctionHasExtraBodyVarScope();
2079 }
2080 }
2081
2082 // See: JSFunction::needsCallObject()
2083 if (FunctionScopeHasClosedOverBindings(pc_) ||
2084 funbox->needsCallObjectRegardlessOfBindings()) {
2085 funbox->setNeedsFunctionEnvironmentObjects();
2086 }
2087
2088 if (funbox->isNamedLambda() && !isStandaloneFunction) {
2089 if (!propagateFreeNamesAndMarkClosedOverBindings(pc_->namedLambdaScope())) {
2090 return false;
2091 }
2092
2093 // See: JSFunction::needsNamedLambdaEnvironment()
2094 if (LexicalScopeHasClosedOverBindings(pc_, pc_->namedLambdaScope())) {
2095 funbox->setNeedsFunctionEnvironmentObjects();
2096 }
2097 }
2098
2099 return true;
2100}
2101
2102template <>
2103bool PerHandlerParser<FullParseHandler>::finishFunction(
2104 bool isStandaloneFunction /* = false */) {
2105 if (!finishFunctionScopes(isStandaloneFunction)) {
2106 return false;
2107 }
2108
2109 FunctionBox* funbox = pc_->functionBox();
2110 ScriptStencil& script = funbox->functionStencil();
2111
2112 if (funbox->isInterpreted()) {
2113 // BCE will need to generate bytecode for this.
2114 funbox->emitBytecode = true;
2115 this->compilationState_.nonLazyFunctionCount++;
2116 }
2117
2118 bool hasParameterExprs = funbox->hasParameterExprs;
2119
2120 if (hasParameterExprs) {
2121 Maybe<VarScope::ParserData*> bindings = newVarScopeData(pc_->varScope());
2122 if (!bindings) {
2123 return false;
2124 }
2125 funbox->setExtraVarScopeBindings(*bindings);
2126
2127 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"
, 2127); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == VarScopeHasBindings(pc_)"
")"); do { *((volatile int*)__null) = 2127; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2128 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"
, 2129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
")"); do { *((volatile int*)__null) = 2129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2129 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"
, 2129); AnnotateMozCrashReason("MOZ_ASSERT" "(" "bool(*bindings) == funbox->functionHasExtraBodyVarScope()"
")"); do { *((volatile int*)__null) = 2129; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2130 }
2131
2132 {
2133 Maybe<FunctionScope::ParserData*> bindings =
2134 newFunctionScopeData(pc_->functionScope(), hasParameterExprs);
2135 if (!bindings) {
2136 return false;
2137 }
2138 funbox->setFunctionScopeBindings(*bindings);
2139 }
2140
2141 if (funbox->isNamedLambda() && !isStandaloneFunction) {
2142 Maybe<LexicalScope::ParserData*> bindings =
2143 newLexicalScopeData(pc_->namedLambdaScope());
2144 if (!bindings) {
2145 return false;
2146 }
2147 funbox->setNamedLambdaBindings(*bindings);
2148 }
2149
2150 funbox->finishScriptFlags();
2151 funbox->copyFunctionFields(script);
2152
2153 if (this->compilationState_.isInitialStencil()) {
2154 ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
2155 funbox->copyFunctionExtraFields(scriptExtra);
2156 funbox->copyScriptExtraFields(scriptExtra);
2157 }
2158
2159 return true;
2160}
2161
2162template <>
2163bool PerHandlerParser<SyntaxParseHandler>::finishFunction(
2164 bool isStandaloneFunction /* = false */) {
2165 // The BaseScript for a lazily parsed function needs to know its set of
2166 // free variables and inner functions so that when it is fully parsed, we
2167 // can skip over any already syntax parsed inner functions and still
2168 // retain correct scope information.
2169
2170 if (!finishFunctionScopes(isStandaloneFunction)) {
2171 return false;
2172 }
2173
2174 FunctionBox* funbox = pc_->functionBox();
2175 ScriptStencil& script = funbox->functionStencil();
2176
2177 funbox->finishScriptFlags();
2178 funbox->copyFunctionFields(script);
2179
2180 ScriptStencilExtra& scriptExtra = funbox->functionExtraStencil();
2181 funbox->copyFunctionExtraFields(scriptExtra);
2182 funbox->copyScriptExtraFields(scriptExtra);
2183
2184 // Elide nullptr sentinels from end of binding list. These are inserted for
2185 // each scope regardless of if any bindings are actually closed over.
2186 {
2187 AtomVector& closedOver = pc_->closedOverBindingsForLazy();
2188 while (!closedOver.empty() && !closedOver.back()) {
2189 closedOver.popBack();
2190 }
2191 }
2192
2193 // Check if we will overflow the `ngcthings` field later.
2194 mozilla::CheckedUint32 ngcthings =
2195 mozilla::CheckedUint32(pc_->innerFunctionIndexesForLazy.length()) +
2196 mozilla::CheckedUint32(pc_->closedOverBindingsForLazy().length());
2197 if (!ngcthings.isValid()) {
2198 ReportAllocationOverflow(fc_);
2199 return false;
2200 }
2201
2202 // If there are no script-things, we can return early without allocating.
2203 if (ngcthings.value() == 0) {
2204 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"
, 2204); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!script.hasGCThings()"
")"); do { *((volatile int*)__null) = 2204; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2205 return true;
2206 }
2207
2208 TaggedScriptThingIndex* cursor = nullptr;
2209 if (!this->compilationState_.allocateGCThingsUninitialized(
2210 fc_, funbox->index(), ngcthings.value(), &cursor)) {
2211 return false;
2212 }
2213
2214 // Copy inner-function and closed-over-binding info for the stencil. The order
2215 // is important here. We emit functions first, followed by the bindings info.
2216 // The bindings list uses nullptr as delimiter to separates the bindings per
2217 // scope.
2218 //
2219 // See: FullParseHandler::nextLazyInnerFunction(),
2220 // FullParseHandler::nextLazyClosedOverBinding()
2221 for (const ScriptIndex& index : pc_->innerFunctionIndexesForLazy) {
2222 void* raw = &(*cursor++);
2223 new (raw) TaggedScriptThingIndex(index);
2224 }
2225 for (auto binding : pc_->closedOverBindingsForLazy()) {
2226 void* raw = &(*cursor++);
2227 if (binding) {
2228 this->parserAtoms().markUsedByStencil(binding, ParserAtom::Atomize::Yes);
2229 new (raw) TaggedScriptThingIndex(binding);
2230 } else {
2231 new (raw) TaggedScriptThingIndex();
2232 }
2233 }
2234
2235 return true;
2236}
2237
2238static YieldHandling GetYieldHandling(GeneratorKind generatorKind) {
2239 if (generatorKind == GeneratorKind::NotGenerator) {
2240 return YieldIsName;
2241 }
2242 return YieldIsKeyword;
2243}
2244
2245static AwaitHandling GetAwaitHandling(FunctionAsyncKind asyncKind) {
2246 if (asyncKind == FunctionAsyncKind::SyncFunction) {
2247 return AwaitIsName;
2248 }
2249 return AwaitIsKeyword;
2250}
2251
2252static FunctionFlags InitialFunctionFlags(FunctionSyntaxKind kind,
2253 GeneratorKind generatorKind,
2254 FunctionAsyncKind asyncKind,
2255 bool isSelfHosting) {
2256 FunctionFlags flags = {};
2257
2258 switch (kind) {
2259 case FunctionSyntaxKind::Expression:
2260 flags = (generatorKind == GeneratorKind::NotGenerator &&
2261 asyncKind == FunctionAsyncKind::SyncFunction
2262 ? FunctionFlags::INTERPRETED_LAMBDA
2263 : FunctionFlags::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC);
2264 break;
2265 case FunctionSyntaxKind::Arrow:
2266 flags = FunctionFlags::INTERPRETED_LAMBDA_ARROW;
2267 break;
2268 case FunctionSyntaxKind::Method:
2269 case FunctionSyntaxKind::FieldInitializer:
2270 case FunctionSyntaxKind::StaticClassBlock:
2271 flags = FunctionFlags::INTERPRETED_METHOD;
2272 break;
2273 case FunctionSyntaxKind::ClassConstructor:
2274 case FunctionSyntaxKind::DerivedClassConstructor:
2275 flags = FunctionFlags::INTERPRETED_CLASS_CTOR;
2276 break;
2277 case FunctionSyntaxKind::Getter:
2278 flags = FunctionFlags::INTERPRETED_GETTER;
2279 break;
2280 case FunctionSyntaxKind::Setter:
2281 flags = FunctionFlags::INTERPRETED_SETTER;
2282 break;
2283 default:
2284 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"
, 2284); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == FunctionSyntaxKind::Statement"
")"); do { *((volatile int*)__null) = 2284; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2285 flags = (generatorKind == GeneratorKind::NotGenerator &&
2286 asyncKind == FunctionAsyncKind::SyncFunction
2287 ? FunctionFlags::INTERPRETED_NORMAL
2288 : FunctionFlags::INTERPRETED_GENERATOR_OR_ASYNC);
2289 }
2290
2291 if (isSelfHosting) {
2292 flags.setIsSelfHostedBuiltin();
2293 }
2294
2295 return flags;
2296}
2297
2298template <typename Unit>
2299FullParseHandler::FunctionNodeResult
2300Parser<FullParseHandler, Unit>::standaloneFunction(
2301 const Maybe<uint32_t>& parameterListEnd, FunctionSyntaxKind syntaxKind,
2302 GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
2303 Directives inheritedDirectives, Directives* newDirectives) {
2304 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"
, 2304); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 2304; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2305 // Skip prelude.
2306 TokenKind tt;
2307 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2308 return errorResult();
2309 }
2310 if (asyncKind == FunctionAsyncKind::AsyncFunction) {
2311 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"
, 2311); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Async"
")"); do { *((volatile int*)__null) = 2311; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2312 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2313 return errorResult();
2314 }
2315 }
2316 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"
, 2316); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Function"
")"); do { *((volatile int*)__null) = 2316; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2317
2318 if (!tokenStream.getToken(&tt)) {
2319 return errorResult();
2320 }
2321 if (generatorKind == GeneratorKind::Generator) {
2322 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"
, 2322); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::Mul"
")"); do { *((volatile int*)__null) = 2322; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2323 if (!tokenStream.getToken(&tt)) {
2324 return errorResult();
2325 }
2326 }
2327
2328 // Skip function name, if present.
2329 TaggedParserAtomIndex explicitName;
2330 if (TokenKindIsPossibleIdentifierName(tt)) {
2331 explicitName = anyChars.currentName();
2332 } else {
2333 anyChars.ungetToken();
2334 }
2335
2336 FunctionNodeType funNode;
2337 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)
;
2338
2339 ParamsBodyNodeType argsbody;
2340 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)
;
2341 funNode->setBody(argsbody);
2342
2343 bool isSelfHosting = options().selfHostingMode;
2344 FunctionFlags flags =
2345 InitialFunctionFlags(syntaxKind, generatorKind, asyncKind, isSelfHosting);
2346 FunctionBox* funbox =
2347 newFunctionBox(funNode, explicitName, flags, /* toStringStart = */ 0,
2348 inheritedDirectives, generatorKind, asyncKind);
2349 if (!funbox) {
2350 return errorResult();
2351 }
2352
2353 // Function is not syntactically part of another script.
2354 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"
, 2354); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->index() == CompilationStencil::TopLevelIndex"
")"); do { *((volatile int*)__null) = 2354; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2355
2356 funbox->initStandalone(this->compilationState_.scopeContext, syntaxKind);
2357
2358 SourceParseContext funpc(this, funbox, newDirectives);
2359 if (!funpc.init()) {
2360 return errorResult();
2361 }
2362
2363 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
2364 AwaitHandling awaitHandling = GetAwaitHandling(asyncKind);
2365 AutoAwaitIsKeyword<FullParseHandler, Unit> awaitIsKeyword(this,
2366 awaitHandling);
2367 if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
2368 syntaxKind, parameterListEnd,
2369 /* isStandaloneFunction = */ true)) {
2370 return errorResult();
2371 }
2372
2373 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2374 return errorResult();
2375 }
2376 if (tt != TokenKind::Eof) {
2377 error(JSMSG_GARBAGE_AFTER_INPUT, "function body", TokenKindToDesc(tt));
2378 return errorResult();
2379 }
2380
2381 if (!CheckParseTree(this->fc_, alloc_, funNode)) {
2382 return errorResult();
2383 }
2384
2385 ParseNode* node = funNode;
2386 // Don't constant-fold inside "use asm" code, as this could create a parse
2387 // tree that doesn't type-check as asm.js.
2388 if (!pc_->useAsmOrInsideUseAsm()) {
2389 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
2390 return errorResult();
2391 }
2392 }
2393 funNode = &node->as<FunctionNode>();
2394
2395 if (!checkForUndefinedPrivateFields(nullptr)) {
2396 return errorResult();
2397 }
2398
2399 if (!this->setSourceMapInfo()) {
2400 return errorResult();
2401 }
2402
2403 return funNode;
2404}
2405
2406template <class ParseHandler, typename Unit>
2407typename ParseHandler::LexicalScopeNodeResult
2408GeneralParser<ParseHandler, Unit>::functionBody(InHandling inHandling,
2409 YieldHandling yieldHandling,
2410 FunctionSyntaxKind kind,
2411 FunctionBodyType type) {
2412 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"
, 2412); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 2412; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2413
2414#ifdef DEBUG1
2415 uint32_t startYieldOffset = pc_->lastYieldOffset;
2416#endif
2417
2418 Node body;
2419 if (type == StatementListBody) {
2420 bool inheritedStrict = pc_->sc()->strict();
2421 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)
;
2422
2423 // When we transitioned from non-strict to strict mode, we need to
2424 // validate that all parameter names are valid strict mode names.
2425 if (!inheritedStrict && pc_->sc()->strict()) {
2426 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"
, 2428); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2428; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2427 "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"
, 2428); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2428; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
2428 "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"
, 2428); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 2428; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
2429 if (!hasValidSimpleStrictParameterNames()) {
2430 // Request that this function be reparsed as strict to report
2431 // the invalid parameter name at the correct source location.
2432 pc_->newDirectives->setStrict();
2433 return errorResult();
2434 }
2435 }
2436 } else {
2437 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"
, 2437); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == ExpressionBody"
")"); do { *((volatile int*)__null) = 2437; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2438
2439 // Async functions are implemented as generators, and generators are
2440 // assumed to be statement lists, to prepend initial `yield`.
2441 ListNodeType stmtList = null();
2442 if (pc_->isAsync()) {
2443 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)
;
2444 }
2445
2446 Node kid;
2447 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)
2448 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)
;
2449
2450 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)
;
2451
2452 if (pc_->isAsync()) {
2453 handler_.addStatementToList(stmtList, body);
2454 body = stmtList;
2455 }
2456 }
2457
2458 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"
, 2459); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->lastYieldOffset == startYieldOffset"
")"); do { *((volatile int*)__null) = 2459; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2459 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"
, 2459); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->lastYieldOffset == startYieldOffset"
")"); do { *((volatile int*)__null) = 2459; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2460 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"
, 2460); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind != FunctionSyntaxKind::Arrow"
")"); do { *((volatile int*)__null) = 2460; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2461 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"
, 2461); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == StatementListBody"
")"); do { *((volatile int*)__null) = 2461; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2462
2463 if (pc_->needsDotGeneratorName()) {
2464 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"
, 2464); AnnotateMozCrashReason("MOZ_ASSERT" "(" "type == StatementListBody"
")"); do { *((volatile int*)__null) = 2464; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2465 if (!pc_->declareDotGeneratorName()) {
2466 return errorResult();
2467 }
2468 if (pc_->isGenerator()) {
2469 NameNodeType generator;
2470 MOZ_TRY_VAR(generator, newDotGeneratorName())do { auto mozTryVarTempResult_ = (newDotGeneratorName()); if (
(__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0))) { return
mozTryVarTempResult_.propagateErr(); } (generator) = mozTryVarTempResult_
.unwrap(); } while (0)
;
2471 if (!handler_.prependInitialYield(handler_.asListNode(body), generator)) {
2472 return errorResult();
2473 }
2474 }
2475 }
2476
2477 if (pc_->numberOfArgumentsNames > 0 || kind == FunctionSyntaxKind::Arrow) {
2478 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"
, 2478); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isFunctionBox()"
")"); do { *((volatile int*)__null) = 2478; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2479 pc_->sc()->setIneligibleForArgumentsLength();
2480 }
2481
2482 // Declare the 'arguments', 'this', and 'new.target' bindings if necessary
2483 // before finishing up the scope so these special bindings get marked as
2484 // closed over if necessary. Arrow functions don't have these bindings.
2485 if (kind != FunctionSyntaxKind::Arrow) {
2486 bool canSkipLazyClosedOverBindings = handler_.reuseClosedOverBindings();
2487 if (!pc_->declareFunctionArgumentsObject(usedNames_,
2488 canSkipLazyClosedOverBindings)) {
2489 return errorResult();
2490 }
2491 if (!pc_->declareFunctionThis(usedNames_, canSkipLazyClosedOverBindings)) {
2492 return errorResult();
2493 }
2494 if (!pc_->declareNewTarget(usedNames_, canSkipLazyClosedOverBindings)) {
2495 return errorResult();
2496 }
2497 }
2498
2499 return finishLexicalScope(pc_->varScope(), body, ScopeKind::FunctionLexical);
2500}
2501
2502template <class ParseHandler, typename Unit>
2503bool GeneralParser<ParseHandler, Unit>::matchOrInsertSemicolon(
2504 Modifier modifier /* = TokenStream::SlashIsRegExp */) {
2505 TokenKind tt = TokenKind::Eof;
2506 if (!tokenStream.peekTokenSameLine(&tt, modifier)) {
2507 return false;
2508 }
2509 if (tt != TokenKind::Eof && tt != TokenKind::Eol && tt != TokenKind::Semi &&
2510 tt != TokenKind::RightCurly) {
2511 /*
2512 * When current token is `await` and it's outside of async function,
2513 * it's possibly intended to be an await expression.
2514 *
2515 * await f();
2516 * ^
2517 * |
2518 * tried to insert semicolon here
2519 *
2520 * Detect this situation and throw an understandable error. Otherwise
2521 * we'd throw a confusing "unexpected token: (unexpected token)" error.
2522 */
2523 if (!pc_->isAsync() && anyChars.currentToken().type == TokenKind::Await) {
2524 error(JSMSG_AWAIT_OUTSIDE_ASYNC_OR_MODULE);
2525 return false;
2526 }
2527 if (!yieldExpressionsSupported() &&
2528 anyChars.currentToken().type == TokenKind::Yield) {
2529 error(JSMSG_YIELD_OUTSIDE_GENERATOR);
2530 return false;
2531 }
2532
2533 /* Advance the scanner for proper error location reporting. */
2534 tokenStream.consumeKnownToken(tt, modifier);
2535 error(JSMSG_UNEXPECTED_TOKEN_NO_EXPECT, TokenKindToDesc(tt));
2536 return false;
2537 }
2538 bool matched;
2539 return tokenStream.matchToken(&matched, TokenKind::Semi, modifier);
2540}
2541
2542bool ParserBase::leaveInnerFunction(ParseContext* outerpc) {
2543 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"
, 2543); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_ != outerpc"
")"); do { *((volatile int*)__null) = 2543; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2544
2545 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"
, 2546); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outerpc->functionBox()->index() < pc_->functionBox()->index()"
")"); do { *((volatile int*)__null) = 2546; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2546 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"
, 2546); AnnotateMozCrashReason("MOZ_ASSERT" "(" "outerpc->functionBox()->index() < pc_->functionBox()->index()"
")"); do { *((volatile int*)__null) = 2546; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2547
2548 // If the current function allows super.property but cannot have a home
2549 // object, i.e., it is an arrow function, we need to propagate the flag to
2550 // the outer ParseContext.
2551 if (pc_->superScopeNeedsHomeObject()) {
2552 if (!pc_->isArrowFunction()) {
2553 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"
, 2553); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->needsHomeObject()"
")"); do { *((volatile int*)__null) = 2553; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2554 } else {
2555 outerpc->setSuperScopeNeedsHomeObject();
2556 }
2557 }
2558
2559 // Lazy functions inner to another lazy function need to be remembered by
2560 // the inner function so that if the outer function is eventually parsed
2561 // we do not need any further parsing or processing of the inner function.
2562 //
2563 // Append the inner function index here unconditionally; the vector is only
2564 // used if the Parser using outerpc is a syntax parsing. See
2565 // GeneralParser<SyntaxParseHandler>::finishFunction.
2566 if (!outerpc->innerFunctionIndexesForLazy.append(
2567 pc_->functionBox()->index())) {
2568 return false;
2569 }
2570
2571 PropagateTransitiveParseFlags(pc_->functionBox(), outerpc->sc());
2572
2573 return true;
2574}
2575
2576TaggedParserAtomIndex ParserBase::prefixAccessorName(
2577 PropertyType propType, TaggedParserAtomIndex propAtom) {
2578 StringBuffer prefixed(fc_);
2579 if (propType == PropertyType::Setter) {
2580 if (!prefixed.append("set ")) {
2581 return TaggedParserAtomIndex::null();
2582 }
2583 } else {
2584 if (!prefixed.append("get ")) {
2585 return TaggedParserAtomIndex::null();
2586 }
2587 }
2588 if (!prefixed.append(this->parserAtoms(), propAtom)) {
2589 return TaggedParserAtomIndex::null();
2590 }
2591 return prefixed.finishParserAtom(this->parserAtoms(), fc_);
2592}
2593
2594template <class ParseHandler, typename Unit>
2595void GeneralParser<ParseHandler, Unit>::setFunctionStartAtPosition(
2596 FunctionBox* funbox, TokenPos pos) const {
2597 uint32_t startLine;
2598 JS::LimitedColumnNumberOneOrigin startColumn;
2599 tokenStream.computeLineAndColumn(pos.begin, &startLine, &startColumn);
2600
2601 // NOTE: `Debugger::CallData::findScripts` relies on sourceStart and
2602 // lineno/column referring to the same location.
2603 funbox->setStart(pos.begin, startLine, startColumn);
2604}
2605
2606template <class ParseHandler, typename Unit>
2607void GeneralParser<ParseHandler, Unit>::setFunctionStartAtCurrentToken(
2608 FunctionBox* funbox) const {
2609 setFunctionStartAtPosition(funbox, anyChars.currentToken().pos);
2610}
2611
2612template <class ParseHandler, typename Unit>
2613bool GeneralParser<ParseHandler, Unit>::functionArguments(
2614 YieldHandling yieldHandling, FunctionSyntaxKind kind,
2615 FunctionNodeType funNode) {
2616 FunctionBox* funbox = pc_->functionBox();
2617
2618 // Modifier for the following tokens.
2619 // TokenStream::SlashIsDiv for the following cases:
2620 // async a => 1
2621 // ^
2622 //
2623 // (a) => 1
2624 // ^
2625 //
2626 // async (a) => 1
2627 // ^
2628 //
2629 // function f(a) {}
2630 // ^
2631 //
2632 // TokenStream::SlashIsRegExp for the following case:
2633 // a => 1
2634 // ^
2635 Modifier firstTokenModifier =
2636 kind != FunctionSyntaxKind::Arrow || funbox->isAsync()
2637 ? TokenStream::SlashIsDiv
2638 : TokenStream::SlashIsRegExp;
2639 TokenKind tt;
2640 if (!tokenStream.getToken(&tt, firstTokenModifier)) {
2641 return false;
2642 }
2643
2644 if (kind == FunctionSyntaxKind::Arrow && TokenKindIsPossibleIdentifier(tt)) {
2645 // Record the start of function source (for FunctionToString).
2646 setFunctionStartAtCurrentToken(funbox);
2647
2648 ParamsBodyNodeType argsbody;
2649 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)
;
2650 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
2651
2652 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
2653 if (!name) {
2654 return false;
2655 }
2656
2657 constexpr bool disallowDuplicateParams = true;
2658 bool duplicatedParam = false;
2659 if (!notePositionalFormalParameter(funNode, name, pos().begin,
2660 disallowDuplicateParams,
2661 &duplicatedParam)) {
2662 return false;
2663 }
2664 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"
, 2664); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!duplicatedParam"
")"); do { *((volatile int*)__null) = 2664; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2665 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"
, 2665); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->positionalFormalParameterNames().length() == 1"
")"); do { *((volatile int*)__null) = 2665; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2666
2667 funbox->setLength(1);
2668 funbox->setArgCount(1);
2669 return true;
2670 }
2671
2672 if (tt != TokenKind::LeftParen) {
2673 error(kind == FunctionSyntaxKind::Arrow ? JSMSG_BAD_ARROW_ARGS
2674 : JSMSG_PAREN_BEFORE_FORMAL);
2675 return false;
2676 }
2677
2678 // Record the start of function source (for FunctionToString).
2679 setFunctionStartAtCurrentToken(funbox);
2680
2681 ParamsBodyNodeType argsbody;
2682 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)
;
2683 handler_.setFunctionFormalParametersAndBody(funNode, argsbody);
2684
2685 bool matched;
2686 if (!tokenStream.matchToken(&matched, TokenKind::RightParen,
2687 TokenStream::SlashIsRegExp)) {
2688 return false;
2689 }
2690 if (!matched) {
2691 bool hasRest = false;
2692 bool hasDefault = false;
2693 bool duplicatedParam = false;
2694 bool disallowDuplicateParams =
2695 kind == FunctionSyntaxKind::Arrow ||
2696 kind == FunctionSyntaxKind::Method ||
2697 kind == FunctionSyntaxKind::FieldInitializer ||
2698 kind == FunctionSyntaxKind::ClassConstructor;
2699 AtomVector& positionalFormals = pc_->positionalFormalParameterNames();
2700
2701 if (kind == FunctionSyntaxKind::Getter) {
2702 error(JSMSG_ACCESSOR_WRONG_ARGS, "getter", "no", "s");
2703 return false;
2704 }
2705
2706 while (true) {
2707 if (hasRest) {
2708 error(JSMSG_PARAMETER_AFTER_REST);
2709 return false;
2710 }
2711
2712 TokenKind tt;
2713 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2714 return false;
2715 }
2716
2717 if (tt == TokenKind::TripleDot) {
2718 if (kind == FunctionSyntaxKind::Setter) {
2719 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2720 return false;
2721 }
2722
2723 disallowDuplicateParams = true;
2724 if (duplicatedParam) {
2725 // Has duplicated args before the rest parameter.
2726 error(JSMSG_BAD_DUP_ARGS);
2727 return false;
2728 }
2729
2730 hasRest = true;
2731 funbox->setHasRest();
2732
2733 if (!tokenStream.getToken(&tt)) {
2734 return false;
2735 }
2736
2737 if (!TokenKindIsPossibleIdentifier(tt) &&
2738 tt != TokenKind::LeftBracket && tt != TokenKind::LeftCurly) {
2739 error(JSMSG_NO_REST_NAME);
2740 return false;
2741 }
2742 }
2743
2744 switch (tt) {
2745 case TokenKind::LeftBracket:
2746 case TokenKind::LeftCurly: {
2747 disallowDuplicateParams = true;
2748 if (duplicatedParam) {
2749 // Has duplicated args before the destructuring parameter.
2750 error(JSMSG_BAD_DUP_ARGS);
2751 return false;
2752 }
2753
2754 funbox->hasDestructuringArgs = true;
2755
2756 Node destruct;
2757 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)
2758 destruct,do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2759 destructuringDeclarationWithoutYieldOrAwait(do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
2760 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)
2761 false)do { auto parserTryVarTempResult_ = (destructuringDeclarationWithoutYieldOrAwait
( DeclarationKind::FormalParameter, yieldHandling, tt)); if (
(__builtin_expect(!!(parserTryVarTempResult_.isErr()), 0))) {
return (false); } (destruct) = parserTryVarTempResult_.unwrap
(); } while (0)
;
2762
2763 if (!noteDestructuredPositionalFormalParameter(funNode, destruct)) {
2764 return false;
2765 }
2766
2767 break;
2768 }
2769
2770 default: {
2771 if (!TokenKindIsPossibleIdentifier(tt)) {
2772 error(JSMSG_MISSING_FORMAL);
2773 return false;
2774 }
2775
2776 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
2777 if (!name) {
2778 return false;
2779 }
2780
2781 if (!notePositionalFormalParameter(funNode, name, pos().begin,
2782 disallowDuplicateParams,
2783 &duplicatedParam)) {
2784 return false;
2785 }
2786 if (duplicatedParam) {
2787 funbox->hasDuplicateParameters = true;
2788 }
2789
2790 break;
2791 }
2792 }
2793
2794 if (positionalFormals.length() >= ARGNO_LIMIT) {
2795 error(JSMSG_TOO_MANY_FUN_ARGS);
2796 return false;
2797 }
2798
2799 bool matched;
2800 if (!tokenStream.matchToken(&matched, TokenKind::Assign,
2801 TokenStream::SlashIsRegExp)) {
2802 return false;
2803 }
2804 if (matched) {
2805 if (hasRest) {
2806 error(JSMSG_REST_WITH_DEFAULT);
2807 return false;
2808 }
2809 disallowDuplicateParams = true;
2810 if (duplicatedParam) {
2811 error(JSMSG_BAD_DUP_ARGS);
2812 return false;
2813 }
2814
2815 if (!hasDefault) {
2816 hasDefault = true;
2817
2818 // The Function.length property is the number of formals
2819 // before the first default argument.
2820 funbox->setLength(positionalFormals.length() - 1);
2821 }
2822 funbox->hasParameterExprs = true;
2823
2824 Node def_expr;
2825 MOZ_TRY_VAR_OR_RETURN(do { auto parserTryVarTempResult_ = (assignExprWithoutYieldOrAwait
(yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (def_expr) = parserTryVarTempResult_
.unwrap(); } while (0)
2826 def_expr, assignExprWithoutYieldOrAwait(yieldHandling), false)do { auto parserTryVarTempResult_ = (assignExprWithoutYieldOrAwait
(yieldHandling)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (def_expr) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2827 if (!handler_.setLastFunctionFormalParameterDefault(funNode,
2828 def_expr)) {
2829 return false;
2830 }
2831 }
2832
2833 // Setter syntax uniquely requires exactly one argument.
2834 if (kind == FunctionSyntaxKind::Setter) {
2835 break;
2836 }
2837
2838 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
2839 TokenStream::SlashIsRegExp)) {
2840 return false;
2841 }
2842 if (!matched) {
2843 break;
2844 }
2845
2846 if (!hasRest) {
2847 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
2848 return false;
2849 }
2850 if (tt == TokenKind::RightParen) {
2851 break;
2852 }
2853 }
2854 }
2855
2856 TokenKind tt;
2857 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2858 return false;
2859 }
2860 if (tt != TokenKind::RightParen) {
2861 if (kind == FunctionSyntaxKind::Setter) {
2862 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2863 return false;
2864 }
2865
2866 error(JSMSG_PAREN_AFTER_FORMAL);
2867 return false;
2868 }
2869
2870 if (!hasDefault) {
2871 funbox->setLength(positionalFormals.length() - hasRest);
2872 }
2873
2874 funbox->setArgCount(positionalFormals.length());
2875 } else if (kind == FunctionSyntaxKind::Setter) {
2876 error(JSMSG_ACCESSOR_WRONG_ARGS, "setter", "one", "");
2877 return false;
2878 }
2879
2880 return true;
2881}
2882
2883template <typename Unit>
2884bool Parser<FullParseHandler, Unit>::skipLazyInnerFunction(
2885 FunctionNode* funNode, uint32_t toStringStart, bool tryAnnexB) {
2886 // When a lazily-parsed function is called, we only fully parse (and emit)
2887 // that function, not any of its nested children. The initial syntax-only
2888 // parse recorded the free variables of nested functions and their extents,
2889 // so we can skip over them after accounting for their free variables.
2890
2891 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"
, 2891); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->isOutermostOfCurrentCompile()"
")"); do { *((volatile int*)__null) = 2891; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2892 handler_.nextLazyInnerFunction();
2893 const ScriptStencil& cachedData = handler_.cachedScriptData();
2894 const ScriptStencilExtra& cachedExtra = handler_.cachedScriptExtra();
2895 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"
, 2895); AnnotateMozCrashReason("MOZ_ASSERT" "(" "toStringStart == cachedExtra.extent.toStringStart"
")"); do { *((volatile int*)__null) = 2895; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2896
2897 FunctionBox* funbox = newFunctionBox(funNode, cachedData, cachedExtra);
2898 if (!funbox) {
2899 return false;
2900 }
2901
2902 ScriptStencil& script = funbox->functionStencil();
2903 funbox->copyFunctionFields(script);
2904
2905 // If the inner lazy function is class constructor, connect it to the class
2906 // statement/expression we are parsing.
2907 if (funbox->isClassConstructor()) {
2908 auto classStmt =
2909 pc_->template findInnermostStatement<ParseContext::ClassStatement>();
2910 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"
, 2910); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!classStmt->constructorBox"
")"); do { *((volatile int*)__null) = 2910; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
2911 classStmt->constructorBox = funbox;
2912 }
2913
2914 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"
, 2915); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->index() < funbox->index()"
")"); do { *((volatile int*)__null) = 2915; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
2915 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"
, 2915); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->functionBox()->index() < funbox->index()"
")"); do { *((volatile int*)__null) = 2915; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
2916
2917 PropagateTransitiveParseFlags(funbox, pc_->sc());
2918
2919 if (!tokenStream.advance(funbox->extent().sourceEnd)) {
2920 return false;
2921 }
2922
2923 // Append possible Annex B function box only upon successfully parsing.
2924 if (tryAnnexB &&
2925 !pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
2926 return false;
2927 }
2928
2929 return true;
2930}
2931
2932template <typename Unit>
2933bool Parser<SyntaxParseHandler, Unit>::skipLazyInnerFunction(
2934 FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
2935 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"
, 2935); AnnotateMozCrashReason("MOZ_CRASH(" "Cannot skip lazy inner functions when syntax parsing"
")"); do { *((volatile int*)__null) = 2935; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
2936}
2937
2938template <class ParseHandler, typename Unit>
2939bool GeneralParser<ParseHandler, Unit>::skipLazyInnerFunction(
2940 FunctionNodeType funNode, uint32_t toStringStart, bool tryAnnexB) {
2941 return asFinalParser()->skipLazyInnerFunction(funNode, toStringStart,
2942 tryAnnexB);
2943}
2944
2945template <class ParseHandler, typename Unit>
2946bool GeneralParser<ParseHandler, Unit>::addExprAndGetNextTemplStrToken(
2947 YieldHandling yieldHandling, ListNodeType nodeList, TokenKind* ttp) {
2948 Node pn;
2949 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)
2950 false)do { auto parserTryVarTempResult_ = (expr(InAllowed, yieldHandling
, TripledotProhibited)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (pn) = parserTryVarTempResult_
.unwrap(); } while (0)
;
2951 handler_.addList(nodeList, pn);
2952
2953 TokenKind tt;
2954 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
2955 return false;
2956 }
2957 if (tt != TokenKind::RightCurly) {
2958 error(JSMSG_TEMPLSTR_UNTERM_EXPR);
2959 return false;
2960 }
2961
2962 return tokenStream.getTemplateToken(ttp);
2963}
2964
2965template <class ParseHandler, typename Unit>
2966bool GeneralParser<ParseHandler, Unit>::taggedTemplate(
2967 YieldHandling yieldHandling, ListNodeType tagArgsList, TokenKind tt) {
2968 CallSiteNodeType callSiteObjNode;
2969 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)
2970 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)
;
2971 handler_.addList(tagArgsList, callSiteObjNode);
2972
2973 pc_->sc()->setHasCallSiteObj();
2974
2975 while (true) {
2976 if (!appendToCallSiteObj(callSiteObjNode)) {
2977 return false;
2978 }
2979 if (tt != TokenKind::TemplateHead) {
2980 break;
2981 }
2982
2983 if (!addExprAndGetNextTemplStrToken(yieldHandling, tagArgsList, &tt)) {
2984 return false;
2985 }
2986 }
2987 handler_.setEndPosition(tagArgsList, callSiteObjNode);
2988 return true;
2989}
2990
2991template <class ParseHandler, typename Unit>
2992typename ParseHandler::ListNodeResult
2993GeneralParser<ParseHandler, Unit>::templateLiteral(
2994 YieldHandling yieldHandling) {
2995 NameNodeType literal;
2996 MOZ_TRY_VAR(literal, noSubstitutionUntaggedTemplate())do { auto mozTryVarTempResult_ = (noSubstitutionUntaggedTemplate
()); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
2997
2998 ListNodeType nodeList;
2999 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)
3000 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)
;
3001
3002 TokenKind tt;
3003 do {
3004 if (!addExprAndGetNextTemplStrToken(yieldHandling, nodeList, &tt)) {
3005 return errorResult();
3006 }
3007
3008 MOZ_TRY_VAR(literal, noSubstitutionUntaggedTemplate())do { auto mozTryVarTempResult_ = (noSubstitutionUntaggedTemplate
()); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr()), 0
))) { return mozTryVarTempResult_.propagateErr(); } (literal)
= mozTryVarTempResult_.unwrap(); } while (0)
;
3009
3010 handler_.addList(nodeList, literal);
3011 } while (tt == TokenKind::TemplateHead);
3012 return nodeList;
3013}
3014
3015template <class ParseHandler, typename Unit>
3016typename ParseHandler::FunctionNodeResult
3017GeneralParser<ParseHandler, Unit>::functionDefinition(
3018 FunctionNodeType funNode, uint32_t toStringStart, InHandling inHandling,
3019 YieldHandling yieldHandling, TaggedParserAtomIndex funName,
3020 FunctionSyntaxKind kind, GeneratorKind generatorKind,
3021 FunctionAsyncKind asyncKind, bool tryAnnexB /* = false */) {
3022 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"
, 3022); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funName" ")"
); do { *((volatile int*)__null) = 3022; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3023
3024 // If we see any inner function, note it on our current context. The bytecode
3025 // emitter may eliminate the function later, but we use a conservative
3026 // definition for consistency between lazy and full parsing.
3027 pc_->sc()->setHasInnerFunctions();
3028
3029 // When fully parsing a lazy script, we do not fully reparse its inner
3030 // functions, which are also lazy. Instead, their free variables and source
3031 // extents are recorded and may be skipped.
3032 if (handler_.reuseLazyInnerFunctions()) {
3033 if (!skipLazyInnerFunction(funNode, toStringStart, tryAnnexB)) {
3034 return errorResult();
3035 }
3036
3037 return funNode;
3038 }
3039
3040 bool isSelfHosting = options().selfHostingMode;
3041 FunctionFlags flags =
3042 InitialFunctionFlags(kind, generatorKind, asyncKind, isSelfHosting);
3043
3044 // Self-hosted functions with special function names require extended slots
3045 // for various purposes.
3046 bool forceExtended =
3047 isSelfHosting && funName &&
3048 this->parserAtoms().isExtendedUnclonedSelfHostedFunctionName(funName);
3049 if (forceExtended) {
3050 flags.setIsExtended();
3051 }
3052
3053 // Speculatively parse using the directives of the parent parsing context.
3054 // If a directive is encountered (e.g., "use strict") that changes how the
3055 // function should have been parsed, we backup and reparse with the new set
3056 // of directives.
3057 Directives directives(pc_);
3058 Directives newDirectives = directives;
3059
3060 Position start(tokenStream);
3061 auto startObj = this->compilationState_.getPosition();
3062
3063 // Parse the inner function. The following is a loop as we may attempt to
3064 // reparse a function due to failed syntax parsing and encountering new
3065 // "use foo" directives.
3066 while (true) {
3067 if (trySyntaxParseInnerFunction(&funNode, funName, flags, toStringStart,
3068 inHandling, yieldHandling, kind,
3069 generatorKind, asyncKind, tryAnnexB,
3070 directives, &newDirectives)) {
3071 break;
3072 }
3073
3074 // Return on error.
3075 if (anyChars.hadError() || directives == newDirectives) {
3076 return errorResult();
3077 }
3078
3079 // Assignment must be monotonic to prevent infinitely attempting to
3080 // reparse.
3081 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"
, 3081); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newDirectives.strict()"
")"); do { *((volatile int*)__null) = 3081; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3082 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"
, 3082); AnnotateMozCrashReason("MOZ_ASSERT" "(" "newDirectives.asmJS()"
")"); do { *((volatile int*)__null) = 3082; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
3083 directives = newDirectives;
3084
3085 // Rewind to retry parsing with new directives applied.
3086 tokenStream.rewind(start);
3087 this->compilationState_.rewind(startObj);
3088
3089 // functionFormalParametersAndBody may have already set body before failing.
3090 handler_.setFunctionFormalParametersAndBody(funNode, null());
3091 }
3092
3093 return funNode;
3094}
3095
3096template <typename Unit>
3097bool Parser<FullParseHandler, Unit>::advancePastSyntaxParsedFunction(
3098 SyntaxParser* syntaxParser) {
3099 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"
, 3099); AnnotateMozCrashReason("MOZ_ASSERT" "(" "getSyntaxParser() == syntaxParser"
")"); do { *((volatile int*)__null) = 3099; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3100
3101 // Advance this parser over tokens processed by the syntax parser.
3102 Position currentSyntaxPosition(syntaxParser->tokenStream);
3103 if (!tokenStream.fastForward(currentSyntaxPosition, syntaxParser->anyChars)) {
3104 return false;
3105 }
3106
3107 anyChars.adoptState(syntaxParser->anyChars);
3108 tokenStream.adoptState(syntaxParser->tokenStream);
3109 return true;
3110}
3111
3112template <typename Unit>
3113bool Parser<FullParseHandler, Unit>::trySyntaxParseInnerFunction(
3114 FunctionNode** funNode, TaggedParserAtomIndex explicitName,
3115 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3116 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3117 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3118 Directives inheritedDirectives, Directives* newDirectives) {
3119 // Try a syntax parse for this inner function.
3120 do {
3121 // If we're assuming this function is an IIFE, always perform a full
3122 // parse to avoid the overhead of a lazy syntax-only parse. Although
3123 // the prediction may be incorrect, IIFEs are common enough that it
3124 // pays off for lots of code.
3125 if ((*funNode)->isLikelyIIFE() &&
3126 generatorKind == GeneratorKind::NotGenerator &&
3127 asyncKind == FunctionAsyncKind::SyncFunction) {
3128 break;
3129 }
3130
3131 SyntaxParser* syntaxParser = getSyntaxParser();
3132 if (!syntaxParser) {
3133 break;
3134 }
3135
3136 UsedNameTracker::RewindToken token = usedNames_.getRewindToken();
3137 auto statePosition = this->compilationState_.getPosition();
3138
3139 // Move the syntax parser to the current position in the stream. In the
3140 // common case this seeks forward, but it'll also seek backward *at least*
3141 // when arrow functions appear inside arrow function argument defaults
3142 // (because we rewind to reparse arrow functions once we're certain they're
3143 // arrow functions):
3144 //
3145 // var x = (y = z => 2) => q;
3146 // // ^ we first seek to here to syntax-parse this function
3147 // // ^ then we seek back to here to syntax-parse the outer function
3148 Position currentPosition(tokenStream);
3149 if (!syntaxParser->tokenStream.seekTo(currentPosition, anyChars)) {
3150 return false;
3151 }
3152
3153 // Make a FunctionBox before we enter the syntax parser, because |pn|
3154 // still expects a FunctionBox to be attached to it during BCE, and
3155 // the syntax parser cannot attach one to it.
3156 FunctionBox* funbox =
3157 newFunctionBox(*funNode, explicitName, flags, toStringStart,
3158 inheritedDirectives, generatorKind, asyncKind);
3159 if (!funbox) {
3160 return false;
3161 }
3162 funbox->initWithEnclosingParseContext(pc_, kind);
3163
3164 auto syntaxNodeResult = syntaxParser->innerFunctionForFunctionBox(
3165 SyntaxParseHandler::Node::NodeGeneric, pc_, funbox, inHandling,
3166 yieldHandling, kind, newDirectives);
3167 if (syntaxNodeResult.isErr()) {
3168 if (syntaxParser->hadAbortedSyntaxParse()) {
3169 // Try again with a full parse. UsedNameTracker needs to be
3170 // rewound to just before we tried the syntax parse for
3171 // correctness.
3172 syntaxParser->clearAbortedSyntaxParse();
3173 usedNames_.rewind(token);
3174 this->compilationState_.rewind(statePosition);
3175 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"
, 3175); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!fc_->hadErrors()"
")"); do { *((volatile int*)__null) = 3175; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3176 break;
3177 }
3178 return false;
3179 }
3180
3181 if (!advancePastSyntaxParsedFunction(syntaxParser)) {
3182 return false;
3183 }
3184
3185 // Update the end position of the parse node.
3186 (*funNode)->pn_pos.end = anyChars.currentToken().pos.end;
3187
3188 // Append possible Annex B function box only upon successfully parsing.
3189 if (tryAnnexB) {
3190 if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
3191 return false;
3192 }
3193 }
3194
3195 return true;
3196 } while (false);
3197
3198 // We failed to do a syntax parse above, so do the full parse.
3199 FunctionNodeType innerFunc;
3200 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)
3201 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)
3202 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)
3203 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)
3204 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)
3205 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)
;
3206
3207 *funNode = innerFunc;
3208 return true;
3209}
3210
3211template <typename Unit>
3212bool Parser<SyntaxParseHandler, Unit>::trySyntaxParseInnerFunction(
3213 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
3214 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3215 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3216 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3217 Directives inheritedDirectives, Directives* newDirectives) {
3218 // This is already a syntax parser, so just parse the inner function.
3219 FunctionNodeType innerFunc;
3220 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)
3221 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)
3222 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)
3223 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)
3224 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)
3225 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)
;
3226
3227 *funNode = innerFunc;
3228 return true;
3229}
3230
3231template <class ParseHandler, typename Unit>
3232inline bool GeneralParser<ParseHandler, Unit>::trySyntaxParseInnerFunction(
3233 FunctionNodeType* funNode, TaggedParserAtomIndex explicitName,
3234 FunctionFlags flags, uint32_t toStringStart, InHandling inHandling,
3235 YieldHandling yieldHandling, FunctionSyntaxKind kind,
3236 GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB,
3237 Directives inheritedDirectives, Directives* newDirectives) {
3238 return asFinalParser()->trySyntaxParseInnerFunction(
3239 funNode, explicitName, flags, toStringStart, inHandling, yieldHandling,
3240 kind, generatorKind, asyncKind, tryAnnexB, inheritedDirectives,
3241 newDirectives);
3242}
3243
3244template <class ParseHandler, typename Unit>
3245typename ParseHandler::FunctionNodeResult
3246GeneralParser<ParseHandler, Unit>::innerFunctionForFunctionBox(
3247 FunctionNodeType funNode, ParseContext* outerpc, FunctionBox* funbox,
3248 InHandling inHandling, YieldHandling yieldHandling, FunctionSyntaxKind kind,
3249 Directives* newDirectives) {
3250 // Note that it is possible for outerpc != this->pc_, as we may be
3251 // attempting to syntax parse an inner function from an outer full
3252 // parser. In that case, outerpc is a SourceParseContext from the full parser
3253 // instead of the current top of the stack of the syntax parser.
3254
3255 // Push a new ParseContext.
3256 SourceParseContext funpc(this, funbox, newDirectives);
3257 if (!funpc.init()) {
3258 return errorResult();
3259 }
3260
3261 if (!functionFormalParametersAndBody(inHandling, yieldHandling, &funNode,
3262 kind)) {
3263 return errorResult();
3264 }
3265
3266 if (!leaveInnerFunction(outerpc)) {
3267 return errorResult();
3268 }
3269
3270 return funNode;
3271}
3272
3273template <class ParseHandler, typename Unit>
3274typename ParseHandler::FunctionNodeResult
3275GeneralParser<ParseHandler, Unit>::innerFunction(
3276 FunctionNodeType funNode, ParseContext* outerpc,
3277 TaggedParserAtomIndex explicitName, FunctionFlags flags,
3278 uint32_t toStringStart, InHandling inHandling, YieldHandling yieldHandling,
3279 FunctionSyntaxKind kind, GeneratorKind generatorKind,
3280 FunctionAsyncKind asyncKind, bool tryAnnexB, Directives inheritedDirectives,
3281 Directives* newDirectives) {
3282 // Note that it is possible for outerpc != this->pc_, as we may be
3283 // attempting to syntax parse an inner function from an outer full
3284 // parser. In that case, outerpc is a SourceParseContext from the full parser
3285 // instead of the current top of the stack of the syntax parser.
3286
3287 FunctionBox* funbox =
3288 newFunctionBox(funNode, explicitName, flags, toStringStart,
3289 inheritedDirectives, generatorKind, asyncKind);
3290 if (!funbox) {
3291 return errorResult();
3292 }
3293 funbox->initWithEnclosingParseContext(outerpc, kind);
3294
3295 FunctionNodeType innerFunc;
3296 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)
3297 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)
3298 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)
;
3299
3300 // Append possible Annex B function box only upon successfully parsing.
3301 if (tryAnnexB) {
3302 if (!pc_->innermostScope()->addPossibleAnnexBFunctionBox(pc_, funbox)) {
3303 return errorResult();
3304 }
3305 }
3306
3307 return innerFunc;
3308}
3309
3310template <class ParseHandler, typename Unit>
3311bool GeneralParser<ParseHandler, Unit>::appendToCallSiteObj(
3312 CallSiteNodeType callSiteObj) {
3313 Node cookedNode;
3314 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)
;
3315
3316 auto atom = tokenStream.getRawTemplateStringAtom();
3317 if (!atom) {
3318 return false;
3319 }
3320 NameNodeType rawNode;
3321 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)
3322 false)do { auto parserTryVarTempResult_ = (handler_.newTemplateStringLiteral
(atom, pos())); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (rawNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
3323
3324 handler_.addToCallSiteObject(callSiteObj, rawNode, cookedNode);
3325 return true;
3326}
3327
3328template <typename Unit>
3329FullParseHandler::FunctionNodeResult
3330Parser<FullParseHandler, Unit>::standaloneLazyFunction(
3331 CompilationInput& input, uint32_t toStringStart, bool strict,
3332 GeneratorKind generatorKind, FunctionAsyncKind asyncKind) {
3333 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"
, 3333); AnnotateMozCrashReason("MOZ_ASSERT" "(" "checkOptionsCalled_"
")"); do { *((volatile int*)__null) = 3333; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3334
3335 FunctionSyntaxKind syntaxKind = input.functionSyntaxKind();
3336 FunctionNodeType funNode;
3337 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)
;
3338
3339 TaggedParserAtomIndex displayAtom =
3340 this->getCompilationState().previousParseCache.displayAtom();
3341
3342 Directives directives(strict);
3343 FunctionBox* funbox =
3344 newFunctionBox(funNode, displayAtom, input.functionFlags(), toStringStart,
3345 directives, generatorKind, asyncKind);
3346 if (!funbox) {
3347 return errorResult();
3348 }
3349 const ScriptStencilExtra& funExtra =
3350 this->getCompilationState().previousParseCache.funExtra();
3351 funbox->initFromLazyFunction(
3352 funExtra, this->getCompilationState().scopeContext, syntaxKind);
3353 if (funbox->useMemberInitializers()) {
3354 funbox->setMemberInitializers(funExtra.memberInitializers());
3355 }
3356
3357 Directives newDirectives = directives;
3358 SourceParseContext funpc(this, funbox, &newDirectives);
3359 if (!funpc.init()) {
3360 return errorResult();
3361 }
3362
3363 // Our tokenStream has no current token, so funNode's position is garbage.
3364 // Substitute the position of the first token in our source. If the
3365 // function is a not-async arrow, use TokenStream::SlashIsRegExp to keep
3366 // verifyConsistentModifier from complaining (we will use
3367 // TokenStream::SlashIsRegExp in functionArguments).
3368 Modifier modifier = (input.functionFlags().isArrow() &&
3369 asyncKind == FunctionAsyncKind::SyncFunction)
3370 ? TokenStream::SlashIsRegExp
3371 : TokenStream::SlashIsDiv;
3372 if (!tokenStream.peekTokenPos(&funNode->pn_pos, modifier)) {
3373 return errorResult();
3374 }
3375
3376 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
3377
3378 if (funbox->isSyntheticFunction()) {
3379 // Currently default class constructors are the only synthetic function that
3380 // supports delazification.
3381 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"
, 3381); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->isClassConstructor()"
")"); do { *((volatile int*)__null) = 3381; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3382 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"
, 3382); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->extent().toStringStart == funbox->extent().sourceStart"
")"); do { *((volatile int*)__null) = 3382; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3383
3384 HasHeritage hasHeritage = funbox->isDerivedClassConstructor()
3385 ? HasHeritage::Yes
3386 : HasHeritage::No;
3387 TokenPos synthesizedBodyPos(funbox->extent().toStringStart,
3388 funbox->extent().toStringEnd);
3389
3390 // Reset pos() to the `class` keyword for predictable results.
3391 tokenStream.consumeKnownToken(TokenKind::Class);
3392
3393 if (!this->synthesizeConstructorBody(synthesizedBodyPos, hasHeritage,
3394 funNode, funbox)) {
3395 return errorResult();
3396 }
3397 } else {
3398 if (!functionFormalParametersAndBody(InAllowed, yieldHandling, &funNode,
3399 syntaxKind)) {
3400 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"
, 3400); AnnotateMozCrashReason("MOZ_ASSERT" "(" "directives == newDirectives"
")"); do { *((volatile int*)__null) = 3400; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3401 return errorResult();
3402 }
3403 }
3404
3405 if (!CheckParseTree(this->fc_, alloc_, funNode)) {
3406 return errorResult();
3407 }
3408
3409 ParseNode* node = funNode;
3410 // Don't constant-fold inside "use asm" code, as this could create a parse
3411 // tree that doesn't type-check as asm.js.
3412 if (!pc_->useAsmOrInsideUseAsm()) {
3413 if (!FoldConstants(this->fc_, this->parserAtoms(), &node, &handler_)) {
3414 return errorResult();
3415 }
3416 }
3417 funNode = &node->as<FunctionNode>();
3418
3419 return funNode;
3420}
3421
3422void ParserBase::setFunctionEndFromCurrentToken(FunctionBox* funbox) const {
3423 if (compilationState_.isInitialStencil()) {
3424 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"
, 3424); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type != TokenKind::Eof"
")"); do { *((volatile int*)__null) = 3424; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3425 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"
, 3425); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type < TokenKind::Limit"
")"); do { *((volatile int*)__null) = 3425; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3426 funbox->setEnd(anyChars.currentToken().pos.end);
3427 } else {
3428 // If we're delazifying an arrow function with expression body and
3429 // the expression is also a function, we arrive here immediately after
3430 // skipping the function by Parser::skipLazyInnerFunction.
3431 //
3432 // a => b => c
3433 // ^
3434 // |
3435 // we're here
3436 //
3437 // In that case, the current token's type field is either Limit or
3438 // poisoned.
3439 // We shouldn't read the value if it's poisoned.
3440 // See TokenStreamSpecific<Unit, AnyCharsAccess>::advance and
3441 // mfbt/MemoryChecking.h for more details.
3442 //
3443 // Also, in delazification, the FunctionBox should already have the
3444 // correct extent, and we shouldn't overwrite it here.
3445 // See ScriptStencil variant of PerHandlerParser::newFunctionBox.
3446#if !defined(MOZ_ASAN) && !defined(MOZ_MSAN) && !defined(MOZ_VALGRIND)
3447 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"
, 3447); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type != TokenKind::Eof"
")"); do { *((volatile int*)__null) = 3447; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3448#endif
3449 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"
, 3449); AnnotateMozCrashReason("MOZ_ASSERT" "(" "funbox->extent().sourceEnd == anyChars.currentToken().pos.end"
")"); do { *((volatile int*)__null) = 3449; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3450 }
3451}
3452
3453template <class ParseHandler, typename Unit>
3454bool GeneralParser<ParseHandler, Unit>::functionFormalParametersAndBody(
3455 InHandling inHandling, YieldHandling yieldHandling,
3456 FunctionNodeType* funNode, FunctionSyntaxKind kind,
3457 const Maybe<uint32_t>& parameterListEnd /* = Nothing() */,
3458 bool isStandaloneFunction /* = false */) {
3459 // Given a properly initialized parse context, try to parse an actual
3460 // function without concern for conversion to strict mode, use of lazy
3461 // parsing and such.
3462
3463 FunctionBox* funbox = pc_->functionBox();
3464
3465 if (kind == FunctionSyntaxKind::ClassConstructor ||
3466 kind == FunctionSyntaxKind::DerivedClassConstructor) {
3467 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::dot_initializers_())) {
3468 return false;
3469 }
3470#ifdef ENABLE_DECORATORS
3471 if (!noteUsedName(TaggedParserAtomIndex::WellKnown::
3472 dot_instanceExtraInitializers_())) {
3473 return false;
3474 }
3475#endif
3476 }
3477
3478 // See below for an explanation why arrow function parameters and arrow
3479 // function bodies are parsed with different yield/await settings.
3480 {
3481 AwaitHandling awaitHandling =
3482 kind == FunctionSyntaxKind::StaticClassBlock ? AwaitIsDisallowed
3483 : (funbox->isAsync() ||
3484 (kind == FunctionSyntaxKind::Arrow && awaitIsKeyword()))
3485 ? AwaitIsKeyword
3486 : AwaitIsName;
3487 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this, awaitHandling);
3488 AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(
3489 this, funbox->isAsync());
3490 if (!functionArguments(yieldHandling, kind, *funNode)) {
3491 return false;
3492 }
3493 }
3494
3495 Maybe<ParseContext::VarScope> varScope;
3496 if (funbox->hasParameterExprs) {
3497 varScope.emplace(this);
3498 if (!varScope->init(pc_)) {
3499 return false;
3500 }
3501 } else {
3502 pc_->functionScope().useAsVarScope(pc_);
3503 }
3504
3505 if (kind == FunctionSyntaxKind::Arrow) {
3506 TokenKind tt;
3507 if (!tokenStream.peekTokenSameLine(&tt)) {
3508 return false;
3509 }
3510
3511 if (tt == TokenKind::Eol) {
3512 error(JSMSG_UNEXPECTED_TOKEN,
3513 "'=>' on the same line after an argument list",
3514 TokenKindToDesc(tt));
3515 return false;
3516 }
3517 if (tt != TokenKind::Arrow) {
3518 error(JSMSG_BAD_ARROW_ARGS);
3519 return false;
3520 }
3521 tokenStream.consumeKnownToken(TokenKind::Arrow);
3522 }
3523
3524 // When parsing something for new Function() we have to make sure to
3525 // only treat a certain part of the source as a parameter list.
3526 if (parameterListEnd.isSome() && parameterListEnd.value() != pos().begin) {
3527 error(JSMSG_UNEXPECTED_PARAMLIST_END);
3528 return false;
3529 }
3530
3531 // Parse the function body.
3532 FunctionBodyType bodyType = StatementListBody;
3533 TokenKind tt;
3534 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
3535 return false;
3536 }
3537 uint32_t openedPos = 0;
3538 if (tt != TokenKind::LeftCurly) {
3539 if (kind != FunctionSyntaxKind::Arrow) {
3540 error(JSMSG_CURLY_BEFORE_BODY);
3541 return false;
3542 }
3543
3544 anyChars.ungetToken();
3545 bodyType = ExpressionBody;
3546 funbox->setHasExprBody();
3547 } else {
3548 openedPos = pos().begin;
3549 }
3550
3551 // Arrow function parameters inherit yieldHandling from the enclosing
3552 // context, but the arrow body doesn't. E.g. in |(a = yield) => yield|,
3553 // |yield| in the parameters is either a name or keyword, depending on
3554 // whether the arrow function is enclosed in a generator function or not.
3555 // Whereas the |yield| in the function body is always parsed as a name.
3556 // The same goes when parsing |await| in arrow functions.
3557 YieldHandling bodyYieldHandling = GetYieldHandling(pc_->generatorKind());
3558 AwaitHandling bodyAwaitHandling = GetAwaitHandling(pc_->asyncKind());
3559 bool inheritedStrict = pc_->sc()->strict();
3560 LexicalScopeNodeType body;
3561 {
3562 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(this,
3563 bodyAwaitHandling);
3564 AutoInParametersOfAsyncFunction<ParseHandler, Unit> inParameters(this,
3565 false);
3566 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)
3567 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)
3568 false)do { auto parserTryVarTempResult_ = (functionBody(inHandling,
bodyYieldHandling, kind, bodyType)); if ((__builtin_expect(!
!(parserTryVarTempResult_.isErr()), 0))) { return (false); } (
body) = parserTryVarTempResult_.unwrap(); } while (0)
;
3569 }
3570
3571 // Revalidate the function name when we transitioned to strict mode.
3572 if ((kind == FunctionSyntaxKind::Statement ||
3573 kind == FunctionSyntaxKind::Expression) &&
3574 funbox->explicitName() && !inheritedStrict && pc_->sc()->strict()) {
3575 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"
, 3577); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3577; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
3576 "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"
, 3577); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3577; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
3577 "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"
, 3577); AnnotateMozCrashReason("MOZ_ASSERT" "(" "pc_->sc()->hasExplicitUseStrict()"
") (" "strict mode should only change when a 'use strict' directive "
"is present" ")"); do { *((volatile int*)__null) = 3577; __attribute__
((nomerge)) ::abort(); } while (false); } } while (false)
;
3578
3579 auto propertyName = funbox->explicitName();
3580 YieldHandling nameYieldHandling;
3581 if (kind == FunctionSyntaxKind::Expression) {
3582 // Named lambda has binding inside it.
3583 nameYieldHandling = bodyYieldHandling;
3584 } else {
3585 // Otherwise YieldHandling cannot be checked at this point
3586 // because of different context.
3587 // It should already be checked before this point.
3588 nameYieldHandling = YieldIsName;
3589 }
3590
3591 // We already use the correct await-handling at this point, therefore
3592 // we don't need call AutoAwaitIsKeyword here.
3593
3594 uint32_t nameOffset = handler_.getFunctionNameOffset(*funNode, anyChars);
3595 if (!checkBindingIdentifier(propertyName, nameOffset, nameYieldHandling)) {
3596 return false;
3597 }
3598 }
3599
3600 if (bodyType == StatementListBody) {
3601 // Cannot use mustMatchToken here because of internal compiler error on
3602 // gcc 6.4.0, with linux 64 SM hazard build.
3603 TokenKind actual;
3604 if (!tokenStream.getToken(&actual, TokenStream::SlashIsRegExp)) {
3605 return false;
3606 }
3607 if (actual != TokenKind::RightCurly) {
3608 reportMissingClosing(JSMSG_CURLY_AFTER_BODY, JSMSG_CURLY_OPENED,
3609 openedPos);
3610 return false;
3611 }
3612
3613 setFunctionEndFromCurrentToken(funbox);
3614 } else {
3615 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"
, 3615); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == FunctionSyntaxKind::Arrow"
")"); do { *((volatile int*)__null) = 3615; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3616
3617 if (anyChars.hadError()) {
3618 return false;
3619 }
3620
3621 setFunctionEndFromCurrentToken(funbox);
3622
3623 if (kind == FunctionSyntaxKind::Statement) {
3624 if (!matchOrInsertSemicolon()) {
3625 return false;
3626 }
3627 }
3628 }
3629
3630 if (IsMethodDefinitionKind(kind) && pc_->superScopeNeedsHomeObject()) {
3631 funbox->setNeedsHomeObject();
3632 }
3633
3634 if (!finishFunction(isStandaloneFunction)) {
3635 return false;
3636 }
3637
3638 handler_.setEndPosition(body, pos().begin);
3639 handler_.setEndPosition(*funNode, pos().end);
3640 handler_.setFunctionBody(*funNode, body);
3641
3642 return true;
3643}
3644
3645template <class ParseHandler, typename Unit>
3646typename ParseHandler::FunctionNodeResult
3647GeneralParser<ParseHandler, Unit>::functionStmt(uint32_t toStringStart,
3648 YieldHandling yieldHandling,
3649 DefaultHandling defaultHandling,
3650 FunctionAsyncKind asyncKind) {
3651 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"
, 3651); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 3651; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3652
3653 // In sloppy mode, Annex B.3.2 allows labelled function declarations.
3654 // Otherwise it's a parse error.
3655 ParseContext::Statement* declaredInStmt = pc_->innermostStatement();
3656 if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
3657 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"
, 3658); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc_->sc()->strict()"
") (" "labeled functions shouldn't be parsed in strict mode"
")"); do { *((volatile int*)__null) = 3658; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
3658 "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"
, 3658); AnnotateMozCrashReason("MOZ_ASSERT" "(" "!pc_->sc()->strict()"
") (" "labeled functions shouldn't be parsed in strict mode"
")"); do { *((volatile int*)__null) = 3658; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3659
3660 // Find the innermost non-label statement. Report an error if it's
3661 // unbraced: functions can't appear in it. Otherwise the statement
3662 // (or its absence) determines the scope the function's bound in.
3663 while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
3664 declaredInStmt = declaredInStmt->enclosing();
3665 }
3666
3667 if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
3668 error(JSMSG_SLOPPY_FUNCTION_LABEL);
3669 return errorResult();
3670 }
3671 }
3672
3673 TokenKind tt;
3674 if (!tokenStream.getToken(&tt)) {
3675 return errorResult();
3676 }
3677
3678 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
3679 if (tt == TokenKind::Mul) {
3680 generatorKind = GeneratorKind::Generator;
3681 if (!tokenStream.getToken(&tt)) {
3682 return errorResult();
3683 }
3684 }
3685
3686 TaggedParserAtomIndex name;
3687 if (TokenKindIsPossibleIdentifier(tt)) {
3688 name = bindingIdentifier(yieldHandling);
3689 if (!name) {
3690 return errorResult();
3691 }
3692 } else if (defaultHandling == AllowDefaultName) {
3693 name = TaggedParserAtomIndex::WellKnown::default_();
3694 anyChars.ungetToken();
3695 } else {
3696 /* Unnamed function expressions are forbidden in statement context. */
3697 error(JSMSG_UNNAMED_FUNCTION_STMT);
3698 return errorResult();
3699 }
3700
3701 // Note the declared name and check for early errors.
3702 DeclarationKind kind;
3703 if (declaredInStmt) {
3704 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"
, 3704); AnnotateMozCrashReason("MOZ_ASSERT" "(" "declaredInStmt->kind() != StatementKind::Label"
")"); do { *((volatile int*)__null) = 3704; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3705 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"
, 3705); AnnotateMozCrashReason("MOZ_ASSERT" "(" "StatementKindIsBraced(declaredInStmt->kind())"
")"); do { *((volatile int*)__null) = 3705; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3706
3707 kind =
3708 (!pc_->sc()->strict() && generatorKind == GeneratorKind::NotGenerator &&
3709 asyncKind == FunctionAsyncKind::SyncFunction)
3710 ? DeclarationKind::SloppyLexicalFunction
3711 : DeclarationKind::LexicalFunction;
3712 } else {
3713 kind = pc_->atModuleLevel() ? DeclarationKind::ModuleBodyLevelFunction
3714 : DeclarationKind::BodyLevelFunction;
3715 }
3716
3717 if (!noteDeclaredName(name, kind, pos())) {
3718 return errorResult();
3719 }
3720
3721 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement;
3722 FunctionNodeType funNode;
3723 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)
;
3724
3725 // Under sloppy mode, try Annex B.3.3 semantics. If making an additional
3726 // 'var' binding of the same name does not throw an early error, do so.
3727 // This 'var' binding would be assigned the function object when its
3728 // declaration is reached, not at the start of the block.
3729 //
3730 // This semantics is implemented upon Scope exit in
3731 // Scope::propagateAndMarkAnnexBFunctionBoxes.
3732 bool tryAnnexB = kind == DeclarationKind::SloppyLexicalFunction;
3733
3734 YieldHandling newYieldHandling = GetYieldHandling(generatorKind);
3735 return functionDefinition(funNode, toStringStart, InAllowed, newYieldHandling,
3736 name, syntaxKind, generatorKind, asyncKind,
3737 tryAnnexB);
3738}
3739
3740template <class ParseHandler, typename Unit>
3741typename ParseHandler::FunctionNodeResult
3742GeneralParser<ParseHandler, Unit>::functionExpr(uint32_t toStringStart,
3743 InvokedPrediction invoked,
3744 FunctionAsyncKind asyncKind) {
3745 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"
, 3745); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Function)"
")"); do { *((volatile int*)__null) = 3745; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
3746
3747 AutoAwaitIsKeyword<ParseHandler, Unit> awaitIsKeyword(
3748 this, GetAwaitHandling(asyncKind));
3749 GeneratorKind generatorKind = GeneratorKind::NotGenerator;
3750 TokenKind tt;
3751 if (!tokenStream.getToken(&tt)) {
3752 return errorResult();
3753 }
3754
3755 if (tt == TokenKind::Mul) {
3756 generatorKind = GeneratorKind::Generator;
3757 if (!tokenStream.getToken(&tt)) {
3758 return errorResult();
3759 }
3760 }
3761
3762 YieldHandling yieldHandling = GetYieldHandling(generatorKind);
3763
3764 TaggedParserAtomIndex name;
3765 if (TokenKindIsPossibleIdentifier(tt)) {
3766 name = bindingIdentifier(yieldHandling);
3767 if (!name) {
3768 return errorResult();
3769 }
3770 } else {
3771 anyChars.ungetToken();
3772 }
3773
3774 FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Expression;
3775 FunctionNodeType funNode;
3776 MOZ_TRY_VAR(funNode, handler_.newFunction(syntaxKind, pos()))do { auto mozTryVarTempResult_ = (handler_.newFunction(syntaxKind
, pos())); if ((__builtin_expect(!!(mozTryVarTempResult_.isErr
()), 0))) { return mozTryVarTempResult_.propagateErr(); } (funNode
) = mozTryVarTempResult_.unwrap(); } while (0)
;
3777
3778 if (invoked) {
3779 funNode = handler_.setLikelyIIFE(funNode);
3780 }
3781
3782 return functionDefinition(funNode, toStringStart, InAllowed, yieldHandling,
3783 name, syntaxKind, generatorKind, asyncKind);
3784}
3785
3786/*
3787 * Return true if this node, known to be an unparenthesized string literal
3788 * that never contain escape sequences, could be the string of a directive in a
3789 * Directive Prologue. Directive strings never contain escape sequences or line
3790 * continuations.
3791 */
3792static inline bool IsUseStrictDirective(const TokenPos& pos,
3793 TaggedParserAtomIndex atom) {
3794 // the length of "use strict", including quotation.
3795 static constexpr size_t useStrictLength = 12;
3796 return atom == TaggedParserAtomIndex::WellKnown::use_strict_() &&
3797 pos.begin + useStrictLength == pos.end;
3798}
3799static inline bool IsUseAsmDirective(const TokenPos& pos,
3800 TaggedParserAtomIndex atom) {
3801 // the length of "use asm", including quotation.
3802 static constexpr size_t useAsmLength = 9;
3803 return atom == TaggedParserAtomIndex::WellKnown::use_asm_() &&
3804 pos.begin + useAsmLength == pos.end;
3805}
3806
3807template <typename Unit>
3808bool Parser<SyntaxParseHandler, Unit>::asmJS(ListNodeType list) {
3809 // While asm.js could technically be validated and compiled during syntax
3810 // parsing, we have no guarantee that some later JS wouldn't abort the
3811 // syntax parse and cause us to re-parse (and re-compile) the asm.js module.
3812 // For simplicity, unconditionally abort the syntax parse when "use asm" is
3813 // encountered so that asm.js is always validated/compiled exactly once
3814 // during a full parse.
3815 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 3815); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 3815; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
3816 return false;
3817}
3818
3819template <typename Unit>
3820bool Parser<FullParseHandler, Unit>::asmJS(ListNodeType list) {
3821 // Disable syntax parsing in anything nested inside the asm.js module.
3822 disableSyntaxParser();
3823
3824 // We should be encountering the "use asm" directive for the first time; if
3825 // the directive is already, we must have failed asm.js validation and we're
3826 // reparsing. In that case, don't try to validate again. A non-null
3827 // newDirectives means we're not in a normal function.
3828 if (!pc_->newDirectives || pc_->newDirectives->asmJS()) {
3829 return true;
3830 }
3831
3832 // If there is no ScriptSource, then we are doing a non-compiling parse and
3833 // so we shouldn't (and can't, without a ScriptSource) compile.
3834 if (ss == nullptr) {
3835 return true;
3836 }
3837
3838 pc_->functionBox()->useAsm = true;
3839
3840 // Attempt to validate and compile this asm.js module. On success, the
3841 // tokenStream has been advanced to the closing }. On failure, the
3842 // tokenStream is in an indeterminate state and we must reparse the
3843 // function from the beginning. Reparsing is triggered by marking that a
3844 // new directive has been encountered and returning 'false'.
3845 bool validated;
3846 if (!CompileAsmJS(this->fc_, this->parserAtoms(), *this, list, &validated)) {
3847 return false;
3848 }
3849 if (!validated) {
3850 pc_->newDirectives->setAsmJS();
3851 return false;
3852 }
3853
3854 return true;
3855}
3856
3857template <class ParseHandler, typename Unit>
3858inline bool GeneralParser<ParseHandler, Unit>::asmJS(ListNodeType list) {
3859 return asFinalParser()->asmJS(list);
3860}
3861
3862/*
3863 * Recognize Directive Prologue members and directives. Assuming |pn| is a
3864 * candidate for membership in a directive prologue, recognize directives and
3865 * set |pc_|'s flags accordingly. If |pn| is indeed part of a prologue, set its
3866 * |prologue| flag.
3867 *
3868 * Note that the following is a strict mode function:
3869 *
3870 * function foo() {
3871 * "blah" // inserted semi colon
3872 * "blurgh"
3873 * "use\x20loose"
3874 * "use strict"
3875 * }
3876 *
3877 * That is, even though "use\x20loose" can never be a directive, now or in the
3878 * future (because of the hex escape), the Directive Prologue extends through it
3879 * to the "use strict" statement, which is indeed a directive.
3880 */
3881template <class ParseHandler, typename Unit>
3882bool GeneralParser<ParseHandler, Unit>::maybeParseDirective(
3883 ListNodeType list, Node possibleDirective, bool* cont) {
3884 TokenPos directivePos;
3885 TaggedParserAtomIndex directive =
3886 handler_.isStringExprStatement(possibleDirective, &directivePos);
3887
3888 *cont = !!directive;
3889 if (!*cont) {
3890 return true;
3891 }
3892
3893 if (IsUseStrictDirective(directivePos, directive)) {
3894 // Functions with non-simple parameter lists (destructuring,
3895 // default or rest parameters) must not contain a "use strict"
3896 // directive.
3897 if (pc_->isFunctionBox()) {
3898 FunctionBox* funbox = pc_->functionBox();
3899 if (!funbox->hasSimpleParameterList()) {
3900 const char* parameterKind = funbox->hasDestructuringArgs
3901 ? "destructuring"
3902 : funbox->hasParameterExprs ? "default"
3903 : "rest";
3904 errorAt(directivePos.begin, JSMSG_STRICT_NON_SIMPLE_PARAMS,
3905 parameterKind);
3906 return false;
3907 }
3908 }
3909
3910 // We're going to be in strict mode. Note that this scope explicitly
3911 // had "use strict";
3912 pc_->sc()->setExplicitUseStrict();
3913 if (!pc_->sc()->strict()) {
3914 // Some strict mode violations can appear before a Use Strict Directive
3915 // is applied. (See the |DeprecatedContent| enum initializers.) These
3916 // violations can manifest in two ways.
3917 //
3918 // First, the violation can appear *before* the Use Strict Directive.
3919 // Numeric literals (and therefore octal literals) can only precede a
3920 // Use Strict Directive if this function's parameter list is not simple,
3921 // but we reported an error for non-simple parameter lists above, so
3922 // octal literals present no issue. But octal escapes and \8 and \9 can
3923 // appear in the directive prologue before a Use Strict Directive:
3924 //
3925 // function f()
3926 // {
3927 // "hell\157 world"; // octal escape
3928 // "\8"; "\9"; // NonOctalDecimalEscape
3929 // "use strict"; // retroactively makes all the above errors
3930 // }
3931 //
3932 // Second, the violation can appear *after* the Use Strict Directive but
3933 // *before* the directive is recognized as terminated. This only
3934 // happens when a directive is terminated by ASI, and the next token
3935 // contains a violation:
3936 //
3937 // function a()
3938 // {
3939 // "use strict" // ASI
3940 // 0755;
3941 // }
3942 // function b()
3943 // {
3944 // "use strict" // ASI
3945 // "hell\157 world";
3946 // }
3947 // function c()
3948 // {
3949 // "use strict" // ASI
3950 // "\8";
3951 // }
3952 //
3953 // We note such violations when tokenizing. Then, if a violation has
3954 // been observed at the time a "use strict" is applied, we report the
3955 // error.
3956 switch (anyChars.sawDeprecatedContent()) {
3957 case DeprecatedContent::None:
3958 break;
3959 case DeprecatedContent::OctalLiteral:
3960 error(JSMSG_DEPRECATED_OCTAL_LITERAL);
3961 return false;
3962 case DeprecatedContent::OctalEscape:
3963 error(JSMSG_DEPRECATED_OCTAL_ESCAPE);
3964 return false;
3965 case DeprecatedContent::EightOrNineEscape:
3966 error(JSMSG_DEPRECATED_EIGHT_OR_NINE_ESCAPE);
3967 return false;
3968 }
3969
3970 pc_->sc()->setStrictScript();
3971 }
3972 } else if (IsUseAsmDirective(directivePos, directive)) {
3973 if (pc_->isFunctionBox()) {
3974 return asmJS(list);
3975 }
3976 return warningAt(directivePos.begin, JSMSG_USE_ASM_DIRECTIVE_FAIL);
3977 }
3978 return true;
3979}
3980
3981template <class ParseHandler, typename Unit>
3982typename ParseHandler::ListNodeResult
3983GeneralParser<ParseHandler, Unit>::statementList(YieldHandling yieldHandling) {
3984 AutoCheckRecursionLimit recursion(this->fc_);
3985 if (!recursion.check(this->fc_)) {
3986 return errorResult();
3987 }
3988
3989 ListNodeType stmtList;
3990 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)
;
3991
3992 bool canHaveDirectives = pc_->atBodyLevel();
3993 if (canHaveDirectives) {
3994 // Clear flags for deprecated content that might have been seen in an
3995 // enclosing context.
3996 anyChars.clearSawDeprecatedContent();
3997 }
3998
3999 bool canHaveHashbangComment = pc_->atTopLevel();
4000 if (canHaveHashbangComment) {
4001 tokenStream.consumeOptionalHashbangComment();
4002 }
4003
4004 bool afterReturn = false;
4005 bool warnedAboutStatementsAfterReturn = false;
4006 uint32_t statementBegin = 0;
4007 for (;;) {
4008 TokenKind tt = TokenKind::Eof;
4009 if (!tokenStream.peekToken(&tt, TokenStream::SlashIsRegExp)) {
4010 if (anyChars.isEOF()) {
4011 isUnexpectedEOF_ = true;
4012 }
4013 return errorResult();
4014 }
4015 if (tt == TokenKind::Eof || tt == TokenKind::RightCurly) {
4016 TokenPos pos;
4017 if (!tokenStream.peekTokenPos(&pos, TokenStream::SlashIsRegExp)) {
4018 return errorResult();
4019 }
4020 handler_.setListEndPosition(stmtList, pos);
4021 break;
4022 }
4023 if (afterReturn) {
4024 if (!tokenStream.peekOffset(&statementBegin,
4025 TokenStream::SlashIsRegExp)) {
4026 return errorResult();
4027 }
4028 }
4029 auto nextResult = statementListItem(yieldHandling, canHaveDirectives);
4030 if (nextResult.isErr()) {
4031 if (anyChars.isEOF()) {
4032 isUnexpectedEOF_ = true;
4033 }
4034 return errorResult();
4035 }
4036 Node next = nextResult.unwrap();
4037 if (!warnedAboutStatementsAfterReturn) {
4038 if (afterReturn) {
4039 if (!handler_.isStatementPermittedAfterReturnStatement(next)) {
4040 if (!warningAt(statementBegin, JSMSG_STMT_AFTER_RETURN)) {
4041 return errorResult();
4042 }
4043
4044 warnedAboutStatementsAfterReturn = true;
4045 }
4046 } else if (handler_.isReturnStatement(next)) {
4047 afterReturn = true;
4048 }
4049 }
4050
4051 if (canHaveDirectives) {
4052 if (!maybeParseDirective(stmtList, next, &canHaveDirectives)) {
4053 return errorResult();
4054 }
4055 }
4056
4057 handler_.addStatementToList(stmtList, next);
4058 }
4059
4060 return stmtList;
4061}
4062
4063template <class ParseHandler, typename Unit>
4064typename ParseHandler::NodeResult GeneralParser<ParseHandler, Unit>::condition(
4065 InHandling inHandling, YieldHandling yieldHandling) {
4066 if (!mustMatchToken(TokenKind::LeftParen, JSMSG_PAREN_BEFORE_COND)) {
4067 return errorResult();
4068 }
4069
4070 Node pn;
4071 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)
;
4072
4073 if (!mustMatchToken(TokenKind::RightParen, JSMSG_PAREN_AFTER_COND)) {
4074 return errorResult();
4075 }
4076
4077 return pn;
4078}
4079
4080template <class ParseHandler, typename Unit>
4081bool GeneralParser<ParseHandler, Unit>::matchLabel(
4082 YieldHandling yieldHandling, TaggedParserAtomIndex* labelOut) {
4083 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"
, 4083); AnnotateMozCrashReason("MOZ_ASSERT" "(" "labelOut != nullptr"
")"); do { *((volatile int*)__null) = 4083; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4084 TokenKind tt = TokenKind::Eof;
4085 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
4086 return false;
4087 }
4088
4089 if (TokenKindIsPossibleIdentifier(tt)) {
4090 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
4091
4092 *labelOut = labelIdentifier(yieldHandling);
4093 if (!*labelOut) {
4094 return false;
4095 }
4096 } else {
4097 *labelOut = TaggedParserAtomIndex::null();
4098 }
4099 return true;
4100}
4101
4102template <class ParseHandler, typename Unit>
4103GeneralParser<ParseHandler, Unit>::PossibleError::PossibleError(
4104 GeneralParser<ParseHandler, Unit>& parser)
4105 : parser_(parser) {}
4106
4107template <class ParseHandler, typename Unit>
4108typename GeneralParser<ParseHandler, Unit>::PossibleError::Error&
4109GeneralParser<ParseHandler, Unit>::PossibleError::error(ErrorKind kind) {
4110 if (kind == ErrorKind::Expression) {
4111 return exprError_;
4112 }
4113 if (kind == ErrorKind::Destructuring) {
4114 return destructuringError_;
4115 }
4116 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"
, 4116); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ErrorKind::DestructuringWarning"
")"); do { *((volatile int*)__null) = 4116; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4117 return destructuringWarning_;
4118}
4119
4120template <class ParseHandler, typename Unit>
4121void GeneralParser<ParseHandler, Unit>::PossibleError::setResolved(
4122 ErrorKind kind) {
4123 error(kind).state_ = ErrorState::None;
4124}
4125
4126template <class ParseHandler, typename Unit>
4127bool GeneralParser<ParseHandler, Unit>::PossibleError::hasError(
4128 ErrorKind kind) {
4129 return error(kind).state_ == ErrorState::Pending;
4130}
4131
4132template <class ParseHandler, typename Unit>
4133bool GeneralParser<ParseHandler,
4134 Unit>::PossibleError::hasPendingDestructuringError() {
4135 return hasError(ErrorKind::Destructuring);
4136}
4137
4138template <class ParseHandler, typename Unit>
4139void GeneralParser<ParseHandler, Unit>::PossibleError::setPending(
4140 ErrorKind kind, const TokenPos& pos, unsigned errorNumber) {
4141 // Don't overwrite a previously recorded error.
4142 if (hasError(kind)) {
4143 return;
4144 }
4145
4146 // If we report an error later, we'll do it from the position where we set
4147 // the state to pending.
4148 Error& err = error(kind);
4149 err.offset_ = pos.begin;
4150 err.errorNumber_ = errorNumber;
4151 err.state_ = ErrorState::Pending;
4152}
4153
4154template <class ParseHandler, typename Unit>
4155void GeneralParser<ParseHandler, Unit>::PossibleError::
4156 setPendingDestructuringErrorAt(const TokenPos& pos, unsigned errorNumber) {
4157 setPending(ErrorKind::Destructuring, pos, errorNumber);
4158}
4159
4160template <class ParseHandler, typename Unit>
4161void GeneralParser<ParseHandler, Unit>::PossibleError::
4162 setPendingDestructuringWarningAt(const TokenPos& pos,
4163 unsigned errorNumber) {
4164 setPending(ErrorKind::DestructuringWarning, pos, errorNumber);
4165}
4166
4167template <class ParseHandler, typename Unit>
4168void GeneralParser<ParseHandler, Unit>::PossibleError::
4169 setPendingExpressionErrorAt(const TokenPos& pos, unsigned errorNumber) {
4170 setPending(ErrorKind::Expression, pos, errorNumber);
4171}
4172
4173template <class ParseHandler, typename Unit>
4174bool GeneralParser<ParseHandler, Unit>::PossibleError::checkForError(
4175 ErrorKind kind) {
4176 if (!hasError(kind)) {
4177 return true;
4178 }
4179
4180 Error& err = error(kind);
4181 parser_.errorAt(err.offset_, err.errorNumber_);
4182 return false;
4183}
4184
4185template <class ParseHandler, typename Unit>
4186bool GeneralParser<ParseHandler,
4187 Unit>::PossibleError::checkForDestructuringErrorOrWarning() {
4188 // Clear pending expression error, because we're definitely not in an
4189 // expression context.
4190 setResolved(ErrorKind::Expression);
4191
4192 // Report any pending destructuring error.
4193 return checkForError(ErrorKind::Destructuring);
4194}
4195
4196template <class ParseHandler, typename Unit>
4197bool GeneralParser<ParseHandler,
4198 Unit>::PossibleError::checkForExpressionError() {
4199 // Clear pending destructuring error, because we're definitely not
4200 // in a destructuring context.
4201 setResolved(ErrorKind::Destructuring);
4202 setResolved(ErrorKind::DestructuringWarning);
4203
4204 // Report any pending expression error.
4205 return checkForError(ErrorKind::Expression);
4206}
4207
4208template <class ParseHandler, typename Unit>
4209void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorTo(
4210 ErrorKind kind, PossibleError* other) {
4211 if (hasError(kind) && !other->hasError(kind)) {
4212 Error& err = error(kind);
4213 Error& otherErr = other->error(kind);
4214 otherErr.offset_ = err.offset_;
4215 otherErr.errorNumber_ = err.errorNumber_;
4216 otherErr.state_ = err.state_;
4217 }
4218}
4219
4220template <class ParseHandler, typename Unit>
4221void GeneralParser<ParseHandler, Unit>::PossibleError::transferErrorsTo(
4222 PossibleError* other) {
4223 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"
, 4223); AnnotateMozCrashReason("MOZ_ASSERT" "(" "other" ")")
; do { *((volatile int*)__null) = 4223; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4224 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"
, 4224); AnnotateMozCrashReason("MOZ_ASSERT" "(" "this != other"
")"); do { *((volatile int*)__null) = 4224; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4225 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"
, 4227); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4227
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
4226 "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"
, 4227); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4227
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
4227 "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"
, 4227); AnnotateMozCrashReason("MOZ_ASSERT" "(" "&parser_ == &other->parser_"
") (" "Can't transfer fields to an instance which belongs to a "
"different parser" ")"); do { *((volatile int*)__null) = 4227
; __attribute__((nomerge)) ::abort(); } while (false); } } while
(false)
;
4228
4229 transferErrorTo(ErrorKind::Destructuring, other);
4230 transferErrorTo(ErrorKind::Expression, other);
4231}
4232
4233template <class ParseHandler, typename Unit>
4234typename ParseHandler::BinaryNodeResult
4235GeneralParser<ParseHandler, Unit>::bindingInitializer(
4236 Node lhs, DeclarationKind kind, YieldHandling yieldHandling) {
4237 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"
, 4237); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assign)"
")"); do { *((volatile int*)__null) = 4237; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4238
4239 if (kind == DeclarationKind::FormalParameter) {
4240 pc_->functionBox()->hasParameterExprs = true;
4241 }
4242
4243 Node rhs;
4244 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)
;
4245
4246 BinaryNodeType assign;
4247 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)
4248 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)
;
4249
4250 return assign;
4251}
4252
4253template <class ParseHandler, typename Unit>
4254typename ParseHandler::NameNodeResult
4255GeneralParser<ParseHandler, Unit>::bindingIdentifier(
4256 DeclarationKind kind, YieldHandling yieldHandling) {
4257 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
4258 if (!name) {
4259 return errorResult();
4260 }
4261
4262 NameNodeType binding;
4263 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)
;
4264 if (!noteDeclaredName(name, kind, pos())) {
4265 return errorResult();
4266 }
4267
4268 return binding;
4269}
4270
4271template <class ParseHandler, typename Unit>
4272typename ParseHandler::NodeResult
4273GeneralParser<ParseHandler, Unit>::bindingIdentifierOrPattern(
4274 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4275 if (tt == TokenKind::LeftBracket) {
4276 return arrayBindingPattern(kind, yieldHandling);
4277 }
4278
4279 if (tt == TokenKind::LeftCurly) {
4280 return objectBindingPattern(kind, yieldHandling);
4281 }
4282
4283 if (!TokenKindIsPossibleIdentifierName(tt)) {
4284 error(JSMSG_NO_VARIABLE_NAME);
4285 return errorResult();
4286 }
4287
4288 return bindingIdentifier(kind, yieldHandling);
4289}
4290
4291template <class ParseHandler, typename Unit>
4292typename ParseHandler::ListNodeResult
4293GeneralParser<ParseHandler, Unit>::objectBindingPattern(
4294 DeclarationKind kind, YieldHandling yieldHandling) {
4295 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"
, 4295); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4295; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4296
4297 AutoCheckRecursionLimit recursion(this->fc_);
4298 if (!recursion.check(this->fc_)) {
4299 return errorResult();
4300 }
4301
4302 uint32_t begin = pos().begin;
4303 ListNodeType literal;
4304 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)
;
4305
4306 Maybe<DeclarationKind> declKind = Some(kind);
4307 TaggedParserAtomIndex propAtom;
4308 for (;;) {
4309 TokenKind tt;
4310 if (!tokenStream.peekToken(&tt)) {
4311 return errorResult();
4312 }
4313 if (tt == TokenKind::RightCurly) {
4314 break;
4315 }
4316
4317 if (tt == TokenKind::TripleDot) {
4318 tokenStream.consumeKnownToken(TokenKind::TripleDot);
4319 uint32_t begin = pos().begin;
4320
4321 TokenKind tt;
4322 if (!tokenStream.getToken(&tt)) {
4323 return errorResult();
4324 }
4325
4326 if (!TokenKindIsPossibleIdentifierName(tt)) {
4327 error(JSMSG_NO_VARIABLE_NAME);
4328 return errorResult();
4329 }
4330
4331 NameNodeType inner;
4332 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)
;
4333
4334 if (!handler_.addSpreadProperty(literal, begin, inner)) {
4335 return errorResult();
4336 }
4337 } else {
4338 TokenPos namePos = anyChars.nextToken().pos;
4339
4340 PropertyType propType;
4341 Node propName;
4342 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)
4343 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)
4344 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)
;
4345
4346 if (propType == PropertyType::Normal) {
4347 // Handle e.g., |var {p: x} = o| and |var {p: x=0} = o|.
4348
4349 if (!tokenStream.getToken(&tt, TokenStream::SlashIsRegExp)) {
4350 return errorResult();
4351 }
4352
4353 Node binding;
4354 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)
4355 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)
;
4356
4357 bool hasInitializer;
4358 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
4359 TokenStream::SlashIsRegExp)) {
4360 return errorResult();
4361 }
4362
4363 Node bindingExpr;
4364 if (hasInitializer) {
4365 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)
4366 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)
;
4367 } else {
4368 bindingExpr = binding;
4369 }
4370
4371 if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
4372 return errorResult();
4373 }
4374 } else if (propType == PropertyType::Shorthand) {
4375 // Handle e.g., |var {x, y} = o| as destructuring shorthand
4376 // for |var {x: x, y: y} = o|.
4377 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"
, 4377); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(tt)"
")"); do { *((volatile int*)__null) = 4377; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4378
4379 NameNodeType binding;
4380 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)
;
4381
4382 if (!handler_.addShorthand(literal, handler_.asNameNode(propName),
4383 binding)) {
4384 return errorResult();
4385 }
4386 } else if (propType == PropertyType::CoverInitializedName) {
4387 // Handle e.g., |var {x=1, y=2} = o| as destructuring
4388 // shorthand with default values.
4389 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"
, 4389); AnnotateMozCrashReason("MOZ_ASSERT" "(" "TokenKindIsPossibleIdentifierName(tt)"
")"); do { *((volatile int*)__null) = 4389; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4390
4391 NameNodeType binding;
4392 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)
;
4393
4394 tokenStream.consumeKnownToken(TokenKind::Assign);
4395
4396 BinaryNodeType bindingExpr;
4397 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)
4398 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)
;
4399
4400 if (!handler_.addPropertyDefinition(literal, propName, bindingExpr)) {
4401 return errorResult();
4402 }
4403 } else {
4404 errorAt(namePos.begin, JSMSG_NO_VARIABLE_NAME);
4405 return errorResult();
4406 }
4407 }
4408
4409 bool matched;
4410 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
4411 TokenStream::SlashIsInvalid)) {
4412 return errorResult();
4413 }
4414 if (!matched) {
4415 break;
4416 }
4417 if (tt == TokenKind::TripleDot) {
4418 error(JSMSG_REST_WITH_COMMA);
4419 return errorResult();
4420 }
4421 }
4422
4423 if (!mustMatchToken(TokenKind::RightCurly, [this, begin](TokenKind actual) {
4424 this->reportMissingClosing(JSMSG_CURLY_AFTER_LIST, JSMSG_CURLY_OPENED,
4425 begin);
4426 })) {
4427 return errorResult();
4428 }
4429
4430 handler_.setEndPosition(literal, pos().end);
4431 return literal;
4432}
4433
4434template <class ParseHandler, typename Unit>
4435typename ParseHandler::ListNodeResult
4436GeneralParser<ParseHandler, Unit>::arrayBindingPattern(
4437 DeclarationKind kind, YieldHandling yieldHandling) {
4438 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"
, 4438); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket)"
")"); do { *((volatile int*)__null) = 4438; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4439
4440 AutoCheckRecursionLimit recursion(this->fc_);
4441 if (!recursion.check(this->fc_)) {
4442 return errorResult();
4443 }
4444
4445 uint32_t begin = pos().begin;
4446 ListNodeType literal;
4447 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)
;
4448
4449 uint32_t index = 0;
4450 for (;; index++) {
4451 if (index >= NativeObject::MAX_DENSE_ELEMENTS_COUNT) {
4452 error(JSMSG_ARRAY_INIT_TOO_BIG);
4453 return errorResult();
4454 }
4455
4456 TokenKind tt;
4457 if (!tokenStream.getToken(&tt)) {
4458 return errorResult();
4459 }
4460
4461 if (tt == TokenKind::RightBracket) {
4462 anyChars.ungetToken();
4463 break;
4464 }
4465
4466 if (tt == TokenKind::Comma) {
4467 if (!handler_.addElision(literal, pos())) {
4468 return errorResult();
4469 }
4470 } else if (tt == TokenKind::TripleDot) {
4471 uint32_t begin = pos().begin;
4472
4473 TokenKind tt;
4474 if (!tokenStream.getToken(&tt)) {
4475 return errorResult();
4476 }
4477
4478 Node inner;
4479 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)
;
4480
4481 if (!handler_.addSpreadElement(literal, begin, inner)) {
4482 return errorResult();
4483 }
4484 } else {
4485 Node binding;
4486 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)
;
4487
4488 bool hasInitializer;
4489 if (!tokenStream.matchToken(&hasInitializer, TokenKind::Assign,
4490 TokenStream::SlashIsRegExp)) {
4491 return errorResult();
4492 }
4493
4494 Node element;
4495 if (hasInitializer) {
4496 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)
;
4497 } else {
4498 element = binding;
4499 }
4500
4501 handler_.addArrayElement(literal, element);
4502 }
4503
4504 if (tt != TokenKind::Comma) {
4505 // If we didn't already match TokenKind::Comma in above case.
4506 bool matched;
4507 if (!tokenStream.matchToken(&matched, TokenKind::Comma,
4508 TokenStream::SlashIsRegExp)) {
4509 return errorResult();
4510 }
4511 if (!matched) {
4512 break;
4513 }
4514
4515 if (tt == TokenKind::TripleDot) {
4516 error(JSMSG_REST_WITH_COMMA);
4517 return errorResult();
4518 }
4519 }
4520 }
4521
4522 if (!mustMatchToken(TokenKind::RightBracket, [this, begin](TokenKind actual) {
4523 this->reportMissingClosing(JSMSG_BRACKET_AFTER_LIST,
4524 JSMSG_BRACKET_OPENED, begin);
4525 })) {
4526 return errorResult();
4527 }
4528
4529 handler_.setEndPosition(literal, pos().end);
4530 return literal;
4531}
4532
4533template <class ParseHandler, typename Unit>
4534typename ParseHandler::NodeResult
4535GeneralParser<ParseHandler, Unit>::destructuringDeclaration(
4536 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4537 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"
, 4537); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(tt)"
")"); do { *((volatile int*)__null) = 4537; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4538 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"
, 4538); AnnotateMozCrashReason("MOZ_ASSERT" "(" "tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly"
")"); do { *((volatile int*)__null) = 4538; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4539
4540 if (tt == TokenKind::LeftBracket) {
4541 return arrayBindingPattern(kind, yieldHandling);
4542 }
4543 return objectBindingPattern(kind, yieldHandling);
4544}
4545
4546template <class ParseHandler, typename Unit>
4547typename ParseHandler::NodeResult
4548GeneralParser<ParseHandler, Unit>::destructuringDeclarationWithoutYieldOrAwait(
4549 DeclarationKind kind, YieldHandling yieldHandling, TokenKind tt) {
4550 uint32_t startYieldOffset = pc_->lastYieldOffset;
4551 uint32_t startAwaitOffset = pc_->lastAwaitOffset;
4552
4553 Node res;
4554 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)
;
4555
4556 if (pc_->lastYieldOffset != startYieldOffset) {
4557 errorAt(pc_->lastYieldOffset, JSMSG_YIELD_IN_PARAMETER);
4558 return errorResult();
4559 }
4560 if (pc_->lastAwaitOffset != startAwaitOffset) {
4561 errorAt(pc_->lastAwaitOffset, JSMSG_AWAIT_IN_PARAMETER);
4562 return errorResult();
4563 }
4564 return res;
4565}
4566
4567template <class ParseHandler, typename Unit>
4568typename ParseHandler::LexicalScopeNodeResult
4569GeneralParser<ParseHandler, Unit>::blockStatement(YieldHandling yieldHandling,
4570 unsigned errorNumber) {
4571 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"
, 4571); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4571; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4572 uint32_t openedPos = pos().begin;
4573
4574 ParseContext::Statement stmt(pc_, StatementKind::Block);
4575 ParseContext::Scope scope(this);
4576 if (!scope.init(pc_)) {
4577 return errorResult();
4578 }
4579
4580 ListNodeType list;
4581 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)
;
4582
4583 if (!mustMatchToken(TokenKind::RightCurly, [this, errorNumber,
4584 openedPos](TokenKind actual) {
4585 this->reportMissingClosing(errorNumber, JSMSG_CURLY_OPENED, openedPos);
4586 })) {
4587 return errorResult();
4588 }
4589
4590 return finishLexicalScope(scope, list);
4591}
4592
4593template <class ParseHandler, typename Unit>
4594typename ParseHandler::NodeResult
4595GeneralParser<ParseHandler, Unit>::expressionAfterForInOrOf(
4596 ParseNodeKind forHeadKind, YieldHandling yieldHandling) {
4597 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"
, 4598); AnnotateMozCrashReason("MOZ_ASSERT" "(" "forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 4598; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4598 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"
, 4598); AnnotateMozCrashReason("MOZ_ASSERT" "(" "forHeadKind == ParseNodeKind::ForIn || forHeadKind == ParseNodeKind::ForOf"
")"); do { *((volatile int*)__null) = 4598; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4599 if (forHeadKind == ParseNodeKind::ForOf) {
4600 return assignExpr(InAllowed, yieldHandling, TripledotProhibited);
4601 }
4602
4603 return expr(InAllowed, yieldHandling, TripledotProhibited);
4604}
4605
4606template <class ParseHandler, typename Unit>
4607typename ParseHandler::NodeResult
4608GeneralParser<ParseHandler, Unit>::declarationPattern(
4609 DeclarationKind declKind, TokenKind tt, bool initialDeclaration,
4610 YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
4611 Node* forInOrOfExpression) {
4612 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"
, 4613); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4613; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4613 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"
, 4613); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::LeftBracket) || anyChars.isCurrentTokenType(TokenKind::LeftCurly)"
")"); do { *((volatile int*)__null) = 4613; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4614
4615 Node pattern;
4616 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)
;
4617
4618 if (initialDeclaration && forHeadKind) {
4619 bool isForIn, isForOf;
4620 if (!matchInOrOf(&isForIn, &isForOf)) {
4621 return errorResult();
4622 }
4623
4624 if (isForIn) {
4625 *forHeadKind = ParseNodeKind::ForIn;
4626 } else if (isForOf) {
4627 *forHeadKind = ParseNodeKind::ForOf;
4628 } else {
4629 *forHeadKind = ParseNodeKind::ForHead;
4630 }
4631
4632 if (*forHeadKind != ParseNodeKind::ForHead) {
4633 MOZ_TRY_VAR(*forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4634 expressionAfterForInOrOf(*forHeadKind, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4635
4636 return pattern;
4637 }
4638 }
4639
4640 if (!mustMatchToken(TokenKind::Assign, JSMSG_BAD_DESTRUCT_DECL)) {
4641 return errorResult();
4642 }
4643
4644 Node init;
4645 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)
4646 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)
;
4647
4648 return handler_.newAssignment(ParseNodeKind::AssignExpr, pattern, init);
4649}
4650
4651template <class ParseHandler, typename Unit>
4652typename ParseHandler::AssignmentNodeResult
4653GeneralParser<ParseHandler, Unit>::initializerInNameDeclaration(
4654 NameNodeType binding, DeclarationKind declKind, bool initialDeclaration,
4655 YieldHandling yieldHandling, ParseNodeKind* forHeadKind,
4656 Node* forInOrOfExpression) {
4657 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"
, 4657); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assign)"
")"); do { *((volatile int*)__null) = 4657; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4658
4659 uint32_t initializerOffset;
4660 if (!tokenStream.peekOffset(&initializerOffset, TokenStream::SlashIsRegExp)) {
4661 return errorResult();
4662 }
4663
4664 Node initializer;
4665 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)
4666 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)
;
4667
4668 if (forHeadKind && initialDeclaration) {
4669 bool isForIn, isForOf;
4670 if (!matchInOrOf(&isForIn, &isForOf)) {
4671 return errorResult();
4672 }
4673
4674 // An initialized declaration can't appear in a for-of:
4675 //
4676 // for (var/let/const x = ... of ...); // BAD
4677 if (isForOf) {
4678 errorAt(initializerOffset, JSMSG_OF_AFTER_FOR_LOOP_DECL);
4679 return errorResult();
4680 }
4681
4682 if (isForIn) {
4683 // Lexical declarations in for-in loops can't be initialized:
4684 //
4685 // for (let/const x = ... in ...); // BAD
4686 if (DeclarationKindIsLexical(declKind)) {
4687 errorAt(initializerOffset, JSMSG_IN_AFTER_LEXICAL_FOR_DECL);
4688 return errorResult();
4689 }
4690
4691 // This leaves only initialized for-in |var| declarations. ES6
4692 // forbids these; later ES un-forbids in non-strict mode code.
4693 *forHeadKind = ParseNodeKind::ForIn;
4694 if (!strictModeErrorAt(initializerOffset,
4695 JSMSG_INVALID_FOR_IN_DECL_WITH_INIT)) {
4696 return errorResult();
4697 }
4698
4699 MOZ_TRY_VAR(do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4700 *forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(ParseNodeKind
::ForIn, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4701 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)
;
4702 } else {
4703 *forHeadKind = ParseNodeKind::ForHead;
4704 }
4705 }
4706
4707 return handler_.finishInitializerAssignment(binding, initializer);
4708}
4709
4710template <class ParseHandler, typename Unit>
4711typename ParseHandler::NodeResult
4712GeneralParser<ParseHandler, Unit>::declarationName(DeclarationKind declKind,
4713 TokenKind tt,
4714 bool initialDeclaration,
4715 YieldHandling yieldHandling,
4716 ParseNodeKind* forHeadKind,
4717 Node* forInOrOfExpression) {
4718 // Anything other than possible identifier is an error.
4719 if (!TokenKindIsPossibleIdentifier(tt)) {
4720 error(JSMSG_NO_VARIABLE_NAME);
4721 return errorResult();
4722 }
4723
4724 TaggedParserAtomIndex name = bindingIdentifier(yieldHandling);
4725 if (!name) {
4726 return errorResult();
4727 }
4728
4729 NameNodeType binding;
4730 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)
;
4731
4732 TokenPos namePos = pos();
4733
4734 // The '=' context after a variable name in a declaration is an opportunity
4735 // for ASI, and thus for the next token to start an ExpressionStatement:
4736 //
4737 // var foo // VariableDeclaration
4738 // /bar/g; // ExpressionStatement
4739 //
4740 // Therefore get the token here with SlashIsRegExp.
4741 bool matched;
4742 if (!tokenStream.matchToken(&matched, TokenKind::Assign,
4743 TokenStream::SlashIsRegExp)) {
4744 return errorResult();
4745 }
4746
4747 Node declaration;
4748 if (matched) {
4749 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)
4750 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)
4751 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)
4752 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)
;
4753 } else {
4754 declaration = binding;
4755
4756 if (initialDeclaration && forHeadKind) {
4757 bool isForIn, isForOf;
4758 if (!matchInOrOf(&isForIn, &isForOf)) {
4759 return errorResult();
4760 }
4761
4762 if (isForIn) {
4763 *forHeadKind = ParseNodeKind::ForIn;
4764 } else if (isForOf) {
4765 *forHeadKind = ParseNodeKind::ForOf;
4766 } else {
4767 *forHeadKind = ParseNodeKind::ForHead;
4768 }
4769 }
4770
4771 if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
4772 MOZ_TRY_VAR(*forInOrOfExpression,do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
4773 expressionAfterForInOrOf(*forHeadKind, yieldHandling))do { auto mozTryVarTempResult_ = (expressionAfterForInOrOf(*forHeadKind
, yieldHandling)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (*forInOrOfExpression) = mozTryVarTempResult_.unwrap(); } while
(0)
;
4774 } else {
4775 // Normal const declarations, and const declarations in for(;;)
4776 // heads, must be initialized.
4777 if (declKind == DeclarationKind::Const) {
4778 errorAt(namePos.begin, JSMSG_BAD_CONST_DECL);
4779 return errorResult();
4780 }
4781 }
4782 }
4783
4784 // Note the declared name after knowing whether or not we are in a for-of
4785 // loop, due to special early error semantics in Annex B.3.5.
4786 if (!noteDeclaredName(name, declKind, namePos)) {
4787 return errorResult();
4788 }
4789
4790 return declaration;
4791}
4792
4793template <class ParseHandler, typename Unit>
4794typename ParseHandler::DeclarationListNodeResult
4795GeneralParser<ParseHandler, Unit>::declarationList(
4796 YieldHandling yieldHandling, ParseNodeKind kind,
4797 ParseNodeKind* forHeadKind /* = nullptr */,
4798 Node* forInOrOfExpression /* = nullptr */) {
4799 MOZ_ASSERT(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl ||do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDecl"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4800); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDecl"
")"); do { *((volatile int*)__null) = 4800; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4800 kind == ParseNodeKind::ConstDecl)do { static_assert( mozilla::detail::AssertionConditionType<
decltype(kind == ParseNodeKind::VarStmt || kind == ParseNodeKind
::LetDecl || kind == ParseNodeKind::ConstDecl)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(kind == ParseNodeKind::VarStmt
|| kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::
ConstDecl))), 0))) { do { } while (false); MOZ_ReportAssertionFailure
("kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDecl"
, "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 4800); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == ParseNodeKind::VarStmt || kind == ParseNodeKind::LetDecl || kind == ParseNodeKind::ConstDecl"
")"); do { *((volatile int*)__null) = 4800; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4801
4802 DeclarationKind declKind;
4803 switch (kind) {
4804 case ParseNodeKind::VarStmt:
4805 declKind = DeclarationKind::Var;
4806 break;
4807 case ParseNodeKind::ConstDecl:
4808 declKind = DeclarationKind::Const;
4809 break;
4810 case ParseNodeKind::LetDecl:
4811 declKind = DeclarationKind::Let;
4812 break;
4813 default:
4814 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"
, 4814); AnnotateMozCrashReason("MOZ_CRASH(" "Unknown declaration kind"
")"); do { *((volatile int*)__null) = 4814; __attribute__((nomerge
)) ::abort(); } while (false); } while (false)
;
4815 }
4816
4817 DeclarationListNodeType decl;
4818 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)
;
4819
4820 bool moreDeclarations;
4821 bool initialDeclaration = true;
4822 do {
4823 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"
, 4824); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*forHeadKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 4824; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
4824 *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"
, 4824); AnnotateMozCrashReason("MOZ_ASSERT" "(" "*forHeadKind == ParseNodeKind::ForHead"
")"); do { *((volatile int*)__null) = 4824; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false); } } while (
false)
;
4825
4826 TokenKind tt;
4827 if (!tokenStream.getToken(&tt)) {
4828 return errorResult();
4829 }
4830
4831 Node binding;
4832 if (tt == TokenKind::LeftBracket || tt == TokenKind::LeftCurly) {
4833 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)
4834 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)
4835 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)
;
4836 } else {
4837 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)
4838 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)
4839 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)
;
4840 }
4841
4842 handler_.addList(decl, binding);
4843
4844 // If we have a for-in/of loop, the above call matches the entirety
4845 // of the loop head (up to the closing parenthesis).
4846 if (forHeadKind && *forHeadKind != ParseNodeKind::ForHead) {
4847 break;
4848 }
4849
4850 initialDeclaration = false;
4851
4852 if (!tokenStream.matchToken(&moreDeclarations, TokenKind::Comma,
4853 TokenStream::SlashIsRegExp)) {
4854 return errorResult();
4855 }
4856 } while (moreDeclarations);
4857
4858 return decl;
4859}
4860
4861template <class ParseHandler, typename Unit>
4862typename ParseHandler::DeclarationListNodeResult
4863GeneralParser<ParseHandler, Unit>::lexicalDeclaration(
4864 YieldHandling yieldHandling, DeclarationKind kind) {
4865 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"
, 4865); AnnotateMozCrashReason("MOZ_ASSERT" "(" "kind == DeclarationKind::Const || kind == DeclarationKind::Let"
")"); do { *((volatile int*)__null) = 4865; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4866
4867 if (options().selfHostingMode) {
4868 error(JSMSG_SELFHOSTED_LEXICAL);
4869 return errorResult();
4870 }
4871
4872 /*
4873 * Parse body-level lets without a new block object. ES6 specs
4874 * that an execution environment's initial lexical environment
4875 * is the VariableEnvironment, i.e., body-level lets are in
4876 * the same environment record as vars.
4877 *
4878 * However, they cannot be parsed exactly as vars, as ES6
4879 * requires that uninitialized lets throw ReferenceError on use.
4880 *
4881 * See 8.1.1.1.6 and the note in 13.2.1.
4882 */
4883 DeclarationListNodeType decl;
4884 MOZ_TRY_VAR(decl,do { auto mozTryVarTempResult_ = (declarationList(yieldHandling
, kind == DeclarationKind::Const ? ParseNodeKind::ConstDecl :
ParseNodeKind::LetDecl)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decl) = mozTryVarTempResult_.unwrap(); } while (0)
4885 declarationList(yieldHandling, kind == DeclarationKind::Constdo { auto mozTryVarTempResult_ = (declarationList(yieldHandling
, kind == DeclarationKind::Const ? ParseNodeKind::ConstDecl :
ParseNodeKind::LetDecl)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decl) = mozTryVarTempResult_.unwrap(); } while (0)
4886 ? ParseNodeKind::ConstDecldo { auto mozTryVarTempResult_ = (declarationList(yieldHandling
, kind == DeclarationKind::Const ? ParseNodeKind::ConstDecl :
ParseNodeKind::LetDecl)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decl) = mozTryVarTempResult_.unwrap(); } while (0)
4887 : ParseNodeKind::LetDecl))do { auto mozTryVarTempResult_ = (declarationList(yieldHandling
, kind == DeclarationKind::Const ? ParseNodeKind::ConstDecl :
ParseNodeKind::LetDecl)); if ((__builtin_expect(!!(mozTryVarTempResult_
.isErr()), 0))) { return mozTryVarTempResult_.propagateErr();
} (decl) = mozTryVarTempResult_.unwrap(); } while (0)
;
4888 if (!matchOrInsertSemicolon()) {
4889 return errorResult();
4890 }
4891
4892 return decl;
4893}
4894
4895template <class ParseHandler, typename Unit>
4896typename ParseHandler::NameNodeResult
4897GeneralParser<ParseHandler, Unit>::moduleExportName() {
4898 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"
, 4898); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.currentToken().type == TokenKind::String"
")"); do { *((volatile int*)__null) = 4898; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4899 TaggedParserAtomIndex name = anyChars.currentToken().atom();
4900 if (!this->parserAtoms().isModuleExportName(name)) {
4901 error(JSMSG_UNPAIRED_SURROGATE_EXPORT);
4902 return errorResult();
4903 }
4904 return handler_.newStringLiteral(name, pos());
4905}
4906
4907template <class ParseHandler, typename Unit>
4908bool GeneralParser<ParseHandler, Unit>::withClause(ListNodeType attributesSet) {
4909 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"
, 4910); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 4910; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
4910 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"
, 4910); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Assert) || anyChars.isCurrentTokenType(TokenKind::With)"
")"); do { *((volatile int*)__null) = 4910; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
4911
4912 if (!options().importAttributes()) {
4913 error(JSMSG_IMPORT_ASSERTIONS_NOT_SUPPORTED);
4914 return false;
4915 }
4916
4917 if (!abortIfSyntaxParser()) {
4918 return false;
4919 }
4920
4921 if (!mustMatchToken(TokenKind::LeftCurly, JSMSG_CURLY_AFTER_ASSERT)) {
4922 return false;
4923 }
4924
4925 // Handle the form |... assert {}|
4926 TokenKind token;
4927 if (!tokenStream.getToken(&token)) {
4928 return false;
4929 }
4930 if (token == TokenKind::RightCurly) {
4931 return true;
4932 }
4933
4934 js::HashSet<TaggedParserAtomIndex, TaggedParserAtomIndexHasher,
4935 js::SystemAllocPolicy>
4936 usedAssertionKeys;
4937
4938 for (;;) {
4939 TaggedParserAtomIndex keyName;
4940 if (TokenKindIsPossibleIdentifierName(token)) {
4941 keyName = anyChars.currentName();
4942 } else if (token == TokenKind::String) {
4943 keyName = anyChars.currentToken().atom();
4944 } else {
4945 error(JSMSG_ASSERT_KEY_EXPECTED);
4946 return false;
4947 }
4948
4949 auto p = usedAssertionKeys.lookupForAdd(keyName);
4950 if (p) {
4951 UniqueChars str = this->parserAtoms().toPrintableString(keyName);
4952 if (!str) {
4953 ReportOutOfMemory(this->fc_);
4954 return false;
4955 }
4956 error(JSMSG_DUPLICATE_ASSERT_KEY, str.get());
4957 return false;
4958 }
4959 if (!usedAssertionKeys.add(p, keyName)) {
4960 ReportOutOfMemory(this->fc_);
4961 return false;
4962 }
4963
4964 NameNodeType keyNode;
4965 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)
;
4966
4967 if (!mustMatchToken(TokenKind::Colon, JSMSG_COLON_AFTER_ASSERT_KEY)) {
4968 return false;
4969 }
4970 if (!mustMatchToken(TokenKind::String, JSMSG_ASSERT_STRING_LITERAL)) {
4971 return false;
4972 }
4973
4974 NameNodeType valueNode;
4975 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)
;
4976
4977 BinaryNodeType importAttributeNode;
4978 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)
4979 handler_.newImportAttribute(keyNode, valueNode),do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
4980 false)do { auto parserTryVarTempResult_ = (handler_.newImportAttribute
(keyNode, valueNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importAttributeNode) = parserTryVarTempResult_
.unwrap(); } while (0)
;
4981
4982 handler_.addList(attributesSet, importAttributeNode);
4983
4984 if (!tokenStream.getToken(&token)) {
4985 return false;
4986 }
4987 if (token == TokenKind::Comma) {
4988 if (!tokenStream.getToken(&token)) {
4989 return false;
4990 }
4991 }
4992 if (token == TokenKind::RightCurly) {
4993 break;
4994 }
4995 }
4996
4997 return true;
4998}
4999
5000template <class ParseHandler, typename Unit>
5001bool GeneralParser<ParseHandler, Unit>::namedImports(
5002 ListNodeType importSpecSet) {
5003 if (!abortIfSyntaxParser()) {
5004 return false;
5005 }
5006
5007 while (true) {
5008 // Handle the forms |import {} from 'a'| and
5009 // |import { ..., } from 'a'| (where ... is non empty), by
5010 // escaping the loop early if the next token is }.
5011 TokenKind tt;
5012 if (!tokenStream.getToken(&tt)) {
5013 return false;
5014 }
5015
5016 if (tt == TokenKind::RightCurly) {
5017 break;
5018 }
5019
5020 TaggedParserAtomIndex importName;
5021 NameNodeType importNameNode = null();
5022 if (TokenKindIsPossibleIdentifierName(tt)) {
5023 importName = anyChars.currentName();
5024 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)
;
5025 } else if (tt == TokenKind::String) {
5026 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)
;
5027 } else {
5028 error(JSMSG_NO_IMPORT_NAME);
5029 return false;
5030 }
5031
5032 bool matched;
5033 if (!tokenStream.matchToken(&matched, TokenKind::As)) {
5034 return false;
5035 }
5036
5037 if (matched) {
5038 TokenKind afterAs;
5039 if (!tokenStream.getToken(&afterAs)) {
5040 return false;
5041 }
5042
5043 if (!TokenKindIsPossibleIdentifierName(afterAs)) {
5044 error(JSMSG_NO_BINDING_NAME);
5045 return false;
5046 }
5047 } else {
5048 // String export names can't refer to local bindings.
5049 if (tt == TokenKind::String) {
5050 error(JSMSG_AS_AFTER_STRING);
5051 return false;
5052 }
5053
5054 // Keywords cannot be bound to themselves, so an import name
5055 // that is a keyword is a syntax error if it is not followed
5056 // by the keyword 'as'.
5057 // See the ImportSpecifier production in ES6 section 15.2.2.
5058 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"
, 5058); AnnotateMozCrashReason("MOZ_ASSERT" "(" "importName"
")"); do { *((volatile int*)__null) = 5058; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5059 if (IsKeyword(importName)) {
5060 error(JSMSG_AS_AFTER_RESERVED_WORD, ReservedWordToCharZ(importName));
5061 return false;
5062 }
5063 }
5064
5065 TaggedParserAtomIndex bindingAtom = importedBinding();
5066 if (!bindingAtom) {
5067 return false;
5068 }
5069
5070 NameNodeType bindingName;
5071 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)
;
5072 if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
5073 return false;
5074 }
5075
5076 BinaryNodeType importSpec;
5077 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)
5078 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)
;
5079
5080 handler_.addList(importSpecSet, importSpec);
5081
5082 TokenKind next;
5083 if (!tokenStream.getToken(&next)) {
5084 return false;
5085 }
5086
5087 if (next == TokenKind::RightCurly) {
5088 break;
5089 }
5090
5091 if (next != TokenKind::Comma) {
5092 error(JSMSG_RC_AFTER_IMPORT_SPEC_LIST);
5093 return false;
5094 }
5095 }
5096
5097 return true;
5098}
5099
5100template <class ParseHandler, typename Unit>
5101bool GeneralParser<ParseHandler, Unit>::namespaceImport(
5102 ListNodeType importSpecSet) {
5103 if (!abortIfSyntaxParser()) {
5104 return false;
5105 }
5106
5107 if (!mustMatchToken(TokenKind::As, JSMSG_AS_AFTER_IMPORT_STAR)) {
5108 return false;
5109 }
5110 uint32_t begin = pos().begin;
5111
5112 if (!mustMatchToken(TokenKindIsPossibleIdentifierName,
5113 JSMSG_NO_BINDING_NAME)) {
5114 return false;
5115 }
5116
5117 // Namespace imports are not indirect bindings but lexical
5118 // definitions that hold a module namespace object. They are treated
5119 // as const variables which are initialized during the
5120 // ModuleInstantiate step.
5121 TaggedParserAtomIndex bindingName = importedBinding();
5122 if (!bindingName) {
5123 return false;
5124 }
5125 NameNodeType bindingNameNode;
5126 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)
;
5127 if (!noteDeclaredName(bindingName, DeclarationKind::Const, pos())) {
5128 return false;
5129 }
5130
5131 // The namespace import name is currently required to live on the
5132 // environment.
5133 pc_->varScope().lookupDeclaredName(bindingName)->value()->setClosedOver();
5134
5135 UnaryNodeType importSpec;
5136 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)
5137 handler_.newImportNamespaceSpec(begin, bindingNameNode),do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
5138 false)do { auto parserTryVarTempResult_ = (handler_.newImportNamespaceSpec
(begin, bindingNameNode)); if ((__builtin_expect(!!(parserTryVarTempResult_
.isErr()), 0))) { return (false); } (importSpec) = parserTryVarTempResult_
.unwrap(); } while (0)
;
5139
5140 handler_.addList(importSpecSet, importSpec);
5141
5142 return true;
5143}
5144
5145template <class ParseHandler, typename Unit>
5146typename ParseHandler::BinaryNodeResult
5147GeneralParser<ParseHandler, Unit>::importDeclaration() {
5148 if (!abortIfSyntaxParser()) {
5149 return errorResult();
5150 }
5151
5152 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"
, 5152); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 5152; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5153
5154 if (!pc_->atModuleLevel()) {
5155 error(JSMSG_IMPORT_DECL_AT_TOP_LEVEL);
5156 return errorResult();
5157 }
5158
5159 uint32_t begin = pos().begin;
5160 TokenKind tt;
5161 if (!tokenStream.getToken(&tt)) {
5162 return errorResult();
5163 }
5164
5165 ListNodeType importSpecSet;
5166 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)
5167 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)
;
5168
5169 if (tt == TokenKind::String) {
5170 // Handle the form |import 'a'| by leaving the list empty. This is
5171 // equivalent to |import {} from 'a'|.
5172 handler_.setEndPosition(importSpecSet, pos().begin);
5173 } else {
5174 if (tt == TokenKind::LeftCurly) {
5175 if (!namedImports(importSpecSet)) {
5176 return errorResult();
5177 }
5178 } else if (tt == TokenKind::Mul) {
5179 if (!namespaceImport(importSpecSet)) {
5180 return errorResult();
5181 }
5182 } else if (TokenKindIsPossibleIdentifierName(tt)) {
5183 // Handle the form |import a from 'b'|, by adding a single import
5184 // specifier to the list, with 'default' as the import name and
5185 // 'a' as the binding name. This is equivalent to
5186 // |import { default as a } from 'b'|.
5187 NameNodeType importName;
5188 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)
5189 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)
;
5190
5191 TaggedParserAtomIndex bindingAtom = importedBinding();
5192 if (!bindingAtom) {
5193 return errorResult();
5194 }
5195
5196 NameNodeType bindingName;
5197 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)
;
5198
5199 if (!noteDeclaredName(bindingAtom, DeclarationKind::Import, pos())) {
5200 return errorResult();
5201 }
5202
5203 BinaryNodeType importSpec;
5204 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)
;
5205
5206 handler_.addList(importSpecSet, importSpec);
5207
5208 if (!tokenStream.peekToken(&tt)) {
5209 return errorResult();
5210 }
5211
5212 if (tt == TokenKind::Comma) {
5213 tokenStream.consumeKnownToken(tt);
5214 if (!tokenStream.getToken(&tt)) {
5215 return errorResult();
5216 }
5217
5218 if (tt == TokenKind::LeftCurly) {
5219 if (!namedImports(importSpecSet)) {
5220 return errorResult();
5221 }
5222 } else if (tt == TokenKind::Mul) {
5223 if (!namespaceImport(importSpecSet)) {
5224 return errorResult();
5225 }
5226 } else {
5227 error(JSMSG_NAMED_IMPORTS_OR_NAMESPACE_IMPORT);
5228 return errorResult();
5229 }
5230 }
5231 } else {
5232 error(JSMSG_DECLARATION_AFTER_IMPORT);
5233 return errorResult();
5234 }
5235
5236 if (!mustMatchToken(TokenKind::From, JSMSG_FROM_AFTER_IMPORT_CLAUSE)) {
5237 return errorResult();
5238 }
5239
5240 if (!mustMatchToken(TokenKind::String, JSMSG_MODULE_SPEC_AFTER_FROM)) {
5241 return errorResult();
5242 }
5243 }
5244
5245 NameNodeType moduleSpec;
5246 MOZ_TRY_VAR(moduleSpec, stringLiteral())do { auto mozTryVarTempResult_ = (stringLiteral()); if ((__builtin_expect
(!!(mozTryVarTempResult_.isErr()), 0))) { return mozTryVarTempResult_
.propagateErr(); } (moduleSpec) = mozTryVarTempResult_.unwrap
(); } while (0)
;
5247
5248 // The `assert` keyword has a [no LineTerminator here] production before it in
5249 // the grammar -- `with` does not. We need to handle this distinction.
5250 if (!tokenStream.peekTokenSameLine(&tt, TokenStream::SlashIsRegExp)) {
5251 return errorResult();
5252 }
5253
5254 // `with` may have an EOL prior, so peek the next token and replace
5255 // EOL if the next token is `with`.
5256 if (tt == TokenKind::Eol) {
5257 // Doing a regular peek won't produce Eol, but the actual next token.
5258 TokenKind peekedToken;
5259 if (!tokenStream.peekToken(&peekedToken, TokenStream::SlashIsRegExp)) {
5260 return errorResult();
5261 }
5262
5263 if (peekedToken == TokenKind::With) {
5264 tt = TokenKind::With;
5265 }
5266 }
5267
5268 ListNodeType importAttributeList;
5269 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)
5270 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)
;
5271
5272 if (tt == TokenKind::With ||
5273 (tt == TokenKind::Assert && options().importAttributesAssertSyntax())) {
5274 tokenStream.consumeKnownToken(tt, TokenStream::SlashIsRegExp);
5275
5276 if (!withClause(importAttributeList)) {
5277 return errorResult();
5278 }
5279 }
5280
5281 if (!matchOrInsertSemicolon(TokenStream::SlashIsRegExp)) {
5282 return errorResult();
5283 }
5284
5285 BinaryNodeType moduleRequest;
5286 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)
5287 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)
5288 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)
;
5289
5290 BinaryNodeType node;
5291 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)
5292 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)
;
5293 if (!processImport(node)) {
5294 return errorResult();
5295 }
5296
5297 return node;
5298}
5299
5300template <class ParseHandler, typename Unit>
5301inline typename ParseHandler::NodeResult
5302GeneralParser<ParseHandler, Unit>::importDeclarationOrImportExpr(
5303 YieldHandling yieldHandling) {
5304 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"
, 5304); AnnotateMozCrashReason("MOZ_ASSERT" "(" "anyChars.isCurrentTokenType(TokenKind::Import)"
")"); do { *((volatile int*)__null) = 5304; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5305
5306 TokenKind tt;
5307 if (!tokenStream.peekToken(&tt)) {
5308 return errorResult();
5309 }
5310
5311 if (tt == TokenKind::Dot || tt == TokenKind::LeftParen) {
5312 return expressionStatement(yieldHandling);
5313 }
5314
5315 return importDeclaration();
5316}
5317
5318template <typename Unit>
5319bool Parser<FullParseHandler, Unit>::checkExportedName(
5320 TaggedParserAtomIndex exportName) {
5321 if (!pc_->sc()->asModuleContext()->builder.hasExportedName(exportName)) {
5322 return true;
5323 }
5324
5325 UniqueChars str = this->parserAtoms().toPrintableString(exportName);
5326 if (!str) {
5327 ReportOutOfMemory(this->fc_);
5328 return false;
5329 }
5330
5331 error(JSMSG_DUPLICATE_EXPORT_NAME, str.get());
5332 return false;
5333}
5334
5335template <typename Unit>
5336inline bool Parser<SyntaxParseHandler, Unit>::checkExportedName(
5337 TaggedParserAtomIndex exportName) {
5338 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5338); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5338; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5339 return false;
5340}
5341
5342template <class ParseHandler, typename Unit>
5343inline bool GeneralParser<ParseHandler, Unit>::checkExportedName(
5344 TaggedParserAtomIndex exportName) {
5345 return asFinalParser()->checkExportedName(exportName);
5346}
5347
5348template <typename Unit>
5349bool Parser<FullParseHandler, Unit>::checkExportedNamesForArrayBinding(
5350 ListNode* array) {
5351 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"
, 5351); AnnotateMozCrashReason("MOZ_ASSERT" "(" "array->isKind(ParseNodeKind::ArrayExpr)"
")"); do { *((volatile int*)__null) = 5351; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5352
5353 for (ParseNode* node : array->contents()) {
5354 if (node->isKind(ParseNodeKind::Elision)) {
5355 continue;
5356 }
5357
5358 ParseNode* binding;
5359 if (node->isKind(ParseNodeKind::Spread)) {
5360 binding = node->as<UnaryNode>().kid();
5361 } else if (node->isKind(ParseNodeKind::AssignExpr)) {
5362 binding = node->as<AssignmentNode>().left();
5363 } else {
5364 binding = node;
5365 }
5366
5367 if (!checkExportedNamesForDeclaration(binding)) {
5368 return false;
5369 }
5370 }
5371
5372 return true;
5373}
5374
5375template <typename Unit>
5376inline bool Parser<SyntaxParseHandler, Unit>::checkExportedNamesForArrayBinding(
5377 ListNodeType array) {
5378 MOZ_ALWAYS_FALSE(abortIfSyntaxParser())do { if ((__builtin_expect(!!(!(abortIfSyntaxParser())), 1)))
{ } else { do { static_assert( mozilla::detail::AssertionConditionType
<decltype(false)>::isValid, "invalid assertion condition"
); if ((__builtin_expect(!!(!(!!(false))), 0))) { do { } while
(false); MOZ_ReportAssertionFailure("false" " (" "!(abortIfSyntaxParser())"
")", "/var/lib/jenkins/workspace/firefox-scan-build/js/src/frontend/Parser.cpp"
, 5378); AnnotateMozCrashReason("MOZ_DIAGNOSTIC_ASSERT" "(" "false"
") (" "!(abortIfSyntaxParser())" ")"); do { *((volatile int*
)__null) = 5378; __attribute__((nomerge)) ::abort(); } while (
false); } } while (false); } } while (false)
;
5379 return false;
5380}
5381
5382template <class ParseHandler, typename Unit>
5383inline bool
5384GeneralParser<ParseHandler, Unit>::checkExportedNamesForArrayBinding(
5385 ListNodeType array) {
5386 return asFinalParser()->checkExportedNamesForArrayBinding(array);
5387}
5388
5389template <typename Unit>
5390bool Parser<FullParseHandler, Unit>::checkExportedNamesForObjectBinding(
5391 ListNode* obj) {
5392 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"
, 5392); AnnotateMozCrashReason("MOZ_ASSERT" "(" "obj->isKind(ParseNodeKind::ObjectExpr)"
")"); do { *((volatile int*)__null) = 5392; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5393
5394 for (ParseNode* node : obj->contents()) {
5395 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"
, 5398); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5398; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5396 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"
, 5398); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5398; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5397 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"
, 5398); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5398; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
5398 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"
, 5398); AnnotateMozCrashReason("MOZ_ASSERT" "(" "node->isKind(ParseNodeKind::MutateProto) || node->isKind(ParseNodeKind::PropertyDefinition) || node->isKind(ParseNodeKind::Shorthand) || node->isKind(ParseNodeKind::Spread)"
")"); do { *((volatile int*)__null) = 5398; __attribute__((nomerge
)) ::abort(); } while (false); } } while (false)
;
5399
5400 ParseNode* target;
5401 if (node->isKind(ParseNodeKind::Spread)) {
5402 target = node->as<UnaryNode>().kid();
5403 } else {
5404 if (node->isKind(ParseNodeKind::MutateProto)) {
5405 target = node->as<UnaryNode>().kid();
5406 } else {
5407 target = node->as<BinaryNode>().right();
5408 }
5409
5410 if (target->isKind(ParseNodeKind::AssignExpr)) {
5411 target = target->as<AssignmentNode>().left();
5412 }
5413 }
5414
5415 if (!checkExportedNamesForDeclaration(target)) {
5416 return false;
5417 }