1 //! Data collection.
2 //!
3 //! `ScopeBuilder` is the entry point of this module.
4 //!
5 //! Each AST node that will hold bindings (global, block, function, etc.) has a
6 //! corresponding scope builder type defined in this module:
7 //!   * `GlobalScopeBuilder`
8 //!   * `BlockScopeBuilder`
9 //!   * `FunctionExpressionScopeBuilder`
10 //!   * `FunctionParametersScopeBuilder`
11 //!   * `FunctionBodyScopeBuilder`
12 //!
13 //! They follow the pattern:
14 //!   * They are created and pushed to the `ScopeBuilderStack` when the
15 //!     algorithm enters a scope.
16 //!   * They collect the information necessary to build a `ScopeData` object
17 //!     (which will eventually become a `js::ScopeCreationData` on the
18 //!      C++ side).
19 //!   * They stay on the scope builder stack until the algorithm leaves that
20 //!     scope.
21 //!   * Then they are converted by `into_scope_data()`.
22 //!
23 //! Fields in the builder types mostly correspond to local variables in spec
24 //! algorithms.  For example, `GlobalScopeBuilder` has fields named
25 //! `functions_to_initialize`, `declared_function_names`, and
26 //! `declared_var_names` which correspond to the
27 //! [GlobalDeclarationInstantiation][1] algorithm's local variables
28 //! *functionsToInitialize*, *declaredFunctionNames*, and *declaredVarNames*.
29 //!
30 //! This module performs some steps of those algorithms -- the parts that can
31 //! be done at compile time. The results are passed along to the emitter and
32 //! ultimately the JS runtime.
33 //!
34 //! # Syntax-only mode
35 //!
36 //! When doing syntax-only parsing, we collect minimal information, that does
37 //! not include `ScopeData`, but `ScriptStencil` for functions.
38 //!
39 //! [1]: https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
40 
41 use crate::data::FunctionDeclarationPropertyMap;
42 use crate::free_name_tracker::FreeNameTracker;
43 use ast::associated_data::AssociatedData;
44 use ast::source_atom_set::{CommonSourceAtomSetIndices, SourceAtomSetIndex};
45 use ast::source_location_accessor::SourceLocationAccessor;
46 use ast::type_id::NodeTypeIdAccessor;
47 use indexmap::set::IndexSet;
48 use std::collections::hash_map::Keys;
49 use std::collections::{HashMap, HashSet};
50 use stencil::function::{FunctionFlags, FunctionSyntaxKind};
51 use stencil::scope::{
52     BindingName, FunctionScopeData, GlobalScopeData, LexicalScopeData, ScopeData, ScopeDataList,
53     ScopeDataMap, ScopeIndex, VarScopeData,
54 };
55 use stencil::script::{ScriptStencil, ScriptStencilIndex, ScriptStencilList, SourceExtent};
56 
57 /// The kind of items inside the result of VarScopedDeclarations.
58 ///
59 /// This enum isn't actually used, but just for simplifying comment in
60 /// ScopeKind.
61 #[derive(Debug, Clone, PartialEq)]
62 enum VarScopedDeclarationsItemKind {
63     /// Static Semantics: VarScopedDeclarations
64     /// https://tc39.es/ecma262/#sec-variable-statement-static-semantics-varscopeddeclarations
65     ///
66     /// VariableDeclarationList : VariableDeclaration
67     ///
68     /// 1. Return a new List containing VariableDeclaration.
69     ///
70     /// VariableDeclarationList : VariableDeclarationList, VariableDeclaration
71     ///
72     /// 1. Let declarations be VarScopedDeclarations of VariableDeclarationList.
73     /// 2. Append VariableDeclaration to declarations.
74     /// 3. Return declarations.
75     #[allow(dead_code)]
76     VariableDeclaration,
77 
78     /// Static Semantics: VarScopedDeclarations
79     /// https://tc39.es/ecma262/#sec-for-in-and-for-of-statements-static-semantics-varscopeddeclarations
80     ///
81     /// IterationStatement :
82     ///   for ( var ForBinding in Expression ) Statement
83     ///   for ( var ForBinding of AssignmentExpression ) Statement
84     ///   for await ( var ForBinding of AssignmentExpression ) Statement
85     ///
86     /// 1. Let declarations be a List containing ForBinding.
87     /// 2. Append to declarations the elements of the VarScopedDeclarations of
88     ///    Statement.
89     /// 3. Return declarations.
90     #[allow(dead_code)]
91     ForBinding,
92 
93     /// Static Semantics: VarScopedDeclarations
94     /// https://tc39.es/ecma262/#sec-function-definitions-static-semantics-varscopeddeclarations
95     ///
96     /// FunctionStatementList : StatementList
97     ///
98     /// 1. Return the TopLevelVarScopedDeclarations of StatementList.
99 
100     /// Static Semantics: VarScopedDeclarations
101     /// https://tc39.es/ecma262/#sec-scripts-static-semantics-varscopeddeclarations
102     ///
103     /// ScriptBody : StatementList
104     ///
105     /// 1. Return TopLevelVarScopedDeclarations of StatementList.
106 
107     /// Static Semantics: TopLevelVarScopedDeclarations
108     /// https://tc39.es/ecma262/#sec-block-static-semantics-toplevelvarscopeddeclarations
109     ///
110     /// StatementListItem : Declaration
111     ///
112     /// 1. If Declaration is Declaration : HoistableDeclaration, then
113     ///   a. Let declaration be DeclarationPart of HoistableDeclaration.
114     ///   b. Return « declaration ».
115     /// 2. Return a new empty List.
116 
117     /// Static Semantics: DeclarationPart
118     /// https://tc39.es/ecma262/#sec-static-semantics-declarationpart
119     ///
120     /// HoistableDeclaration : FunctionDeclaration
121     ///
122     /// 1. Return FunctionDeclaration.
123     #[allow(dead_code)]
124     FunctionDeclaration,
125 
126     /// HoistableDeclaration : GeneratorDeclaration
127     ///
128     /// 1. Return GeneratorDeclaration.
129     #[allow(dead_code)]
130     GeneratorDeclaration,
131 
132     /// HoistableDeclaration : AsyncFunctionDeclaration
133     ///
134     /// 1. Return AsyncFunctionDeclaration.
135     #[allow(dead_code)]
136     AsyncFunctionDeclaration,
137 
138     /// HoistableDeclaration : AsyncGeneratorDeclaration
139     ///
140     /// 1. Return AsyncGeneratorDeclaration.
141     #[allow(dead_code)]
142     AsyncGeneratorDeclaration,
143 
144     /// Static Semantics: TopLevelVarScopedDeclarations
145     /// https://tc39.es/ecma262/#sec-labelled-statements-static-semantics-toplevelvarscopeddeclarations
146     ///
147     /// LabelledItem : FunctionDeclaration
148     ///
149     /// 1. Return a new List containing FunctionDeclaration.
150     /* FunctionDeclaration */
151 
152     /// Annex B Initializers in ForIn Statement Heads
153     /// https://tc39.es/ecma262/#sec-initializers-in-forin-statement-heads
154     ///
155     /// IterationStatement :
156     ///   for ( var BindingIdentifier Initializer in Expression ) Statement
157     ///
158     /// 1. Let declarations be a List containing BindingIdentifier.
159     /// 2. Append to declarations the elements of the VarScopedDeclarations of
160     ///    Statement.
161     /// 3. Return declarations.
162     #[allow(dead_code)]
163     BindingIdentifier,
164 }
165 
166 /// The kind of items inside the result of LexicallyScopedDeclarations.
167 ///
168 /// This enum isn't actually used, but just for simplifying comment in
169 /// ScopeKind.
170 #[derive(Debug, Clone, PartialEq)]
171 enum LexicallyScopedDeclarations {
172     /// Static Semantics: LexicallyScopedDeclarations
173     /// https://tc39.es/ecma262/#sec-block-static-semantics-lexicallyscopeddeclarations
174     ///
175     /// StatementListItem : Declaration
176     ///
177     /// 1. Return a new List containing DeclarationPart of Declaration.
178 
179     /// Static Semantics: DeclarationPart
180     /// https://tc39.es/ecma262/#sec-static-semantics-declarationpart
181     ///
182     /// HoistableDeclaration : FunctionDeclaration
183     ///
184     /// 1. Return FunctionDeclaration.
185     #[allow(dead_code)]
186     FunctionDeclaration,
187 
188     /// HoistableDeclaration : GeneratorDeclaration
189     ///
190     /// 1. Return GeneratorDeclaration.
191     #[allow(dead_code)]
192     GeneratorDeclaration,
193 
194     /// HoistableDeclaration : AsyncFunctionDeclaration
195     ///
196     /// 1. Return AsyncFunctionDeclaration.
197     #[allow(dead_code)]
198     AsyncFunctionDeclaration,
199 
200     /// HoistableDeclaration : AsyncGeneratorDeclaration
201     ///
202     /// 1. Return AsyncGeneratorDeclaration.
203     #[allow(dead_code)]
204     AsyncGeneratorDeclaration,
205 
206     /// Declaration : ClassDeclaration
207     ///
208     /// 1. Return ClassDeclaration.
209     #[allow(dead_code)]
210     ClassDeclaration,
211 
212     /// Declaration : LexicalDeclaration
213     ///
214     /// 1. Return LexicalDeclaration.
215     #[allow(dead_code)]
216     LexicalDeclarationWithLet,
217     #[allow(dead_code)]
218     LexicalDeclarationWithConst,
219 
220     /// Static Semantics: LexicallyScopedDeclarations
221     /// https://tc39.es/ecma262/#sec-labelled-statements-static-semantics-lexicallyscopeddeclarations
222     ///
223     /// LabelledItem : FunctionDeclaration
224     ///
225     /// 1. Return a new List containing FunctionDeclaration.
226     /* FunctionDeclaration */
227 
228     /// Static Semantics: LexicallyScopedDeclarations
229     /// https://tc39.es/ecma262/#sec-function-definitions-static-semantics-lexicallyscopeddeclarations
230     ///
231     /// FunctionStatementList : StatementList
232     ///
233     /// 1. Return the TopLevelLexicallyScopedDeclarations of StatementList.
234 
235     /// Static Semantics: LexicallyScopedDeclarations
236     /// https://tc39.es/ecma262/#sec-scripts-static-semantics-lexicallyscopeddeclarations
237     ///
238     /// ScriptBody : StatementList
239     ///
240     /// 1. Return TopLevelLexicallyScopedDeclarations of StatementList.
241 
242     /// Static Semantics: TopLevelLexicallyScopedDeclarations
243     /// https://tc39.es/ecma262/#sec-block-static-semantics-toplevellexicallyscopeddeclarations
244     ///
245     /// StatementListItem : Declaration
246     ///
247     /// 1. If Declaration is Declaration : HoistableDeclaration, then
248     ///   a. Return « ».
249     /// 2. Return a new List containing Declaration.
250 
251     /// Static Semantics: LexicallyScopedDeclarations
252     /// https://tc39.es/ecma262/#sec-exports-static-semantics-lexicallyscopeddeclarations
253     ///
254     /// ExportDeclaration : export Declaration
255     ///
256     /// 1. Return a new List containing DeclarationPart of Declaration.
257 
258     /// ExportDeclaration : export default HoistableDeclaration
259     ///
260     /// 1. Return a new List containing DeclarationPart of HoistableDeclaration.
261 
262     /// ExportDeclaration : export default ClassDeclaration
263     ///
264     /// 1. Return a new List containing ClassDeclaration.
265     /* ClassDeclaration */
266 
267     /// ExportDeclaration : export default AssignmentExpression ;
268     ///
269     /// 1. Return a new List containing this ExportDeclaration.
270     #[allow(dead_code)]
271     ExportDeclarationWithAssignmentExpression,
272 }
273 
274 /// Items on the ScopeBuilder.scope_stack.
275 /// Specifies the kind of BindingIdentifier.
276 ///
277 /// This includes only BindingIdentifier that appears inside list or recursive
278 /// structure.
279 ///
280 /// BindingIdentifier that appears only once for a structure
281 /// (e.g. Function.name) should be handled immediately, without using
282 /// ScopeBuilder.scope_stack.
283 #[derive(Debug, Clone, PartialEq)]
284 enum ScopeKind {
285     /// VarScopedDeclarationsItemKind::VariableDeclaration
286     /// VarScopedDeclarationsItemKind::ForBinding
287     /// VarScopedDeclarationsItemKind::BindingIdentifier
288     Var,
289 
290     /// LexicallyScopedDeclarations::LexicalDeclarationWithLet
291     Let,
292 
293     /// LexicallyScopedDeclarations::LexicalDeclarationWithConst
294     Const,
295 
296     /// Pushed when entering function, to catch function name.
297     FunctionName,
298 
299     /// Pushed when entering function parameter, to disable FunctionName's
300     /// effect.
301     /// Equivalent to the case there's no kind on the stack.
302     FunctionParametersAndBody,
303 
304     FormalParameter,
305 
306     #[allow(dead_code)]
307     CatchParameter,
308 
309     /// LexicallyScopedDeclarations::ExportDeclarationWithAssignmentExpression
310     #[allow(dead_code)]
311     Export,
312 
313     /// VarScopedDeclarationsItemKind::FunctionDeclaration
314     /// VarScopedDeclarationsItemKind::GeneratorDeclaration
315     /// VarScopedDeclarationsItemKind::AsyncFunctionDeclaration
316     /// VarScopedDeclarationsItemKind::AsyncGeneratorDeclaration
317     #[allow(dead_code)]
318     ScriptBodyStatementList,
319     #[allow(dead_code)]
320     FunctionStatementList,
321 
322     /// LexicallyScopedDeclarations::FunctionDeclaration
323     /// LexicallyScopedDeclarations::GeneratorDeclaration
324     /// LexicallyScopedDeclarations::AsyncFunctionDeclaration
325     /// LexicallyScopedDeclarations::AsyncGeneratorDeclaration
326     /// LexicallyScopedDeclarations::ClassDeclaration
327     #[allow(dead_code)]
328     BlockStatementList,
329 }
330 
331 /// Index into BaseScopeData.bindings.
332 #[derive(Debug, Clone, Copy, PartialEq)]
333 pub struct BindingIndex {
334     index: usize,
335 }
336 impl BindingIndex {
new(index: usize) -> Self337     fn new(index: usize) -> Self {
338         Self { index }
339     }
340 
next(&self) -> Self341     pub fn next(&self) -> Self {
342         Self {
343             index: self.index + 1,
344         }
345     }
346 }
347 
348 impl From<BindingIndex> for usize {
from(index: BindingIndex) -> usize349     fn from(index: BindingIndex) -> usize {
350         index.index
351     }
352 }
353 
354 #[derive(Debug)]
355 struct PossiblyAnnexBFunction {
356     name: SourceAtomSetIndex,
357     owner_scope_index: ScopeIndex,
358     binding_index: BindingIndex,
359 
360     /// Index of the script in the list of `functions` in the
361     /// `FunctionScriptStencilBuilder`.
362     script_index: ScriptStencilIndex,
363 }
364 
365 #[derive(Debug)]
366 struct PossiblyAnnexBFunctionList {
367     functions: HashMap<SourceAtomSetIndex, Vec<PossiblyAnnexBFunction>>,
368 }
369 
370 impl PossiblyAnnexBFunctionList {
new() -> Self371     fn new() -> Self {
372         Self {
373             functions: HashMap::new(),
374         }
375     }
376 
push( &mut self, name: SourceAtomSetIndex, owner_scope_index: ScopeIndex, binding_index: BindingIndex, script_index: ScriptStencilIndex, )377     fn push(
378         &mut self,
379         name: SourceAtomSetIndex,
380         owner_scope_index: ScopeIndex,
381         binding_index: BindingIndex,
382         script_index: ScriptStencilIndex,
383     ) {
384         if let Some(functions) = self.functions.get_mut(&name) {
385             functions.push(PossiblyAnnexBFunction {
386                 name,
387                 owner_scope_index,
388                 binding_index,
389                 script_index,
390             });
391             return;
392         }
393 
394         let mut functions = Vec::with_capacity(1);
395         functions.push(PossiblyAnnexBFunction {
396             name,
397             owner_scope_index,
398             binding_index,
399             script_index,
400         });
401         self.functions.insert(name, functions);
402     }
403 
remove_if_exists(&mut self, name: SourceAtomSetIndex)404     fn remove_if_exists(&mut self, name: SourceAtomSetIndex) {
405         self.functions.remove(&name);
406     }
407 
mark_annex_b(&self, function_declaration_properties: &mut FunctionDeclarationPropertyMap)408     fn mark_annex_b(&self, function_declaration_properties: &mut FunctionDeclarationPropertyMap) {
409         for functions in &mut self.functions.values() {
410             for fun in functions {
411                 function_declaration_properties.mark_annex_b(fun.script_index);
412             }
413         }
414     }
415 
names(&self) -> Keys<SourceAtomSetIndex, Vec<PossiblyAnnexBFunction>>416     fn names(&self) -> Keys<SourceAtomSetIndex, Vec<PossiblyAnnexBFunction>> {
417         self.functions.keys()
418     }
419 
clear(&mut self)420     fn clear(&mut self) {
421         self.functions.clear();
422     }
423 }
424 
425 /// Common fields across all *ScopeBuilder.
426 #[derive(Debug)]
427 struct BaseScopeBuilder {
428     name_tracker: FreeNameTracker,
429 
430     /// Bindings in this scope can be accessed dynamically by:
431     ///   * direct `eval`
432     ///   * `with` statement
433     ///   * `delete name` statement
434     bindings_accessed_dynamically: bool,
435 }
436 
437 impl BaseScopeBuilder {
new() -> Self438     fn new() -> Self {
439         Self {
440             name_tracker: FreeNameTracker::new(),
441             bindings_accessed_dynamically: false,
442         }
443     }
444 
propagate_common(&mut self, inner: &BaseScopeBuilder)445     fn propagate_common(&mut self, inner: &BaseScopeBuilder) {
446         // When construct such as `eval`, `with` and `delete` access
447         // name dynamically in inner scopes, we have to propagate this
448         // flag to the outer scope such that we prevent optimizations.
449         self.bindings_accessed_dynamically |= inner.bindings_accessed_dynamically;
450     }
451 
propagate_from_inner_non_script(&mut self, inner: &BaseScopeBuilder)452     fn propagate_from_inner_non_script(&mut self, inner: &BaseScopeBuilder) {
453         self.propagate_common(inner);
454         self.name_tracker
455             .propagate_from_inner_non_script(&inner.name_tracker);
456     }
457 
propagate_from_inner_script(&mut self, inner: &BaseScopeBuilder)458     fn propagate_from_inner_script(&mut self, inner: &BaseScopeBuilder) {
459         self.propagate_common(inner);
460         self.name_tracker
461             .propagate_from_inner_script(&inner.name_tracker);
462     }
463 
declare_var(&mut self, name: SourceAtomSetIndex)464     fn declare_var(&mut self, name: SourceAtomSetIndex) {
465         self.name_tracker.note_def(name);
466     }
467 
declare_let(&mut self, name: SourceAtomSetIndex)468     fn declare_let(&mut self, name: SourceAtomSetIndex) {
469         self.name_tracker.note_def(name);
470     }
471 
declare_const(&mut self, name: SourceAtomSetIndex)472     fn declare_const(&mut self, name: SourceAtomSetIndex) {
473         self.name_tracker.note_def(name);
474     }
475 
declare_function(&mut self, name: SourceAtomSetIndex)476     fn declare_function(&mut self, name: SourceAtomSetIndex) {
477         self.name_tracker.note_def(name);
478     }
479 
set_function_name(&mut self, name: SourceAtomSetIndex)480     fn set_function_name(&mut self, name: SourceAtomSetIndex) {
481         self.name_tracker.note_def(name);
482     }
483 
declare_param(&mut self, name: SourceAtomSetIndex)484     fn declare_param(&mut self, name: SourceAtomSetIndex) {
485         self.name_tracker.note_def(name);
486     }
487 }
488 
489 /// Variables declared/used in GlobalDeclarationInstantiation.
490 #[derive(Debug)]
491 struct GlobalScopeBuilder {
492     base: BaseScopeBuilder,
493 
494     /// Runtime Semantics: GlobalDeclarationInstantiation ( script, env )
495     /// https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
496     ///
497     /// Step 8. Let functionsToInitialize be a new empty List.
498     functions_to_initialize: Vec<ScriptStencilIndex>,
499 
500     /// Step 9. Let declaredFunctionNames be a new empty List.
501     declared_function_names: IndexSet<SourceAtomSetIndex>,
502 
503     /// Step 11. Let declaredVarNames be a new empty List.
504     /// NOTE: This is slightly different than the spec that this can contain
505     ///       names in declaredFunctionNames.
506     ///       The duplication should be filtered before the use.
507     declared_var_names: IndexSet<SourceAtomSetIndex>,
508 
509     /// Step 15. Let lexDeclarations be the LexicallyScopedDeclarations of
510     ///          script.
511     let_names: Vec<SourceAtomSetIndex>,
512     const_names: Vec<SourceAtomSetIndex>,
513 
514     scope_index: ScopeIndex,
515 }
516 
517 impl GlobalScopeBuilder {
new(scope_index: ScopeIndex) -> Self518     fn new(scope_index: ScopeIndex) -> Self {
519         Self {
520             base: BaseScopeBuilder::new(),
521             functions_to_initialize: Vec::new(),
522             declared_function_names: IndexSet::new(),
523             declared_var_names: IndexSet::new(),
524             let_names: Vec::new(),
525             const_names: Vec::new(),
526             scope_index,
527         }
528     }
529 
declare_var(&mut self, name: SourceAtomSetIndex)530     fn declare_var(&mut self, name: SourceAtomSetIndex) {
531         // Runtime Semantics: GlobalDeclarationInstantiation ( script, env )
532         // https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
533         //
534         // Step 7. Let varDeclarations be the VarScopedDeclarations of script.
535         //
536         // Step 12. For each d in varDeclarations, do
537         // Step 12.a. If d is a VariableDeclaration, a ForBinding, or a
538         //            BindingIdentifier, then
539         // Step 12.a.i. For each String vn in the BoundNames of d, do
540         // (implicit)
541 
542         // Step 12.a.i.i If vn is not an element of declaredFunctionNames, then
543         // (done in remove_function_names_from_var_names)
544 
545         // Step 12.a.i.1.a. Let vnDefinable be ? envRec.CanDeclareGlobalVar(vn).
546         // Step 12.a.i.1.b. If vnDefinable is false, throw a TypeError
547         //                  exception.
548         // (done in runtime)
549 
550         // Step 12.a.i.1.c. If vn is not an element of declaredVarNames, then
551         // Step 12.a.i.1.a.i. Append vn to declaredVarNames.
552         self.declared_var_names.insert(name);
553         self.base.declare_var(name);
554     }
555 
declare_let(&mut self, name: SourceAtomSetIndex)556     fn declare_let(&mut self, name: SourceAtomSetIndex) {
557         // Runtime Semantics: GlobalDeclarationInstantiation ( script, env )
558         // https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
559         //
560         // Step 15. Let lexDeclarations be the LexicallyScopedDeclarations of
561         //          script.
562         self.let_names.push(name);
563         self.base.declare_let(name);
564     }
565 
declare_const(&mut self, name: SourceAtomSetIndex)566     fn declare_const(&mut self, name: SourceAtomSetIndex) {
567         // Runtime Semantics: GlobalDeclarationInstantiation ( script, env )
568         // https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
569         //
570         // Step 15. Let lexDeclarations be the LexicallyScopedDeclarations of
571         //          script.
572         self.const_names.push(name);
573         self.base.declare_const(name);
574     }
575 
declare_function(&mut self, name: SourceAtomSetIndex, fun_index: ScriptStencilIndex)576     fn declare_function(&mut self, name: SourceAtomSetIndex, fun_index: ScriptStencilIndex) {
577         // Runtime Semantics: GlobalDeclarationInstantiation ( script, env )
578         // https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
579         //
580         // Step 10. For each d in varDeclarations, in reverse list order, do
581         // Step 10.a. If d is neither a VariableDeclaration nor a ForBinding
582         //            nor a BindingIdentifier, then
583         // (implicit)
584 
585         // Step 10.a.i. Assert: d is either a FunctionDeclaration,
586         //              a GeneratorDeclaration, an AsyncFunctionDeclaration,
587         //              or an AsyncGeneratorDeclaration.
588 
589         // Step 10.a.ii. NOTE: If there are multiple function declarations for
590         //               the same name, the last declaration is used.
591 
592         // Step 10.a.iii. Let fn be the sole element of the BoundNames of d.
593 
594         // Step 10.a.iv. If fn is not an element of declaredFunctionNames, then
595         //
596         // NOTE: Instead of iterating in reverse list oder, we iterate in
597         // normal order and overwrite existing item.
598 
599         // Steps 10.a.iv.1. Let fnDefinable be
600         //                  ? envRec.CanDeclareGlobalFunction(fn).
601         // Steps 10.a.iv.2. If fnDefinable is false, throw a TypeError
602         //                  exception.
603         // (done in runtime)
604 
605         // Step 10.a.iv.3. Append fn to declaredFunctionNames.
606         self.declared_function_names.insert(name.clone());
607 
608         // Step 10.a.iv.4. Insert d as the first element of
609         //                 functionsToInitialize.
610         self.functions_to_initialize.push(fun_index);
611 
612         self.base.declare_function(name);
613     }
614 
remove_function_names_from_var_names(&mut self)615     fn remove_function_names_from_var_names(&mut self) {
616         // Runtime Semantics: GlobalDeclarationInstantiation ( script, env )
617         // https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
618         //
619         // Step 12.a.i.i If vn is not an element of declaredFunctionNames, then
620         //
621         // To avoid doing 2-pass, we note all var names, and filter function
622         // names out after visiting all of them.
623         for n in &self.declared_function_names {
624             self.declared_var_names.remove(n);
625         }
626     }
627 
perform_annex_b( &mut self, function_declaration_properties: &mut FunctionDeclarationPropertyMap, possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList, )628     fn perform_annex_b(
629         &mut self,
630         function_declaration_properties: &mut FunctionDeclarationPropertyMap,
631         possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList,
632     ) {
633         // Annex B
634         // Changes to GlobalDeclarationInstantiation
635         // https://tc39.es/ecma262/#sec-web-compat-globaldeclarationinstantiation
636         //
637         // Step 1. Let strict be IsStrict of script.
638         //
639         // FIXME: Once directives are supported, reflect it here.
640         let strict = false;
641 
642         // Step 2. If strict is false, then
643         if strict {
644             return;
645         }
646 
647         // Step 2.a. Let declaredFunctionOrVarNames be a new empty List.
648         // Step 2.b. Append to declaredFunctionOrVarNames the elements of
649         //           declaredFunctionNames.
650         // Step 2.c. Append to declaredFunctionOrVarNames the elements of
651         //           declaredVarNames.
652         //
653         // NOTE: Use `self.declared_var_names` to avoid duplication against
654         //       `declaredVarNames`.
655         //       And duplication against `declaredFunctionNames` will be
656         //       removed in `remove_function_names_from_var_names`.
657 
658         // Step 2.d. For each FunctionDeclaration f that is directly contained
659         //           in the StatementList of a Block, CaseClause, or
660         //           DefaultClause Contained within script, do
661         //
662         // NOTE: `possibly_annex_b_functions` contains all of them.
663 
664         // Step 2.d.i. Let F be StringValue of the BindingIdentifier of f.
665         // Step 2.d.ii. If replacing the FunctionDeclaration f with a
666         //              VariableStatement that has F as a BindingIdentifier
667         //              would not produce any Early Errors for script, then
668         //
669         // NOTE: Early Errors happen if any of top-level lexical has
670         //       the same name.  Filter out those functions here.
671         for n in &self.let_names {
672             possibly_annex_b_functions.remove_if_exists(*n);
673         }
674         for n in &self.const_names {
675             possibly_annex_b_functions.remove_if_exists(*n);
676         }
677 
678         // Step 2.d.ii.1. If env.HasLexicalDeclaration(F) is false, then
679         // Step 2.d.ii.1.a. Let fnDefinable be ? env.CanDeclareGlobalVar(F).
680         // Step 2.d.ii.1.b. If fnDefinable is true, then
681         //
682         // FIXME: Are these steps performed by any implementation?
683         //        https://github.com/tc39/ecma262/issues/2019
684 
685         // Step 2.d.ii.1.b.i. NOTE: A var binding for F is only instantiated
686         //                    here if it is neither a VarDeclaredName nor
687         //                    the name of another FunctionDeclaration.
688         // Step 2.d.ii.1.b.ii. If declaredFunctionOrVarNames does not
689         //                     contain F, then
690         // Step 2.d.ii.1.b.ii.1. Perform
691         //                       ?env.CreateGlobalVarBinding(F, false).
692         // Step 2.d.ii.1.b.ii.2. Append F to declaredFunctionOrVarNames.
693         for n in possibly_annex_b_functions.names() {
694             self.declare_var(*n);
695         }
696 
697         // Step 2.d.ii.1.b.iii. When the FunctionDeclaration f is evaluated,
698         //                      perform the following steps in place of the
699         //                      FunctionDeclaration Evaluation algorithm
700         //                      provided in
701         //                      https://tc39.es/ecma262/#sec-function-definitions-runtime-semantics-evaluation :
702         // Step 2.d.ii.1.b.iii.1. Let genv be the running execution
703         //                        context's VariableEnvironment.
704         // Step 2.d.ii.1.b.iii.2. Let benv be the running execution
705         //                        context's LexicalEnvironment.
706         // Step 2.d.ii.1.b.iii.3. Let fobj be
707         //                        ! benv.GetBindingValue(F, false).
708         // Step 2.d.ii.1.b.iii.4. Perform
709         //                        ? genv.SetMutableBinding(F, fobj, false).
710         // Step 2.d.ii.1.b.iii.5. Return NormalCompletion(empty).
711         possibly_annex_b_functions.mark_annex_b(function_declaration_properties);
712     }
713 
into_scope_data( mut self, function_declaration_properties: &mut FunctionDeclarationPropertyMap, possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList, ) -> ScopeData714     fn into_scope_data(
715         mut self,
716         function_declaration_properties: &mut FunctionDeclarationPropertyMap,
717         possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList,
718     ) -> ScopeData {
719         // Runtime Semantics: GlobalDeclarationInstantiation ( script, env )
720         // https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
721         //
722         // NOTE: Steps are reordered to match the order of binding in runtime.
723 
724         // Step 13. NOTE: Annex B adds additional steps at this point.
725         //
726         // NOTE: Reordered here to reflect the change to
727         //       self.declared_var_names.
728         self.perform_annex_b(function_declaration_properties, possibly_annex_b_functions);
729 
730         // Step 12.a.i.i If vn is not an element of declaredFunctionNames, then
731         self.remove_function_names_from_var_names();
732 
733         let mut data = GlobalScopeData::new(
734             self.declared_var_names.len() + self.declared_function_names.len(),
735             self.let_names.len(),
736             self.const_names.len(),
737             self.functions_to_initialize,
738         );
739 
740         // Step 18. For each String vn in declaredVarNames, in list order, do
741         for n in &self.declared_var_names {
742             // 18.a. Perform ? envRec.CreateGlobalVarBinding(vn, false).
743             let is_closed_over = self.base.name_tracker.is_closed_over_def(n);
744             data.base
745                 .bindings
746                 .push(BindingName::new(*n, is_closed_over))
747         }
748 
749         // Step 17. For each Parse Node f in functionsToInitialize, do
750         for n in &self.declared_function_names {
751             // Step 17.a. Let fn be the sole element of the BoundNames of f.
752             // Step 17.b. Let fo be InstantiateFunctionObject of f with
753             //            argument env.
754             // Step 17.c. Perform
755             //            ? envRec.CreateGlobalFunctionBinding(fn, fo, false).
756             let is_closed_over = self.base.name_tracker.is_closed_over_def(n);
757             data.base
758                 .bindings
759                 .push(BindingName::new_top_level_function(*n, is_closed_over));
760         }
761 
762         // Step 15. Let lexDeclarations be the LexicallyScopedDeclarations of
763         //          script.
764         // Step 16. For each element d in lexDeclarations, do
765         // Step 16.b. For each element dn of the BoundNames of d, do
766         for n in &self.let_names {
767             // Step 16.b.ii. Else,
768             // Step 16.b.ii.1. Perform ? envRec.CreateMutableBinding(dn, false).
769             let is_closed_over = self.base.name_tracker.is_closed_over_def(n);
770             data.base
771                 .bindings
772                 .push(BindingName::new(*n, is_closed_over))
773         }
774         for n in &self.const_names {
775             // Step 16.b.i. If IsConstantDeclaration of d is true, then
776             // Step 16.b.i.1. Perform ? envRec.CreateImmutableBinding(dn, true).
777             let is_closed_over = self.base.name_tracker.is_closed_over_def(n);
778             data.base
779                 .bindings
780                 .push(BindingName::new(*n, is_closed_over))
781         }
782 
783         ScopeData::Global(data)
784     }
785 }
786 
787 #[derive(Debug)]
788 struct FunctionNameAndStencilIndex {
789     name: SourceAtomSetIndex,
790     stencil: ScriptStencilIndex,
791 }
792 
793 /// Variables declared/used in BlockDeclarationInstantiation
794 #[derive(Debug)]
795 struct BlockScopeBuilder {
796     base: BaseScopeBuilder,
797 
798     /// Runtime Semantics: BlockDeclarationInstantiation ( code, env )
799     /// https://tc39.es/ecma262/#sec-blockdeclarationinstantiation
800     ///
801     /// Step 3. Let declarations be the LexicallyScopedDeclarations of code.
802     let_names: Vec<SourceAtomSetIndex>,
803     const_names: Vec<SourceAtomSetIndex>,
804 
805     /// Runtime Semantics: BlockDeclarationInstantiation ( code, env )
806     /// https://tc39.es/ecma262/#sec-blockdeclarationinstantiation
807     ///
808     /// Step 4.b. If d is a FunctionDeclaration, a GeneratorDeclaration, an
809     ///           AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration,
810     ///           then
811     functions: Vec<FunctionNameAndStencilIndex>,
812 
813     /// Scope associated to this builder.
814     scope_index: ScopeIndex,
815 }
816 
817 impl BlockScopeBuilder {
new(scope_index: ScopeIndex) -> Self818     fn new(scope_index: ScopeIndex) -> Self {
819         Self {
820             base: BaseScopeBuilder::new(),
821             let_names: Vec::new(),
822             const_names: Vec::new(),
823             functions: Vec::new(),
824             scope_index,
825         }
826     }
827 
declare_let(&mut self, name: SourceAtomSetIndex)828     fn declare_let(&mut self, name: SourceAtomSetIndex) {
829         // Runtime Semantics: BlockDeclarationInstantiation ( code, env )
830         // https://tc39.es/ecma262/#sec-blockdeclarationinstantiation
831         //
832         // Step 3. Let declarations be the LexicallyScopedDeclarations of code.
833         self.let_names.push(name);
834         self.base.declare_let(name);
835     }
836 
declare_const(&mut self, name: SourceAtomSetIndex)837     fn declare_const(&mut self, name: SourceAtomSetIndex) {
838         // Runtime Semantics: BlockDeclarationInstantiation ( code, env )
839         // https://tc39.es/ecma262/#sec-blockdeclarationinstantiation
840         //
841         // Step 3. Let declarations be the LexicallyScopedDeclarations of code.
842         self.const_names.push(name);
843         self.base.declare_const(name);
844     }
845 
declare_function(&mut self, name: SourceAtomSetIndex, fun_index: ScriptStencilIndex)846     fn declare_function(&mut self, name: SourceAtomSetIndex, fun_index: ScriptStencilIndex) {
847         // Runtime Semantics: BlockDeclarationInstantiation ( code, env )
848         // https://tc39.es/ecma262/#sec-blockdeclarationinstantiation
849         //
850         // Step 3. Let declarations be the LexicallyScopedDeclarations of code.
851         //
852         // Step 4.b. If d is a FunctionDeclaration, a GeneratorDeclaration, an
853         //           AsyncFunctionDeclaration, or an AsyncGeneratorDeclaration,
854         //           then
855         self.functions.push(FunctionNameAndStencilIndex {
856             name,
857             stencil: fun_index,
858         });
859 
860         self.base.declare_function(name);
861     }
862 
into_scope_data( self, enclosing: ScopeIndex, possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList, ) -> ScopeData863     fn into_scope_data(
864         self,
865         enclosing: ScopeIndex,
866         possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList,
867     ) -> ScopeData {
868         let mut data = LexicalScopeData::new_block(
869             self.let_names.len() + self.functions.len(),
870             self.const_names.len(),
871             enclosing,
872             self.functions.iter().map(|n| n.stencil).collect(),
873         );
874 
875         // Runtime Semantics: BlockDeclarationInstantiation ( code, env )
876         // https://tc39.es/ecma262/#sec-blockdeclarationinstantiation
877         //
878         // Step 1. Let envRec be env's EnvironmentRecord.
879         // Step 2. Assert: envRec is a declarative Environment Record.
880         // (implicit)
881 
882         // Step 4. For each element d in declarations, do
883         // Step 4.a. For each element dn of the BoundNames of d, do
884         for n in &self.let_names {
885             // Step 4.a.ii. Else,
886             // Step 4.a.ii.1. Perform ! envRec.CreateMutableBinding(dn, false).
887             let is_closed_over = self.base.name_tracker.is_closed_over_def(n);
888             data.base
889                 .bindings
890                 .push(BindingName::new(*n, is_closed_over));
891         }
892         for n in &self.functions {
893             // Step 4.b. If d is a FunctionDeclaration, a GeneratorDeclaration,
894             //           an AsyncFunctionDeclaration,
895             //           or an AsyncGeneratorDeclaration, then
896             // Step 4.b.i. Let fn be the sole element of the BoundNames of d.
897             // Step 4.b.ii. Let fo be InstantiateFunctionObject of d with
898             //              argument env.
899             // Step 4.b.iii. Perform envRec.InitializeBinding(fn, fo).
900             let is_closed_over = self.base.name_tracker.is_closed_over_def(&n.name);
901             let binding_index = BindingIndex::new(data.base.bindings.len());
902             data.base
903                 .bindings
904                 .push(BindingName::new(n.name, is_closed_over));
905 
906             possibly_annex_b_functions.push(n.name, self.scope_index, binding_index, n.stencil);
907         }
908         for n in &self.const_names {
909             // Step 4.a.i. If IsConstantDeclaration of d is true, then
910             // Step 4.a.i.1. Perform ! envRec.CreateImmutableBinding(dn, true).
911             let is_closed_over = self.base.name_tracker.is_closed_over_def(n);
912             data.base
913                 .bindings
914                 .push(BindingName::new(*n, is_closed_over));
915         }
916 
917         ScopeData::Lexical(data)
918     }
919 }
920 
921 /// Scope for a FunctionExpression.
922 ///
923 /// The FunctionExpression `(function f() { return f; })` introduces a lexical
924 /// scope with a single binding `f`, set to the function itself. We create this
925 /// scope builder whether the FunctionExpression has a name or not, for
926 /// consistency.
927 #[derive(Debug)]
928 struct FunctionExpressionScopeBuilder {
929     base: BaseScopeBuilder,
930 
931     function_expression_name: Option<SourceAtomSetIndex>,
932 
933     scope_index: ScopeIndex,
934 }
935 
936 impl FunctionExpressionScopeBuilder {
new(scope_index: ScopeIndex) -> Self937     fn new(scope_index: ScopeIndex) -> Self {
938         Self {
939             base: BaseScopeBuilder::new(),
940             function_expression_name: None,
941             scope_index,
942         }
943     }
944 
set_function_name(&mut self, name: SourceAtomSetIndex)945     fn set_function_name(&mut self, name: SourceAtomSetIndex) {
946         self.function_expression_name = Some(name);
947         self.base.set_function_name(name);
948     }
949 
into_scope_data(self, enclosing: ScopeIndex) -> ScopeData950     fn into_scope_data(self, enclosing: ScopeIndex) -> ScopeData {
951         match &self.function_expression_name {
952             Some(name) => {
953                 // Runtime Semantics: Evaluation
954                 // https://tc39.es/ecma262/#sec-function-definitions-runtime-semantics-evaluation
955                 //
956                 // FunctionExpression :
957                 //   function BindingIdentifier ( FormalParameters )
958                 //   { FunctionBody }
959                 //
960                 // Step 1. Let scope be the running execution context's
961                 //         LexicalEnvironment.
962                 // Step 2. Let funcEnv be NewDeclarativeEnvironment(scope).
963                 // Step 3. Let envRec be funcEnv's EnvironmentRecord.
964                 let mut data = LexicalScopeData::new_named_lambda(enclosing);
965 
966                 // Step 4. Let name be StringValue of BindingIdentifier .
967                 // Step 5. Perform envRec.CreateImmutableBinding(name, false).
968                 let is_closed_over = self.base.name_tracker.is_closed_over_def(name);
969                 data.base
970                     .bindings
971                     .push(BindingName::new(*name, is_closed_over));
972 
973                 ScopeData::Lexical(data)
974             }
975             None => ScopeData::Alias(enclosing),
976         }
977     }
978 }
979 
980 /// The value of [[ThisMode]] internal slot of function object.
981 /// https://tc39.es/ecma262/#sec-ecmascript-function-objects
982 ///
983 /// Defines how this references are interpreted within the formal parameters
984 /// and code body of the function.
985 #[derive(Debug, Clone, PartialEq)]
986 enum ThisMode {
987     /// `this` refers to the `this` value of a lexically enclosing function.
988     Lexical,
989 
990     /// `this` value is used exactly as provided by an invocation of the
991     /// function.
992     #[allow(dead_code)]
993     Strict,
994 
995     /// `this` value of `undefined` is interpreted as a reference to the global
996     /// object.
997     Global,
998 }
999 
1000 /// The result of converting the builder of function parameters and body
1001 /// into scope data.
1002 struct FunctionScopeDataSet {
1003     /// ScopeData::Function.
1004     function: ScopeData,
1005 
1006     /// Either ScopeData::Var or ScopeData::Alias.
1007     extra_body_var: ScopeData,
1008 
1009     /// Either ScopeData::Lexical or ScopeData::Alias.
1010     lexical: ScopeData,
1011 }
1012 
1013 /// See FunctionParametersScopeBuilder.state.
1014 #[derive(Debug)]
1015 enum FunctionParametersState {
1016     /// Entered FormalParameters.
1017     Init,
1018 
1019     /// Entered Parameter.
1020     /// At this point, this parameter can be either non-destructuring or
1021     /// destructuring.
1022     /// If BindingIdentifier is found in this state, this parameter is
1023     /// non-destructuring.
1024     Parameter,
1025 
1026     /// Entered BindingPattern inside Parameter.
1027     /// This parameter is destructuring.
1028     DestructuringParameter,
1029 
1030     /// Entered rest parameter.
1031     /// At this point, the rest parameter can be either non-destructuring or
1032     /// destructuring.
1033     /// If BindingIdentifier is found in this state, the rest parameter is
1034     /// non-destructuring.
1035     RestParameter,
1036 
1037     /// Entered BindingPattern inside rest parameter.
1038     /// The rest parameter is destructuring.
1039     DestructuringRestParameter,
1040 }
1041 
1042 /// Function parameters in FormalParameters, and variables used in
1043 /// FormalParameters
1044 /// Shared part between full-parse and syntax-only parse.
1045 #[derive(Debug)]
1046 struct SharedFunctionParametersScopeBuilder {
1047     base: BaseScopeBuilder,
1048 
1049     /// FunctionDeclarationInstantiation ( func, argumentsList )
1050     /// https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1051     ///
1052     /// Step 3. Let strict be func.[[Strict]].
1053     strict: bool,
1054 
1055     /// Step 5. Let parameterNames be the BoundNames of formals.
1056     parameter_names: HashSet<SourceAtomSetIndex>,
1057 
1058     /// Step 7. Let simpleParameterList be IsSimpleParameterList of formals.
1059     simple_parameter_list: bool,
1060 
1061     /// Step 8. Let hasParameterExpressions be ContainsExpression of formals.
1062     has_parameter_expressions: bool,
1063 
1064     /// Step 17. Else if "arguments" is an element of parameterNames, then
1065     parameter_has_arguments: bool,
1066 }
1067 
1068 impl SharedFunctionParametersScopeBuilder {
new(is_arrow: bool) -> Self1069     fn new(is_arrow: bool) -> Self {
1070         let mut base = BaseScopeBuilder::new();
1071 
1072         if !is_arrow {
1073             // Arrow function closes over this/arguments from enclosing
1074             // function.
1075             base.name_tracker
1076                 .note_def(CommonSourceAtomSetIndices::this());
1077             base.name_tracker
1078                 .note_def(CommonSourceAtomSetIndices::arguments());
1079         }
1080 
1081         Self {
1082             base,
1083 
1084             // FIMXE: Receive the enclosing strictness,
1085             //        and update on directive in body.
1086             strict: false,
1087 
1088             parameter_names: HashSet::new(),
1089             simple_parameter_list: true,
1090             has_parameter_expressions: false,
1091             parameter_has_arguments: false,
1092         }
1093     }
1094 
perform_annex_b( &self, function_declaration_properties: &mut FunctionDeclarationPropertyMap, possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList, body_scope_builder: &mut SharedFunctionBodyScopeBuilder, )1095     fn perform_annex_b(
1096         &self,
1097         function_declaration_properties: &mut FunctionDeclarationPropertyMap,
1098         possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList,
1099         body_scope_builder: &mut SharedFunctionBodyScopeBuilder,
1100     ) {
1101         // Annex B
1102         // Changes to FunctionDeclarationInstantiation
1103         // https://tc39.es/ecma262/#sec-web-compat-functiondeclarationinstantiation
1104         //
1105         // Step 1. If strict is false, then
1106         //
1107         // FIXME: Once directives are supported, reflect it here.
1108         let strict = false;
1109         if strict {
1110             return;
1111         }
1112 
1113         // Step 1.a. For each FunctionDeclaration f that is directly contained
1114         //           in the StatementList of a Block, CaseClause, or
1115         //           DefaultClause, do
1116         //
1117         // NOTE: `possibly_annex_b_functions` contains all of them.
1118 
1119         // Step 1.a.i. Let F be StringValue of the BindingIdentifier of f.
1120         // Step 1.a.ii. If replacing the FunctionDeclaration f with a
1121         //              VariableStatement that has F as a BindingIdentifier
1122         //              would not produce any Early Errors for func and F is
1123         //              not an element of parameterNames, then
1124         //
1125         // NOTE: Early Errors happen if any of top-level lexical has
1126         //       the same name.  Filter out those functions here.
1127         for n in &body_scope_builder.let_names {
1128             possibly_annex_b_functions.remove_if_exists(*n);
1129         }
1130         for n in &body_scope_builder.const_names {
1131             possibly_annex_b_functions.remove_if_exists(*n);
1132         }
1133         for n in &self.parameter_names {
1134             possibly_annex_b_functions.remove_if_exists(*n);
1135         }
1136 
1137         // Step 1.a.ii.1. NOTE: A var binding for F is only instantiated here
1138         //                if it is neither a VarDeclaredName, the name of a
1139         //                formal parameter, or another FunctionDeclaration.
1140         //
1141         // NOTE: The binding is merged into the list of other var names.
1142 
1143         // Step 1.a.ii.2. If initializedBindings does not contain F and F is
1144         //                not "arguments", then
1145         possibly_annex_b_functions.remove_if_exists(CommonSourceAtomSetIndices::arguments());
1146 
1147         // Step 1.a.ii.2.a. Perform ! varEnv.CreateMutableBinding(F, false).
1148         // Step 1.a.ii.2.b. Perform varEnv.InitializeBinding(F, undefined).
1149         // Step 1.a.ii.2.c. Append F to instantiatedVarNames.
1150         for n in possibly_annex_b_functions.names() {
1151             body_scope_builder.declare_var(*n);
1152         }
1153 
1154         // Step 1.a.ii.3. When the FunctionDeclaration f is evaluated, perform
1155         //                the following steps in place of the
1156         //                FunctionDeclaration Evaluation algorithm provided in
1157         //                https://tc39.es/ecma262/#sec-function-definitions-runtime-semantics-evaluation
1158         // Step 1.a.ii.3.a. Let fenv be the running execution context's
1159         //                  VariableEnvironment.
1160         // Step 1.a.ii.3.b. Let benv be the running execution context's
1161         //                  LexicalEnvironment.
1162         // Step 1.a.ii.3.c. Let fobj be ! benv.GetBindingValue(F, false).
1163         // Step 1.a.ii.3.d. Perform ! fenv.SetMutableBinding(F, fobj, false).
1164         // Step 1.a.ii.3.e. Return NormalCompletion(empty).
1165         possibly_annex_b_functions.mark_annex_b(function_declaration_properties);
1166     }
1167 
before_binding_pattern(&mut self)1168     fn before_binding_pattern(&mut self) {
1169         // Static Semantics: IsSimpleParameterList
1170         // https://tc39.es/ecma262/#sec-destructuring-binding-patterns-static-semantics-issimpleparameterlist
1171         //
1172         // BindingElement : BindingPattern
1173         //
1174         //   1. Return false.
1175         //
1176         // BindingElement : BindingPattern Initializer
1177         //
1178         //   1. Return false.
1179         self.simple_parameter_list = false;
1180     }
1181 
before_rest_parameter(&mut self)1182     fn before_rest_parameter(&mut self) {
1183         // Static Semantics: IsSimpleParameterList
1184         // https://tc39.es/ecma262/#sec-function-definitions-static-semantics-issimpleparameterlist
1185         //
1186         // FormalParameters : FunctionRestParameter
1187         //
1188         //   1. Return false.
1189         //
1190         // FormalParameters : FormalParameterList , FunctionRestParameter
1191         //
1192         //   1. Return false.
1193         self.simple_parameter_list = false;
1194     }
1195 
after_initializer(&mut self)1196     fn after_initializer(&mut self) {
1197         // Static Semantics: IsSimpleParameterList
1198         // https://tc39.es/ecma262/#sec-destructuring-binding-patterns-static-semantics-issimpleparameterlist
1199         //
1200         // BindingElement : BindingPattern Initializer
1201         //
1202         //   1. Return false.
1203         //
1204         // SingleNameBinding : BindingIdentifier Initializer
1205         //
1206         //   1. Return false.
1207         self.simple_parameter_list = false;
1208 
1209         // FunctionDeclarationInstantiation ( func, argumentsList )
1210         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1211         //
1212         // Step 8. Let hasParameterExpressions be ContainsExpression of formals.
1213 
1214         // Static Semantics: ContainsExpression
1215         // https://tc39.es/ecma262/#sec-destructuring-binding-patterns-static-semantics-containsexpression
1216         //
1217         // BindingElement : BindingPattern Initializer
1218         //
1219         //   1. Return true.
1220         //
1221         // SingleNameBinding : BindingIdentifier Initializer
1222         //
1223         //   1. Return true.
1224         self.has_parameter_expressions = true;
1225     }
1226 
before_computed_property_name(&mut self)1227     fn before_computed_property_name(&mut self) {
1228         // FunctionDeclarationInstantiation ( func, argumentsList )
1229         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1230         //
1231         // Step 8. Let hasParameterExpressions be ContainsExpression of formals.
1232 
1233         // Static Semantics: ContainsExpression
1234         // https://tc39.es/ecma262/#sec-destructuring-binding-patterns-static-semantics-containsexpression
1235         //
1236         // BindingProperty : PropertyName : BindingElement
1237         //
1238         //   1. Let has be IsComputedPropertyKey of PropertyName .
1239         //   2. If has is true, return true.
1240         //   3. Return ContainsExpression of BindingElement .
1241         self.has_parameter_expressions = true;
1242     }
1243 
declare_param(&mut self, name: SourceAtomSetIndex)1244     fn declare_param(&mut self, name: SourceAtomSetIndex) {
1245         // Step 17. Else if "arguments" is an element of parameterNames,
1246         //          then
1247         if name == CommonSourceAtomSetIndices::arguments() {
1248             self.parameter_has_arguments = true;
1249         }
1250 
1251         self.parameter_names.insert(name.clone());
1252         self.base.declare_param(name);
1253     }
1254 
is_parameter_closed_over(&self) -> bool1255     fn is_parameter_closed_over(&self) -> bool {
1256         for name in &self.parameter_names {
1257             if self.base.name_tracker.is_closed_over_def(name) {
1258                 return true;
1259             }
1260         }
1261 
1262         false
1263     }
1264 }
1265 
1266 /// Function parameters in FormalParameters, and variables used in
1267 /// FormalParameters
1268 /// For full-parse.
1269 #[derive(Debug)]
1270 struct FunctionParametersScopeBuilder {
1271     shared: SharedFunctionParametersScopeBuilder,
1272 
1273     /// State of the analysis.
1274     /// This is used to determine what kind of binding the parameter is.
1275     state: FunctionParametersState,
1276 
1277     /// List of positional parameter or None if destructuring.
1278     /// This includes rest parameter.
1279     positional_parameter_names: Vec<Option<SourceAtomSetIndex>>,
1280 
1281     /// List of non-positional parameters (destructuring parameters).
1282     non_positional_parameter_names: Vec<SourceAtomSetIndex>,
1283 
1284     /// FunctionDeclarationInstantiation ( func, argumentsList )
1285     /// https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1286     ///
1287     /// Step 16. If func.[[ThisMode]] is lexical, then
1288     this_mode: ThisMode,
1289 
1290     /// Step 6. If parameterNames has any duplicate entries, let hasDuplicates
1291     ///         be true. Otherwise, let hasDuplicates be false.
1292     has_duplicates: bool,
1293 
1294     scope_index: ScopeIndex,
1295 
1296     /// Index of the script in the list of `functions` in the
1297     /// `FunctionScriptStencilBuilder`.
1298     script_index: ScriptStencilIndex,
1299 
1300     has_direct_eval: bool,
1301 
1302     is_arrow: bool,
1303 }
1304 
1305 impl FunctionParametersScopeBuilder {
new(scope_index: ScopeIndex, is_arrow: bool, script_index: ScriptStencilIndex) -> Self1306     fn new(scope_index: ScopeIndex, is_arrow: bool, script_index: ScriptStencilIndex) -> Self {
1307         Self {
1308             shared: SharedFunctionParametersScopeBuilder::new(is_arrow),
1309 
1310             state: FunctionParametersState::Init,
1311 
1312             positional_parameter_names: Vec::new(),
1313             non_positional_parameter_names: Vec::new(),
1314 
1315             // FIXME: Receive correct value.
1316             this_mode: ThisMode::Global,
1317 
1318             has_duplicates: false,
1319             scope_index,
1320             script_index,
1321             has_direct_eval: false,
1322             is_arrow,
1323         }
1324     }
1325 
before_parameter(&mut self)1326     fn before_parameter(&mut self) {
1327         match self.state {
1328             FunctionParametersState::Init => {
1329                 self.state = FunctionParametersState::Parameter;
1330             }
1331             FunctionParametersState::Parameter => {
1332                 self.state = FunctionParametersState::Parameter;
1333             }
1334             FunctionParametersState::DestructuringParameter => {
1335                 self.state = FunctionParametersState::Parameter;
1336             }
1337             FunctionParametersState::RestParameter
1338             | FunctionParametersState::DestructuringRestParameter => panic!("Invalid transition"),
1339         }
1340     }
1341 
before_binding_pattern(&mut self)1342     fn before_binding_pattern(&mut self) {
1343         self.shared.before_binding_pattern();
1344 
1345         match self.state {
1346             FunctionParametersState::Parameter => {
1347                 self.positional_parameter_names.push(None);
1348                 self.state = FunctionParametersState::DestructuringParameter;
1349             }
1350             FunctionParametersState::DestructuringParameter => {}
1351             FunctionParametersState::RestParameter => {
1352                 self.positional_parameter_names.push(None);
1353                 self.state = FunctionParametersState::DestructuringRestParameter;
1354             }
1355             FunctionParametersState::DestructuringRestParameter => {}
1356             FunctionParametersState::Init => panic!("Invalid transition"),
1357         }
1358     }
1359 
before_rest_parameter(&mut self)1360     fn before_rest_parameter(&mut self) {
1361         self.shared.before_rest_parameter();
1362 
1363         match self.state {
1364             FunctionParametersState::Init
1365             | FunctionParametersState::Parameter
1366             | FunctionParametersState::DestructuringParameter => {
1367                 self.state = FunctionParametersState::RestParameter;
1368             }
1369             FunctionParametersState::RestParameter
1370             | FunctionParametersState::DestructuringRestParameter => panic!("Invalid transition"),
1371         }
1372     }
1373 
after_initializer(&mut self)1374     fn after_initializer(&mut self) {
1375         self.shared.after_initializer();
1376     }
1377 
before_computed_property_name(&mut self)1378     fn before_computed_property_name(&mut self) {
1379         self.shared.before_computed_property_name();
1380     }
1381 
declare_param(&mut self, name: SourceAtomSetIndex)1382     fn declare_param(&mut self, name: SourceAtomSetIndex) {
1383         // FunctionDeclarationInstantiation ( func, argumentsList )
1384         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1385         //
1386         // Step 5. Let parameterNames be the BoundNames of formals.
1387         match self.state {
1388             FunctionParametersState::Init => panic!("Invalid state"),
1389             FunctionParametersState::Parameter => {
1390                 self.positional_parameter_names.push(Some(name.clone()));
1391             }
1392             FunctionParametersState::DestructuringParameter => {
1393                 self.non_positional_parameter_names.push(name.clone());
1394             }
1395             FunctionParametersState::RestParameter => {
1396                 self.positional_parameter_names.push(Some(name.clone()));
1397             }
1398             FunctionParametersState::DestructuringRestParameter => {
1399                 self.non_positional_parameter_names.push(name.clone());
1400             }
1401         }
1402 
1403         // Step 6. If parameterNames has any duplicate entries, let
1404         //         hasDuplicates be true. Otherwise, let hasDuplicates be
1405         //         false.
1406         if self.shared.parameter_names.contains(&name) {
1407             self.has_duplicates = true;
1408         }
1409 
1410         self.shared.declare_param(name);
1411     }
1412 
into_scope_data_set( self, enclosing: ScopeIndex, body_scope_builder: FunctionBodyScopeBuilder, ) -> FunctionScopeDataSet1413     fn into_scope_data_set(
1414         self,
1415         enclosing: ScopeIndex,
1416         body_scope_builder: FunctionBodyScopeBuilder,
1417     ) -> FunctionScopeDataSet {
1418         // FunctionDeclarationInstantiation ( func, argumentsList )
1419         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1420         //
1421         // Step 15. Let argumentsObjectNeeded be true.
1422         let mut arguments_object_needed = true;
1423 
1424         // Step 16. If func.[[ThisMode]] is lexical, then
1425         if self.this_mode == ThisMode::Lexical {
1426             // Step 16.a. NOTE: Arrow functions never have an arguments objects.
1427             // Step 16.b. Set argumentsObjectNeeded to false.
1428             arguments_object_needed = false;
1429         }
1430         // Step 17. Else if "arguments" is an element of parameterNames,
1431         //          then
1432         else if self.shared.parameter_has_arguments {
1433             // Step 17.a. Set argumentsObjectNeeded to false.
1434             arguments_object_needed = false;
1435         }
1436         // Step 18. Else if hasParameterExpressions is false, then
1437         else if !self.shared.parameter_has_arguments {
1438             // Step 18.a. If "arguments" is an element of functionNames or if
1439             //            "arguments" is
1440             //            an element of lexicalNames, then
1441             if body_scope_builder.shared.function_or_lexical_has_arguments {
1442                 // Step 18.a.i. Set argumentsObjectNeeded to false.
1443                 arguments_object_needed = false;
1444             }
1445         }
1446 
1447         // NOTE: In SpiderMonkey, single environment can have multiple
1448         //       binding kind.
1449         //       It's not necessary to create yet another environment here.
1450         //
1451         // Step 19. If strict is true or if hasParameterExpressions is false,
1452         //          then
1453         if self.shared.strict || !self.shared.has_parameter_expressions {
1454             // Step 19.a. NOTE: Only a single lexical environment is needed for
1455             //            the parameters and top-level vars.
1456             // Step 19.b. Let env be the LexicalEnvironment of calleeContext.
1457             // Step 19.c. Let envRec be env's EnvironmentRecord.
1458         }
1459         // Step 20. Else,
1460         else {
1461             // Step 20.a. NOTE: A separate Environment Record is needed to
1462             //            ensure that bindings created by direct eval calls in
1463             //            the formal parameter list are outside the environment
1464             //            where parameters are declared.
1465             // Step 20.b. Let calleeEnv be the LexicalEnvironment of
1466             //            calleeContext.
1467             // Step 20.c. Let env be NewDeclarativeEnvironment(calleeEnv).
1468             // Step 20.d. Let envRec be env's EnvironmentRecord.
1469             // Step 20.e. Assert: The VariableEnvironment of calleeContext is
1470             //            calleeEnv.
1471             // Step 20.f. Set the LexicalEnvironment of calleeContext to env.
1472         }
1473 
1474         let has_extra_body_var_scope = self.shared.has_parameter_expressions;
1475 
1476         // NOTE: Names in `body_scope_builder.var_names` is skipped if
1477         //       it's `arguments`, at step 27.c.i.
1478         //       The count here isn't the exact number of var bindings, but
1479         //       it's fine given FunctionScopeData::new doesn't require the
1480         //       exact number, but just maximum number.
1481         let function_max_var_names_count = if has_extra_body_var_scope {
1482             0
1483         } else {
1484             body_scope_builder.shared.var_names.len()
1485         };
1486 
1487         let mut function_scope_data = FunctionScopeData::new(
1488             self.shared.has_parameter_expressions,
1489             self.positional_parameter_names.len(),
1490             self.non_positional_parameter_names.len(),
1491             function_max_var_names_count,
1492             enclosing,
1493             self.script_index,
1494             self.is_arrow,
1495         );
1496 
1497         // FunctionDeclarationInstantiation ( func, argumentsList )
1498         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1499         //
1500         // Step 21. For each String paramName in parameterNames, do
1501         // Step 21.a. Let alreadyDeclared be envRec.HasBinding(paramName).
1502         // Step 21.b. NOTE: Early errors ensure that duplicate parameter names
1503         //            can only occur in non-strict functions that do not have
1504         //            parameter default values or rest parameters.
1505         // Step 21.c. If alreadyDeclared is false, then
1506         // Step 21.c.i. Perform ! envRec.CreateMutableBinding(paramName, false).
1507         // Step 21.c.ii. If hasDuplicates is true, then
1508         // Step 21.c.ii.1. Perform
1509         //                 ! envRec.InitializeBinding(paramName, undefined).
1510         //
1511         // NOTE: The existence of duplication isn't encoded in scope data.
1512         for maybe_name in &self.positional_parameter_names {
1513             match maybe_name {
1514                 Some(n) => {
1515                     let is_closed_over = self.shared.base.name_tracker.is_closed_over_def(n)
1516                         || (!has_extra_body_var_scope
1517                             && body_scope_builder
1518                                 .shared
1519                                 .base
1520                                 .name_tracker
1521                                 .is_closed_over_def(n));
1522                     function_scope_data
1523                         .base
1524                         .bindings
1525                         .push(Some(BindingName::new(*n, is_closed_over)))
1526                 }
1527                 None => function_scope_data.base.bindings.push(None),
1528             }
1529         }
1530         for n in &self.non_positional_parameter_names {
1531             let is_closed_over = self.shared.base.name_tracker.is_closed_over_def(n)
1532                 || (!has_extra_body_var_scope
1533                     && body_scope_builder
1534                         .shared
1535                         .base
1536                         .name_tracker
1537                         .is_closed_over_def(n));
1538             function_scope_data
1539                 .base
1540                 .bindings
1541                 .push(Some(BindingName::new(*n, is_closed_over)))
1542         }
1543 
1544         // Step 22. If argumentsObjectNeeded is true, then
1545         // Steps 22.a-b. Create{Unm,M}appedArgumentsObject
1546         // (done in emitter)
1547 
1548         // Step 22.c. If strict is true, then
1549         // Step 22.c.i. Perform
1550         //              ! envRec.CreateImmutableBinding("arguments", false).
1551         // Step 22.d. Else,
1552         // Step 22.d.i. Perform
1553         //              ! envRec.CreateMutableBinding("arguments", false).
1554         // Step 22.e. Call envRec.InitializeBinding("arguments", ao).
1555         //
1556         // NOTE: In SpiderMonkey, whether immutable or not is not stored
1557         //       in scope data, but checked while parsing, including
1558         //       when parsing eval inside function.
1559 
1560         // Step 22.f. Let parameterBindings be a new List of parameterNames
1561         //            with "arguments" appended.
1562         //
1563         // NOTE: Done in each consumer of parameterNames.
1564 
1565         // Step 23. Else,
1566         // Step 23.a. Let parameterBindings be parameterNames.
1567         //
1568         // NOTE: Done in each consumer of parameterNames.
1569 
1570         // Steps 24-26. IteratorBindingInitialization
1571         // (done in emitter)
1572 
1573         // Step 27. If hasParameterExpressions is false, then
1574         let extra_body_var_scope_data = if !self.shared.has_parameter_expressions {
1575             debug_assert!(!has_extra_body_var_scope);
1576 
1577             // Step 27.a. NOTE: Only a single lexical environment is needed for
1578             //            the parameters and top-level vars.
1579 
1580             // Step 27.b. Let instantiatedVarNames be a copy of the List
1581             //            parameterBindings.
1582 
1583             // Step 27.c. For each n in varNames, do
1584             for n in &body_scope_builder.shared.var_names {
1585                 // Step 27.c.i. If n is not an element of instantiatedVarNames,
1586                 //              then
1587                 // Step 27.c.i.1. Append n to instantiatedVarNames.
1588                 //
1589                 // NOTE: var_names is already unique.
1590                 //       Check against parameters and `arguments` here.
1591                 if self.shared.parameter_names.contains(n)
1592                     || (arguments_object_needed && *n == CommonSourceAtomSetIndices::arguments())
1593                 {
1594                     continue;
1595                 }
1596 
1597                 // Step 27.c.i.2. Perform
1598                 //                ! envRec.CreateMutableBinding(n, false).
1599                 let is_closed_over = body_scope_builder
1600                     .shared
1601                     .base
1602                     .name_tracker
1603                     .is_closed_over_def(n);
1604                 function_scope_data
1605                     .base
1606                     .bindings
1607                     .push(Some(BindingName::new(*n, is_closed_over)));
1608 
1609                 // Step 27.c.i.3. Call envRec.InitializeBinding(n, undefined).
1610                 // (done in runtime)
1611             }
1612 
1613             // Step 27.d. Let varEnv be env.
1614             // Step 27.e. Let varEnvRec be envRec.
1615             ScopeData::Alias(self.scope_index)
1616         }
1617         // Step 28. Else,
1618         else {
1619             debug_assert!(has_extra_body_var_scope);
1620 
1621             // In non-strict mode code, direct `eval` can extend function's
1622             // scope.
1623             let function_has_extensible_scope = !self.shared.strict && self.has_direct_eval;
1624 
1625             // Step 28.a. NOTE: A separate Environment Record is needed to
1626             //            ensure that closures created by expressions in the
1627             //            formal parameter list do not have visibility of
1628             //            declarations in the function body.
1629 
1630             // Step 28.b. Let varEnv be NewDeclarativeEnvironment(env).
1631             // Step 28.c. Set the VariableEnvironment of calleeContext to
1632             //            varEnv.
1633             let mut data = VarScopeData::new(
1634                 body_scope_builder.shared.var_names.len(),
1635                 function_has_extensible_scope,
1636                 /* encloding= */ self.scope_index,
1637             );
1638 
1639             // Step 28.d. Let instantiatedVarNames be a new empty List.
1640 
1641             // Step 28.e. For each n in varNames, do
1642             for n in &body_scope_builder.shared.var_names {
1643                 // Step 28.e.i. If n is not an element of instantiatedVarNames, then
1644                 // Step 28.e.i.1. Append n to instantiatedVarNames.
1645                 //
1646                 // NOTE: var_names is already unique.
1647 
1648                 // Step 28.e.i.2. Perform
1649                 //                ! varEnv.CreateMutableBinding(n, false).
1650                 let is_closed_over = body_scope_builder
1651                     .shared
1652                     .base
1653                     .name_tracker
1654                     .is_closed_over_def(n);
1655                 data.base
1656                     .bindings
1657                     .push(BindingName::new(*n, is_closed_over));
1658 
1659                 // Step 28.e.i.3. If n is not an element of parameterBindings or if
1660                 //                n is an element of functionNames, let
1661                 //                initialValue be undefined.
1662                 // Step 28.e.i.4. Else,
1663                 // Step 28.e.i.4.a. Let initialValue be
1664                 //                  ! env.GetBindingValue(n, false).
1665                 // Step 28.e.i.5. Call varEnv.InitializeBinding(n, initialValue).
1666                 // (done in emitter)
1667 
1668                 // Step 28.e.i.6. NOTE: A var with the same name as a formal
1669                 //                parameter initially has the same value as the
1670                 //                corresponding initialized parameter.
1671             }
1672 
1673             ScopeData::Var(data)
1674         };
1675 
1676         // Step 30. If strict is false, then
1677         // Step 30.a. Let lexEnv be NewDeclarativeEnvironment(varEnv).
1678         // Step 30.b. NOTE: Non-strict functions use a separate lexical
1679         //            Environment Record for top-level lexical declarations so
1680         //            that a direct eval can determine whether any var scoped
1681         //            declarations introduced by the eval code conflict with
1682         //            pre-existing top-level lexically scoped declarations.
1683         //            This is not needed for strict functions because a strict
1684         //            direct eval always places all declarations into a new
1685         //            Environment Record.
1686         // Step 31. Else, let lexEnv be varEnv.
1687         // Step 32. Let lexEnvRec be lexEnv's EnvironmentRecord.
1688         //
1689         // NOTE: SpiderMonkey creates lexical env whenever lexical binding
1690         //       exists.
1691 
1692         let lexical_scope_data = if body_scope_builder.shared.let_names.len() > 0
1693             || body_scope_builder.shared.const_names.len() > 0
1694         {
1695             let mut data = LexicalScopeData::new_function_lexical(
1696                 body_scope_builder.shared.let_names.len(),
1697                 body_scope_builder.shared.const_names.len(),
1698                 /* encloding= */ body_scope_builder.var_scope_index,
1699             );
1700 
1701             // Step 33. Set the LexicalEnvironment of calleeContext to lexEnv.
1702             // Step 34. Let lexDeclarations be the LexicallyScopedDeclarations
1703             //          of code.
1704             // Step 35. For each element d in lexDeclarations, do
1705             // Step 35.a. NOTE: A lexically declared name cannot be the same as
1706             //            a function/generator declaration, formal parameter,
1707             //            or a var name. Lexically declared names are only
1708             //            instantiated here but not initialized.
1709             // Step 35.b. For each element dn of the BoundNames of d, do
1710 
1711             for n in &body_scope_builder.shared.let_names {
1712                 // Step 35.b.ii. Else,
1713                 // Step 35.b.ii.1. Perform
1714                 //                 ! lexEnvRec.CreateMutableBinding(dn, false).
1715                 let is_closed_over = body_scope_builder
1716                     .shared
1717                     .base
1718                     .name_tracker
1719                     .is_closed_over_def(n);
1720                 data.base
1721                     .bindings
1722                     .push(BindingName::new(*n, is_closed_over))
1723             }
1724             for n in &body_scope_builder.shared.const_names {
1725                 // Step 35.b.i. If IsConstantDeclaration of d is true, then
1726                 // Step 35.b.i.1. Perform
1727                 //                ! lexEnvRec.CreateImmutableBinding(dn, true).
1728                 let is_closed_over = body_scope_builder
1729                     .shared
1730                     .base
1731                     .name_tracker
1732                     .is_closed_over_def(n);
1733                 data.base
1734                     .bindings
1735                     .push(BindingName::new(*n, is_closed_over))
1736             }
1737 
1738             ScopeData::Lexical(data)
1739         } else {
1740             ScopeData::Alias(body_scope_builder.var_scope_index)
1741         };
1742 
1743         // Step 36. For each Parse Node f in functionsToInitialize, do
1744         // (done in emitter)
1745 
1746         FunctionScopeDataSet {
1747             function: ScopeData::Function(function_scope_data),
1748             extra_body_var: extra_body_var_scope_data,
1749             lexical: lexical_scope_data,
1750         }
1751     }
1752 }
1753 
1754 /// Variables declared/used in FunctionBody.
1755 /// Shared part between full-parse and syntax-only parse.
1756 #[derive(Debug)]
1757 struct SharedFunctionBodyScopeBuilder {
1758     base: BaseScopeBuilder,
1759 
1760     /// FunctionDeclarationInstantiation ( func, argumentsList )
1761     /// https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1762     ///
1763     /// Step 9. Let varNames be the VarDeclaredNames of code.
1764     var_names: IndexSet<SourceAtomSetIndex>,
1765 
1766     /// Step 11. Let lexicalNames be the LexicallyDeclaredNames of code.
1767     let_names: Vec<SourceAtomSetIndex>,
1768     const_names: Vec<SourceAtomSetIndex>,
1769 
1770     /// Step 18. Else if hasParameterExpressions is false, then
1771     /// Step 18.a. If "arguments" is an element of functionNames or
1772     ///            if "arguments" is an element of lexicalNames, then
1773     function_or_lexical_has_arguments: bool,
1774 }
1775 
1776 impl SharedFunctionBodyScopeBuilder {
new() -> Self1777     fn new() -> Self {
1778         Self {
1779             base: BaseScopeBuilder::new(),
1780             var_names: IndexSet::new(),
1781             let_names: Vec::new(),
1782             const_names: Vec::new(),
1783             function_or_lexical_has_arguments: false,
1784         }
1785     }
1786 
declare_var(&mut self, name: SourceAtomSetIndex)1787     fn declare_var(&mut self, name: SourceAtomSetIndex) {
1788         // FunctionDeclarationInstantiation ( func, argumentsList )
1789         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1790         //
1791         // Step 9. Let varNames be the VarDeclaredNames of code.
1792         self.var_names.insert(name);
1793         self.base.declare_var(name);
1794     }
1795 
check_lexical_or_function_name(&mut self, name: SourceAtomSetIndex)1796     fn check_lexical_or_function_name(&mut self, name: SourceAtomSetIndex) {
1797         // FunctionDeclarationInstantiation ( func, argumentsList )
1798         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1799         //
1800         // Step 18.a. If "arguments" is an element of functionNames or if
1801         //            "arguments" is an element of lexicalNames, then
1802         if name == CommonSourceAtomSetIndices::arguments() {
1803             self.function_or_lexical_has_arguments = true;
1804         }
1805     }
1806 
declare_let(&mut self, name: SourceAtomSetIndex)1807     fn declare_let(&mut self, name: SourceAtomSetIndex) {
1808         // FunctionDeclarationInstantiation ( func, argumentsList )
1809         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1810         //
1811         // Step 11. Let lexicalNames be the LexicallyDeclaredNames of code.
1812         self.let_names.push(name.clone());
1813         self.check_lexical_or_function_name(name.clone());
1814         self.base.declare_let(name);
1815     }
1816 
declare_const(&mut self, name: SourceAtomSetIndex)1817     fn declare_const(&mut self, name: SourceAtomSetIndex) {
1818         // FunctionDeclarationInstantiation ( func, argumentsList )
1819         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1820         //
1821         // Step 11. Let lexicalNames be the LexicallyDeclaredNames of code.
1822         self.let_names.push(name.clone());
1823         self.check_lexical_or_function_name(name.clone());
1824         self.base.declare_const(name);
1825     }
1826 
declare_function(&mut self, name: SourceAtomSetIndex)1827     fn declare_function(&mut self, name: SourceAtomSetIndex) {
1828         // FunctionDeclarationInstantiation ( func, argumentsList )
1829         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1830         //
1831         // Step 9. Let varNames be the VarDeclaredNames of code.
1832         self.var_names.insert(name.clone());
1833 
1834         // Step 14. For each d in varDeclarations, in reverse list order, do
1835         // Step 14.a. If d is neither a VariableDeclaration nor a ForBinding
1836         //            nor a BindingIdentifier , then
1837         // (implicit)
1838 
1839         // Step 14.a.i. Assert: d is either a FunctionDeclaration, a
1840         //              GeneratorDeclaration, an AsyncFunctionDeclaration,
1841         //              or an AsyncGeneratorDeclaration.
1842 
1843         // Step 14.a.ii. Let fn be the sole element of the BoundNames of d.
1844 
1845         // Step 14.a.iii. If fn is not an element of functionNames, then
1846         //
1847         // NOTE: Instead of iterating in reverse list oder, we iterate in
1848         // normal order and overwrite existing item.
1849 
1850         // Step 14.a.iii.1. Insert fn as the first element of functionNames.
1851         // Step 14.a.iii.2. NOTE: If there are multiple function declarations
1852         //                  for the same name, the last declaration is used.
1853         self.check_lexical_or_function_name(name);
1854 
1855         self.base.declare_function(name)
1856     }
1857 
is_var_closed_over(&self) -> bool1858     fn is_var_closed_over(&self) -> bool {
1859         for name in &self.var_names {
1860             if self.base.name_tracker.is_closed_over_def(name) {
1861                 return true;
1862             }
1863         }
1864 
1865         false
1866     }
1867 }
1868 
1869 /// Variables declared/used in FunctionBody.
1870 /// For full-parse.
1871 #[derive(Debug)]
1872 struct FunctionBodyScopeBuilder {
1873     shared: SharedFunctionBodyScopeBuilder,
1874 
1875     /// FunctionDeclarationInstantiation ( func, argumentsList )
1876     /// https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1877     ///
1878     /// Step 13. Let functionsToInitialize be a new empty List.
1879     functions_to_initialize: Vec<ScriptStencilIndex>,
1880 
1881     var_scope_index: ScopeIndex,
1882     lexical_scope_index: ScopeIndex,
1883 }
1884 
1885 impl FunctionBodyScopeBuilder {
new(var_scope_index: ScopeIndex, lexical_scope_index: ScopeIndex) -> Self1886     fn new(var_scope_index: ScopeIndex, lexical_scope_index: ScopeIndex) -> Self {
1887         Self {
1888             shared: SharedFunctionBodyScopeBuilder::new(),
1889             functions_to_initialize: Vec::new(),
1890             var_scope_index,
1891             lexical_scope_index,
1892         }
1893     }
1894 
declare_var(&mut self, name: SourceAtomSetIndex)1895     fn declare_var(&mut self, name: SourceAtomSetIndex) {
1896         self.shared.declare_var(name);
1897     }
1898 
declare_let(&mut self, name: SourceAtomSetIndex)1899     fn declare_let(&mut self, name: SourceAtomSetIndex) {
1900         self.shared.declare_let(name);
1901     }
1902 
declare_const(&mut self, name: SourceAtomSetIndex)1903     fn declare_const(&mut self, name: SourceAtomSetIndex) {
1904         self.shared.declare_const(name);
1905     }
1906 
declare_function(&mut self, name: SourceAtomSetIndex, fun_index: ScriptStencilIndex)1907     fn declare_function(&mut self, name: SourceAtomSetIndex, fun_index: ScriptStencilIndex) {
1908         self.shared.declare_function(name);
1909 
1910         // FunctionDeclarationInstantiation ( func, argumentsList )
1911         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
1912         //
1913         // Step 14.a.iii.3. Insert d as the first element of
1914         //                  functionsToInitialize.
1915         self.functions_to_initialize.push(fun_index);
1916     }
1917 }
1918 
1919 #[derive(Debug)]
1920 enum ScopeBuilder {
1921     Global(GlobalScopeBuilder),
1922     SyntaxOnlyGlobal(BaseScopeBuilder),
1923 
1924     Block(BlockScopeBuilder),
1925     SyntaxOnlyBlock(BaseScopeBuilder),
1926 
1927     FunctionExpression(FunctionExpressionScopeBuilder),
1928     SyntaxOnlyFunctionExpression(BaseScopeBuilder),
1929 
1930     FunctionParameters(FunctionParametersScopeBuilder),
1931     SyntaxOnlyFunctionParameters(SharedFunctionParametersScopeBuilder),
1932 
1933     FunctionBody(FunctionBodyScopeBuilder),
1934     SyntaxOnlyFunctionBody(SharedFunctionBodyScopeBuilder),
1935 }
1936 
1937 impl ScopeBuilder {
get_scope_index(&self) -> Option<ScopeIndex>1938     fn get_scope_index(&self) -> Option<ScopeIndex> {
1939         match self {
1940             ScopeBuilder::Global(builder) => Some(builder.scope_index),
1941             ScopeBuilder::SyntaxOnlyGlobal(_) => None,
1942             ScopeBuilder::Block(builder) => Some(builder.scope_index),
1943             ScopeBuilder::SyntaxOnlyBlock(_) => None,
1944             ScopeBuilder::FunctionExpression(builder) => Some(builder.scope_index),
1945             ScopeBuilder::SyntaxOnlyFunctionExpression(_) => None,
1946             ScopeBuilder::FunctionParameters(builder) => Some(builder.scope_index),
1947             ScopeBuilder::SyntaxOnlyFunctionParameters(_) => None,
1948             ScopeBuilder::FunctionBody(builder) => Some(builder.lexical_scope_index),
1949             ScopeBuilder::SyntaxOnlyFunctionBody(_) => None,
1950         }
1951     }
1952 
declare_var(&mut self, name: SourceAtomSetIndex)1953     fn declare_var(&mut self, name: SourceAtomSetIndex) {
1954         match self {
1955             ScopeBuilder::Global(ref mut builder) => builder.declare_var(name),
1956             ScopeBuilder::SyntaxOnlyGlobal(ref mut builder) => builder.declare_var(name),
1957             ScopeBuilder::FunctionBody(ref mut builder) => builder.declare_var(name),
1958             ScopeBuilder::SyntaxOnlyFunctionBody(ref mut builder) => builder.declare_var(name),
1959             _ => panic!("unexpected var scope builder"),
1960         }
1961     }
1962 
declare_let(&mut self, name: SourceAtomSetIndex)1963     fn declare_let(&mut self, name: SourceAtomSetIndex) {
1964         match self {
1965             ScopeBuilder::Global(ref mut builder) => builder.declare_let(name),
1966             ScopeBuilder::SyntaxOnlyGlobal(ref mut builder) => builder.declare_let(name),
1967             ScopeBuilder::Block(ref mut builder) => builder.declare_let(name),
1968             ScopeBuilder::SyntaxOnlyBlock(ref mut builder) => builder.declare_let(name),
1969             ScopeBuilder::FunctionBody(ref mut builder) => builder.declare_let(name),
1970             ScopeBuilder::SyntaxOnlyFunctionBody(ref mut builder) => builder.declare_let(name),
1971             _ => panic!("unexpected lexical scope builder"),
1972         }
1973     }
1974 
declare_const(&mut self, name: SourceAtomSetIndex)1975     fn declare_const(&mut self, name: SourceAtomSetIndex) {
1976         match self {
1977             ScopeBuilder::Global(ref mut builder) => builder.declare_const(name),
1978             ScopeBuilder::SyntaxOnlyGlobal(ref mut builder) => builder.declare_const(name),
1979             ScopeBuilder::Block(ref mut builder) => builder.declare_const(name),
1980             ScopeBuilder::SyntaxOnlyBlock(ref mut builder) => builder.declare_const(name),
1981             ScopeBuilder::FunctionBody(ref mut builder) => builder.declare_const(name),
1982             ScopeBuilder::SyntaxOnlyFunctionBody(ref mut builder) => builder.declare_const(name),
1983             _ => panic!("unexpected lexical scope builder"),
1984         }
1985     }
1986 
set_function_name(&mut self, name: SourceAtomSetIndex)1987     fn set_function_name(&mut self, name: SourceAtomSetIndex) {
1988         match self {
1989             ScopeBuilder::FunctionExpression(ref mut builder) => builder.set_function_name(name),
1990             ScopeBuilder::SyntaxOnlyFunctionExpression(ref mut builder) => {
1991                 builder.set_function_name(name)
1992             }
1993             // FunctionDeclaration etc doesn't push any scope builder.
1994             // Just ignore.
1995             _ => {}
1996         }
1997     }
1998 
declare_param(&mut self, name: SourceAtomSetIndex)1999     fn declare_param(&mut self, name: SourceAtomSetIndex) {
2000         match self {
2001             ScopeBuilder::FunctionParameters(ref mut builder) => builder.declare_param(name),
2002             ScopeBuilder::SyntaxOnlyFunctionParameters(ref mut builder) => {
2003                 builder.declare_param(name)
2004             }
2005             _ => panic!("unexpected function scope builder"),
2006         }
2007     }
2008 
base_mut(&mut self) -> &mut BaseScopeBuilder2009     fn base_mut(&mut self) -> &mut BaseScopeBuilder {
2010         match self {
2011             ScopeBuilder::Global(builder) => &mut builder.base,
2012             ScopeBuilder::SyntaxOnlyGlobal(builder) => builder,
2013             ScopeBuilder::Block(builder) => &mut builder.base,
2014             ScopeBuilder::SyntaxOnlyBlock(builder) => builder,
2015             ScopeBuilder::FunctionExpression(builder) => &mut builder.base,
2016             ScopeBuilder::SyntaxOnlyFunctionExpression(builder) => builder,
2017             ScopeBuilder::FunctionParameters(builder) => &mut builder.shared.base,
2018             ScopeBuilder::SyntaxOnlyFunctionParameters(builder) => &mut builder.base,
2019             ScopeBuilder::FunctionBody(builder) => &mut builder.shared.base,
2020             ScopeBuilder::SyntaxOnlyFunctionBody(builder) => &mut builder.base,
2021         }
2022     }
2023 }
2024 
2025 /// Tracks what kind of binding the BindingIdentifier node corresponds to.
2026 #[derive(Debug)]
2027 struct ScopeKindStack {
2028     stack: Vec<ScopeKind>,
2029 }
2030 
2031 impl ScopeKindStack {
new() -> Self2032     fn new() -> Self {
2033         Self { stack: Vec::new() }
2034     }
2035 
innermost<'a>(&'a self) -> &'a ScopeKind2036     fn innermost<'a>(&'a self) -> &'a ScopeKind {
2037         self.stack
2038             .last()
2039             .expect("There should be at least one scope on the stack")
2040     }
2041 
push(&mut self, kind: ScopeKind)2042     fn push(&mut self, kind: ScopeKind) {
2043         self.stack.push(kind)
2044     }
2045 
pop(&mut self, kind: ScopeKind)2046     fn pop(&mut self, kind: ScopeKind) {
2047         match self.stack.pop() {
2048             Some(k) if k == kind => {}
2049             _ => panic!("unmatching scope kind"),
2050         }
2051     }
2052 
is_empty(&self) -> bool2053     fn is_empty(&self) -> bool {
2054         self.stack.len() == 0
2055     }
2056 }
2057 
2058 /// The stack of scope builder for creating binding into.
2059 #[derive(Debug)]
2060 struct ScopeBuilderStack {
2061     stack: Vec<ScopeBuilder>,
2062 
2063     /// Stack of lists of names that is
2064     ///   1. defined in the scope
2065     ///   2. closed over by inner script
2066     ///
2067     /// Each list is delimited by `None`, for each scope.
2068     ///
2069     /// The order of scopes is depth-first post-order, and the order of names
2070     /// inside each scope is in not defined.
2071     ///
2072     /// When entering a function, empty list is pushed to this stack, and
2073     /// when leaving each function, top-most list is popped, and
2074     /// added to gcthings of the function, and this list is reset to empty.
2075     closed_over_bindings_for_lazy: Vec<Vec<Option<SourceAtomSetIndex>>>,
2076 }
2077 
2078 impl ScopeBuilderStack {
new() -> Self2079     fn new() -> Self {
2080         Self {
2081             stack: Vec::new(),
2082             closed_over_bindings_for_lazy: Vec::new(),
2083         }
2084     }
2085 
innermost_var<'a>(&'a mut self) -> &'a mut ScopeBuilder2086     fn innermost_var<'a>(&'a mut self) -> &'a mut ScopeBuilder {
2087         for builder in self.stack.iter_mut().rev() {
2088             match builder {
2089                 ScopeBuilder::Global(_) => return builder,
2090                 ScopeBuilder::SyntaxOnlyGlobal(_) => return builder,
2091                 // NOTE: Function's body-level variable goes to
2092                 // `FunctionBodyScopeBuilder`, regardless of the existence of
2093                 // extra body var scope.
2094                 // See `FunctionParametersScopeBuilder::into_scope_data_set`
2095                 // for how those vars are stored into either function scope or
2096                 // extra body var scope.
2097                 ScopeBuilder::FunctionBody(_) => return builder,
2098                 ScopeBuilder::SyntaxOnlyFunctionBody(_) => return builder,
2099                 _ => {}
2100             }
2101         }
2102 
2103         panic!("There should be at least one scope on the stack");
2104     }
2105 
maybe_innermost_function_parameters<'a>( &'a mut self, ) -> Option<&'a mut FunctionParametersScopeBuilder>2106     fn maybe_innermost_function_parameters<'a>(
2107         &'a mut self,
2108     ) -> Option<&'a mut FunctionParametersScopeBuilder> {
2109         for builder in self.stack.iter_mut().rev() {
2110             match builder {
2111                 ScopeBuilder::FunctionParameters(builder) => return Some(builder),
2112                 _ => {}
2113             }
2114         }
2115 
2116         None
2117     }
2118 
innermost_lexical<'a>(&'a mut self) -> &'a mut ScopeBuilder2119     fn innermost_lexical<'a>(&'a mut self) -> &'a mut ScopeBuilder {
2120         // FIXME: If there's no other case, merge with innermost.
2121         self.innermost()
2122     }
2123 
innermost<'a>(&'a mut self) -> &'a mut ScopeBuilder2124     fn innermost<'a>(&'a mut self) -> &'a mut ScopeBuilder {
2125         self.stack
2126             .last_mut()
2127             .expect("There should be at least one scope on the stack")
2128     }
2129 
maybe_innermost<'a>(&'a mut self) -> Option<&'a mut ScopeBuilder>2130     fn maybe_innermost<'a>(&'a mut self) -> Option<&'a mut ScopeBuilder> {
2131         self.stack.last_mut()
2132     }
2133 
current_scope_index(&self) -> ScopeIndex2134     fn current_scope_index(&self) -> ScopeIndex {
2135         self.maybe_current_scope_index()
2136             .expect("Shouldn't be in syntax-only mode")
2137     }
2138 
maybe_current_scope_index(&self) -> Option<ScopeIndex>2139     fn maybe_current_scope_index(&self) -> Option<ScopeIndex> {
2140         self.stack
2141             .last()
2142             .expect("There should be at least one scope on the stack")
2143             .get_scope_index()
2144     }
2145 
push_global(&mut self, builder: GlobalScopeBuilder)2146     fn push_global(&mut self, builder: GlobalScopeBuilder) {
2147         self.stack.push(ScopeBuilder::Global(builder))
2148     }
push_syntax_only_global(&mut self, builder: BaseScopeBuilder)2149     fn push_syntax_only_global(&mut self, builder: BaseScopeBuilder) {
2150         self.stack.push(ScopeBuilder::SyntaxOnlyGlobal(builder))
2151     }
2152 
pop_global(&mut self) -> GlobalScopeBuilder2153     fn pop_global(&mut self) -> GlobalScopeBuilder {
2154         match self.pop() {
2155             ScopeBuilder::Global(builder) => {
2156                 debug_assert!(self.stack.is_empty());
2157                 builder
2158             }
2159             _ => panic!("unmatching scope builder"),
2160         }
2161     }
pop_syntax_only_global(&mut self)2162     fn pop_syntax_only_global(&mut self) {
2163         match self.pop() {
2164             ScopeBuilder::SyntaxOnlyGlobal(_) => {
2165                 debug_assert!(self.stack.is_empty());
2166             }
2167             _ => panic!("unmatching scope builder"),
2168         }
2169     }
2170 
push_block(&mut self, builder: BlockScopeBuilder)2171     fn push_block(&mut self, builder: BlockScopeBuilder) {
2172         self.stack.push(ScopeBuilder::Block(builder))
2173     }
push_syntax_only_block(&mut self, builder: BaseScopeBuilder)2174     fn push_syntax_only_block(&mut self, builder: BaseScopeBuilder) {
2175         self.stack.push(ScopeBuilder::SyntaxOnlyBlock(builder))
2176     }
2177 
handle_popped_block(&mut self, builder: &BaseScopeBuilder)2178     fn handle_popped_block(&mut self, builder: &BaseScopeBuilder) {
2179         self.innermost()
2180             .base_mut()
2181             .propagate_from_inner_non_script(builder);
2182 
2183         self.update_closed_over_bindings_for_lazy(builder);
2184     }
2185 
pop_block(&mut self) -> BlockScopeBuilder2186     fn pop_block(&mut self) -> BlockScopeBuilder {
2187         match self.pop() {
2188             ScopeBuilder::Block(builder) => {
2189                 self.handle_popped_block(&builder.base);
2190                 builder
2191             }
2192             _ => panic!("unmatching scope builder"),
2193         }
2194     }
pop_syntax_only_block(&mut self)2195     fn pop_syntax_only_block(&mut self) {
2196         match self.pop() {
2197             ScopeBuilder::SyntaxOnlyBlock(builder) => self.handle_popped_block(&builder),
2198             _ => panic!("unmatching scope builder"),
2199         }
2200     }
2201 
push_function_expression(&mut self, builder: FunctionExpressionScopeBuilder)2202     fn push_function_expression(&mut self, builder: FunctionExpressionScopeBuilder) {
2203         self.stack.push(ScopeBuilder::FunctionExpression(builder))
2204     }
push_syntax_only_function_expression(&mut self, builder: BaseScopeBuilder)2205     fn push_syntax_only_function_expression(&mut self, builder: BaseScopeBuilder) {
2206         self.stack
2207             .push(ScopeBuilder::SyntaxOnlyFunctionExpression(builder))
2208     }
2209 
handle_popped_function_expression(&mut self, builder: &BaseScopeBuilder)2210     fn handle_popped_function_expression(&mut self, builder: &BaseScopeBuilder) {
2211         if let Some(outer) = self.maybe_innermost() {
2212             // NOTE: Function expression's name cannot have any
2213             //       used free variables.
2214             //       We can treat it as non-script here, so that
2215             //       any closed-over free variables inside this
2216             //       function is propagated from FunctionParameters
2217             //       to enclosing scope builder.
2218             outer.base_mut().propagate_from_inner_non_script(builder);
2219         }
2220 
2221         self.update_closed_over_bindings_for_lazy(builder);
2222     }
2223 
pop_function_expression(&mut self) -> FunctionExpressionScopeBuilder2224     fn pop_function_expression(&mut self) -> FunctionExpressionScopeBuilder {
2225         match self.pop() {
2226             ScopeBuilder::FunctionExpression(builder) => {
2227                 self.handle_popped_function_expression(&builder.base);
2228                 builder
2229             }
2230             _ => panic!("unmatching scope builder"),
2231         }
2232     }
pop_syntax_only_function_expression(&mut self)2233     fn pop_syntax_only_function_expression(&mut self) {
2234         match self.pop() {
2235             ScopeBuilder::SyntaxOnlyFunctionExpression(builder) => {
2236                 self.handle_popped_function_expression(&builder);
2237             }
2238             _ => panic!("unmatching scope builder"),
2239         }
2240     }
2241 
push_function_parameters(&mut self, builder: FunctionParametersScopeBuilder)2242     fn push_function_parameters(&mut self, builder: FunctionParametersScopeBuilder) {
2243         self.stack.push(ScopeBuilder::FunctionParameters(builder))
2244     }
push_syntax_only_function_parameters( &mut self, builder: SharedFunctionParametersScopeBuilder, )2245     fn push_syntax_only_function_parameters(
2246         &mut self,
2247         builder: SharedFunctionParametersScopeBuilder,
2248     ) {
2249         self.stack
2250             .push(ScopeBuilder::SyntaxOnlyFunctionParameters(builder))
2251     }
2252 
handle_popped_function_parameters_and_body( &mut self, function_declaration_properties: &mut FunctionDeclarationPropertyMap, possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList, parameter_scope_builder: &mut SharedFunctionParametersScopeBuilder, body_scope_builder: &mut SharedFunctionBodyScopeBuilder, )2253     fn handle_popped_function_parameters_and_body(
2254         &mut self,
2255         function_declaration_properties: &mut FunctionDeclarationPropertyMap,
2256         possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList,
2257         parameter_scope_builder: &mut SharedFunctionParametersScopeBuilder,
2258         body_scope_builder: &mut SharedFunctionBodyScopeBuilder,
2259     ) {
2260         // FunctionDeclarationInstantiation ( func, argumentsList )
2261         // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
2262         //
2263         // Step 29. NOTE: Annex B adds additional steps at this point.
2264         //
2265         // NOTE: Reordered here in order to reflect Annex B functions
2266         //       to FreeNameTracker.
2267         parameter_scope_builder.perform_annex_b(
2268             function_declaration_properties,
2269             possibly_annex_b_functions,
2270             body_scope_builder,
2271         );
2272 
2273         parameter_scope_builder
2274             .base
2275             .propagate_from_inner_non_script(&body_scope_builder.base);
2276         if let Some(outer) = self.maybe_innermost() {
2277             outer
2278                 .base_mut()
2279                 .propagate_from_inner_script(&parameter_scope_builder.base);
2280         }
2281 
2282         let has_extra_body_var_scope = parameter_scope_builder.has_parameter_expressions;
2283         if has_extra_body_var_scope {
2284             self.update_closed_over_bindings_for_lazy(&body_scope_builder.base);
2285             self.update_closed_over_bindings_for_lazy(&parameter_scope_builder.base);
2286         } else {
2287             self.update_closed_over_bindings_for_lazy_with_parameters_and_body(
2288                 &parameter_scope_builder.base,
2289                 &body_scope_builder.base,
2290             );
2291         }
2292     }
2293 
pop_function_parameters_and_body( &mut self, function_declaration_properties: &mut FunctionDeclarationPropertyMap, possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList, ) -> (FunctionParametersScopeBuilder, FunctionBodyScopeBuilder)2294     fn pop_function_parameters_and_body(
2295         &mut self,
2296         function_declaration_properties: &mut FunctionDeclarationPropertyMap,
2297         possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList,
2298     ) -> (FunctionParametersScopeBuilder, FunctionBodyScopeBuilder) {
2299         let mut body_scope_builder = match self.pop() {
2300             ScopeBuilder::FunctionBody(builder) => builder,
2301             _ => panic!("unmatching scope builder"),
2302         };
2303 
2304         let mut parameter_scope_builder = match self.pop() {
2305             ScopeBuilder::FunctionParameters(builder) => builder,
2306             _ => panic!("unmatching scope builder"),
2307         };
2308 
2309         self.handle_popped_function_parameters_and_body(
2310             function_declaration_properties,
2311             possibly_annex_b_functions,
2312             &mut parameter_scope_builder.shared,
2313             &mut body_scope_builder.shared,
2314         );
2315 
2316         (parameter_scope_builder, body_scope_builder)
2317     }
pop_syntax_only_function_parameters_and_body( &mut self, function_declaration_properties: &mut FunctionDeclarationPropertyMap, possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList, ) -> ( SharedFunctionParametersScopeBuilder, SharedFunctionBodyScopeBuilder, )2318     fn pop_syntax_only_function_parameters_and_body(
2319         &mut self,
2320         function_declaration_properties: &mut FunctionDeclarationPropertyMap,
2321         possibly_annex_b_functions: &mut PossiblyAnnexBFunctionList,
2322     ) -> (
2323         SharedFunctionParametersScopeBuilder,
2324         SharedFunctionBodyScopeBuilder,
2325     ) {
2326         let mut body_scope_builder = match self.pop() {
2327             ScopeBuilder::SyntaxOnlyFunctionBody(builder) => builder,
2328             _ => panic!("unmatching scope builder"),
2329         };
2330 
2331         let mut parameter_scope_builder = match self.pop() {
2332             ScopeBuilder::SyntaxOnlyFunctionParameters(builder) => builder,
2333             _ => panic!("unmatching scope builder"),
2334         };
2335 
2336         self.handle_popped_function_parameters_and_body(
2337             function_declaration_properties,
2338             possibly_annex_b_functions,
2339             &mut parameter_scope_builder,
2340             &mut body_scope_builder,
2341         );
2342 
2343         (parameter_scope_builder, body_scope_builder)
2344     }
2345 
get_function_parameters<'a>(&'a mut self) -> &'a mut FunctionParametersScopeBuilder2346     fn get_function_parameters<'a>(&'a mut self) -> &'a mut FunctionParametersScopeBuilder {
2347         match self.innermost() {
2348             ScopeBuilder::FunctionParameters(builder) => builder,
2349             _ => panic!("unmatching scope builder"),
2350         }
2351     }
2352 
get_syntax_only_function_parameters<'a>( &'a mut self, ) -> &'a mut SharedFunctionParametersScopeBuilder2353     fn get_syntax_only_function_parameters<'a>(
2354         &'a mut self,
2355     ) -> &'a mut SharedFunctionParametersScopeBuilder {
2356         match self.innermost() {
2357             ScopeBuilder::SyntaxOnlyFunctionParameters(builder) => builder,
2358             _ => panic!("unmatching scope builder"),
2359         }
2360     }
2361 
push_function_body(&mut self, builder: FunctionBodyScopeBuilder)2362     fn push_function_body(&mut self, builder: FunctionBodyScopeBuilder) {
2363         self.stack.push(ScopeBuilder::FunctionBody(builder))
2364     }
push_syntax_only_function_body(&mut self, builder: SharedFunctionBodyScopeBuilder)2365     fn push_syntax_only_function_body(&mut self, builder: SharedFunctionBodyScopeBuilder) {
2366         self.stack
2367             .push(ScopeBuilder::SyntaxOnlyFunctionBody(builder))
2368     }
2369 
update_closed_over_bindings_for_lazy(&mut self, builder: &BaseScopeBuilder)2370     fn update_closed_over_bindings_for_lazy(&mut self, builder: &BaseScopeBuilder) {
2371         match self.closed_over_bindings_for_lazy.last_mut() {
2372             Some(bindings) => {
2373                 for name in builder.name_tracker.defined_and_closed_over_vars() {
2374                     bindings.push(Some(*name));
2375                 }
2376                 bindings.push(None);
2377             }
2378             None => {
2379                 // We're leaving lexical scope in top-level script.
2380             }
2381         }
2382     }
2383 
2384     // Just like update_closed_over_bindings_for_lazy, but merge
2385     // 2 builders for parameters and body, in case the function doesn't have
2386     // extra body scope.
update_closed_over_bindings_for_lazy_with_parameters_and_body( &mut self, builder1: &BaseScopeBuilder, builder2: &BaseScopeBuilder, )2387     fn update_closed_over_bindings_for_lazy_with_parameters_and_body(
2388         &mut self,
2389         builder1: &BaseScopeBuilder,
2390         builder2: &BaseScopeBuilder,
2391     ) {
2392         match self.closed_over_bindings_for_lazy.last_mut() {
2393             Some(bindings) => {
2394                 for name in builder1.name_tracker.defined_and_closed_over_vars() {
2395                     bindings.push(Some(*name));
2396                 }
2397                 for name in builder2.name_tracker.defined_and_closed_over_vars() {
2398                     bindings.push(Some(*name));
2399                 }
2400                 bindings.push(None);
2401             }
2402             None => {
2403                 // We're leaving lexical scope in top-level script.
2404             }
2405         }
2406     }
2407 
2408     /// Pop the current scope.
pop(&mut self) -> ScopeBuilder2409     fn pop(&mut self) -> ScopeBuilder {
2410         self.stack.pop().expect("unmatching scope builder")
2411     }
2412 
depth(&self) -> usize2413     fn depth(&self) -> usize {
2414         self.stack.len()
2415     }
2416 }
2417 
2418 /// Builds `ScriptStencil` for all functions (both non-lazy and lazy).
2419 /// The script is set to lazy function, with inner functions and
2420 /// closed over bindings populated in gcthings list.
2421 ///
2422 /// TODO: For non-lazy function, gcthings list should be populated in the
2423 ///       emitter pass, not here.
2424 #[derive(Debug)]
2425 pub struct FunctionScriptStencilBuilder {
2426     /// The map from function node to ScriptStencil.
2427     ///
2428     /// The map is separated into `function_stencil_indicies` and `functions`,
2429     /// because it can be referred to in different ways from multiple places:
2430     ///   * map from Function AST node (`function_stencil_indices`)
2431     ///   * enclosing script/function, to list inner functions
2432     function_stencil_indices: AssociatedData<ScriptStencilIndex>,
2433     scripts: ScriptStencilList,
2434 
2435     /// The stack of functions that the current context is in.
2436     ///
2437     /// The last element in this stack represents the current function, where
2438     /// the inner function will be stored
2439     function_stack: Vec<ScriptStencilIndex>,
2440 }
2441 
2442 impl FunctionScriptStencilBuilder {
new() -> Self2443     fn new() -> Self {
2444         let scripts = ScriptStencilList::new_with_empty_top_level();
2445 
2446         Self {
2447             function_stencil_indices: AssociatedData::new(),
2448             scripts,
2449             function_stack: Vec::new(),
2450         }
2451     }
2452 
2453     /// Enter a function.
2454     ///
2455     /// This creates `ScriptStencil` for the function, and adds it to
2456     /// enclosing function if exists.
enter<T>( &mut self, fun: &T, syntax_kind: FunctionSyntaxKind, enclosing_scope_index: Option<ScopeIndex>, ) -> ScriptStencilIndex where T: SourceLocationAccessor + NodeTypeIdAccessor,2457     fn enter<T>(
2458         &mut self,
2459         fun: &T,
2460         syntax_kind: FunctionSyntaxKind,
2461         enclosing_scope_index: Option<ScopeIndex>,
2462     ) -> ScriptStencilIndex
2463     where
2464         T: SourceLocationAccessor + NodeTypeIdAccessor,
2465     {
2466         let loc = fun.get_loc();
2467         let source_start = loc.start as u32;
2468 
2469         // FIXME: Map from offset to line/column.
2470         let lineno = 1;
2471         let column = 0;
2472 
2473         let function_stencil = ScriptStencil::lazy_function(
2474             SourceExtent {
2475                 source_start,
2476                 source_end: 0,
2477                 to_string_start: source_start,
2478                 to_string_end: 0,
2479                 lineno,
2480                 column,
2481             },
2482             None,
2483             syntax_kind.is_generator(),
2484             syntax_kind.is_async(),
2485             FunctionFlags::interpreted(syntax_kind),
2486             enclosing_scope_index,
2487         );
2488         let index = self.scripts.push(function_stencil);
2489         self.function_stencil_indices.insert(fun, index);
2490 
2491         match self.maybe_current_mut() {
2492             Some(enclosing) => {
2493                 enclosing.push_inner_function(index);
2494             }
2495             None => {}
2496         }
2497 
2498         self.function_stack.push(index);
2499 
2500         index
2501     }
2502 
2503     /// Leave a function, setting its source location.
leave<T>(&mut self, fun: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,2504     fn leave<T>(&mut self, fun: &T)
2505     where
2506         T: SourceLocationAccessor + NodeTypeIdAccessor,
2507     {
2508         let loc = fun.get_loc();
2509         let source_end = loc.end;
2510 
2511         self.current_mut().set_source_end(source_end);
2512         self.current_mut().set_to_string_end(source_end);
2513 
2514         self.function_stack.pop();
2515     }
2516 
2517     /// Returns the current function's index.
2518     /// Panics if no current function is found.
current_index(&self) -> ScriptStencilIndex2519     fn current_index(&self) -> ScriptStencilIndex {
2520         *self
2521             .function_stack
2522             .last()
2523             .expect("should be inside function")
2524     }
2525 
2526     /// Returns a immutable reference to the innermost function. None otherwise.
maybe_current<'a>(&'a self) -> Option<&'a ScriptStencil>2527     fn maybe_current<'a>(&'a self) -> Option<&'a ScriptStencil> {
2528         let maybe_index = self.function_stack.last();
2529         maybe_index.map(move |index| self.scripts.get(*index))
2530     }
2531 
2532     /// Returns a immutable reference to the current function.
2533     /// Panics if no current function is found.
current<'a>(&'a self) -> &'a ScriptStencil2534     fn current<'a>(&'a self) -> &'a ScriptStencil {
2535         self.maybe_current().expect("should be inside function")
2536     }
2537 
2538     /// Returns a mutable reference to the innermost function. None otherwise.
maybe_current_mut<'a>(&'a mut self) -> Option<&'a mut ScriptStencil>2539     fn maybe_current_mut<'a>(&'a mut self) -> Option<&'a mut ScriptStencil> {
2540         let maybe_index = self.function_stack.last().cloned();
2541         maybe_index.map(move |index| self.scripts.get_mut(index))
2542     }
2543 
2544     /// Returns a mutable reference to the current function.
2545     /// Panics if no current function is found.
current_mut<'a>(&'a mut self) -> &'a mut ScriptStencil2546     fn current_mut<'a>(&'a mut self) -> &'a mut ScriptStencil {
2547         self.maybe_current_mut().expect("should be inside function")
2548     }
2549 
2550     /// Sets the name of the current function.
set_function_name(&mut self, name: SourceAtomSetIndex)2551     fn set_function_name(&mut self, name: SourceAtomSetIndex) {
2552         self.current_mut().set_fun_name(name);
2553     }
2554 
2555     /// Sets the position of the function parameters.
2556     /// `params` should point to the `(` of the function parameters.
2557     /// If it's an arrow function without parenthesis, `params` should point
2558     /// the parameter binding.
on_function_parameters<T>(&mut self, params: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,2559     fn on_function_parameters<T>(&mut self, params: &T)
2560     where
2561         T: SourceLocationAccessor + NodeTypeIdAccessor,
2562     {
2563         let loc = params.get_loc();
2564         let params_start = loc.start;
2565         self.current_mut().set_source_starts(params_start);
2566     }
2567 
on_non_rest_parameter(&mut self)2568     fn on_non_rest_parameter(&mut self) {
2569         let fun = self.current_mut();
2570         fun.add_fun_nargs();
2571     }
2572 
2573     /// Flags that the current function has rest parameter.
on_rest_parameter(&mut self)2574     fn on_rest_parameter(&mut self) {
2575         let fun = self.current_mut();
2576         fun.add_fun_nargs();
2577         fun.set_has_rest();
2578     }
2579 
add_closed_over_bindings( &mut self, mut closed_over_bindings_for_lazy: Vec<Option<SourceAtomSetIndex>>, )2580     fn add_closed_over_bindings(
2581         &mut self,
2582         mut closed_over_bindings_for_lazy: Vec<Option<SourceAtomSetIndex>>,
2583     ) {
2584         // Remove trailing `None`s.
2585         loop {
2586             match closed_over_bindings_for_lazy.last() {
2587                 Some(Some(_)) => {
2588                     // The last item isn't None.
2589                     break;
2590                 }
2591 
2592                 Some(None) => {
2593                     // The last item is None, remove it
2594                     closed_over_bindings_for_lazy.pop();
2595                 }
2596 
2597                 None => {
2598                     // List is empty.
2599                     break;
2600                 }
2601             }
2602         }
2603 
2604         let current = self.current_mut();
2605         for name in closed_over_bindings_for_lazy {
2606             match name {
2607                 Some(name) => current.push_closed_over_bindings(name),
2608                 None => current.push_closed_over_bindings_delimiter(),
2609             }
2610         }
2611     }
2612 }
2613 
2614 /// Scope builder shouldn't raise any error except not-implemented.
2615 /// This struct should eventually be removed.
2616 #[derive(Clone, Debug)]
2617 pub enum ScopeBuildError {
2618     NotImplemented(&'static str),
2619 }
2620 
2621 /// Receives method calls telling about a JS script and builds a
2622 /// `ScopeDataMap`.
2623 ///
2624 /// Usage: This struct's public methods must be called for each scope,
2625 /// declaration, and identifier in a JS script, in source order. Then use
2626 /// `ScopeDataMap::from()` to extract the results. Currently this object is
2627 /// driven by method calls from a `pass::ScopePass`.
2628 #[derive(Debug)]
2629 pub struct ScopeDataMapBuilder {
2630     scope_kind_stack: ScopeKindStack,
2631     builder_stack: ScopeBuilderStack,
2632     scopes: ScopeDataList,
2633 
2634     /// The global scope information.
2635     /// Using `Option` to make this field populated later.
2636     global: Option<ScopeIndex>,
2637 
2638     /// The map from non-global AST node to scope information.
2639     non_global: AssociatedData<ScopeIndex>,
2640 
2641     function_stencil_builder: FunctionScriptStencilBuilder,
2642 
2643     function_declaration_properties: FunctionDeclarationPropertyMap,
2644 
2645     possibly_annex_b_functions: PossiblyAnnexBFunctionList,
2646 
2647     error: Option<ScopeBuildError>,
2648 
2649     // The depth of `builder_stack` where syntax-only mode started.
2650     // The pointed `builder_stack` item should be enclosing scope of
2651     // function.
2652     //
2653     // None if not in syntax-only mode.
2654     syntax_only_depth: Option<usize>,
2655 }
2656 
2657 impl ScopeDataMapBuilder {
new() -> Self2658     pub fn new() -> Self {
2659         Self {
2660             scope_kind_stack: ScopeKindStack::new(),
2661             builder_stack: ScopeBuilderStack::new(),
2662             scopes: ScopeDataList::new(),
2663             global: None,
2664             non_global: AssociatedData::new(),
2665             function_stencil_builder: FunctionScriptStencilBuilder::new(),
2666             function_declaration_properties: FunctionDeclarationPropertyMap::new(),
2667             possibly_annex_b_functions: PossiblyAnnexBFunctionList::new(),
2668             error: None,
2669             syntax_only_depth: None,
2670         }
2671     }
2672 
set_error(&mut self, e: ScopeBuildError)2673     fn set_error(&mut self, e: ScopeBuildError) {
2674         if self.error.is_none() {
2675             self.error = Some(e);
2676         }
2677     }
2678 
enter_syntax_only_mode(&mut self)2679     pub fn enter_syntax_only_mode(&mut self) {
2680         assert!(self.syntax_only_depth.is_none());
2681         self.syntax_only_depth = Some(self.builder_stack.depth());
2682     }
2683 
maybe_exit_syntax_only_mode(&mut self)2684     fn maybe_exit_syntax_only_mode(&mut self) {
2685         if self.syntax_only_depth.is_none() {
2686             return;
2687         }
2688 
2689         let depth = self.syntax_only_depth.unwrap();
2690         if self.builder_stack.depth() == depth {
2691             self.syntax_only_depth = None;
2692             return;
2693         }
2694 
2695         debug_assert!(self.builder_stack.depth() > depth);
2696     }
2697 
is_syntax_only_mode(&self) -> bool2698     pub fn is_syntax_only_mode(&self) -> bool {
2699         self.syntax_only_depth.is_some()
2700     }
2701 
before_script(&mut self)2702     pub fn before_script(&mut self) {
2703         if self.is_syntax_only_mode() {
2704             let builder = BaseScopeBuilder::new();
2705             self.builder_stack.push_syntax_only_global(builder);
2706             return;
2707         }
2708 
2709         // SetRealmGlobalObject ( realmRec, globalObj, thisValue )
2710         // https://tc39.es/ecma262/#sec-setrealmglobalobject
2711         //
2712         // Steps 1-4, 7.
2713         // (done in runtime)
2714 
2715         // Step 5. Let newGlobalEnv be
2716         //         NewGlobalEnvironment(globalObj, thisValue).
2717         let index = self.scopes.allocate();
2718         let builder = GlobalScopeBuilder::new(index);
2719         self.global = Some(index);
2720 
2721         // Step 6. Set realmRec.[[GlobalEnv]] to newGlobalEnv.
2722         // (implicit)
2723 
2724         // ScriptEvaluation ( scriptRecord )
2725         // https://tc39.es/ecma262/#sec-runtime-semantics-scriptevaluation
2726         //
2727         // Step 1. Let globalEnv be scriptRecord.[[Realm]].[[GlobalEnv]].
2728         // (implicit)
2729 
2730         // Step 2. Let scriptContext be a new ECMAScript code execution context.
2731         // (implicit)
2732 
2733         // Steps 3-5.
2734         // (done in runtime)
2735 
2736         // Step 6. Set the VariableEnvironment of scriptContext to globalEnv.
2737         // Step 7. Set the LexicalEnvironment of scriptContext to globalEnv.
2738         self.builder_stack.push_global(builder);
2739 
2740         // Steps 8-17.
2741         // (done in runtime)
2742     }
2743 
after_script(&mut self)2744     pub fn after_script(&mut self) {
2745         if self.is_syntax_only_mode() {
2746             self.builder_stack.pop_syntax_only_global();
2747             self.maybe_exit_syntax_only_mode();
2748             return;
2749         }
2750 
2751         let builder = self.builder_stack.pop_global();
2752 
2753         // Runtime Semantics: GlobalDeclarationInstantiation ( script, env )
2754         // https://tc39.es/ecma262/#sec-globaldeclarationinstantiation
2755         //
2756         // Steps 3-6.
2757         // (done in runtime)
2758 
2759         // Steps 12-18.
2760         let scope_index = builder.scope_index;
2761         let scope = builder.into_scope_data(
2762             &mut self.function_declaration_properties,
2763             &mut self.possibly_annex_b_functions,
2764         );
2765         self.scopes.populate(scope_index, scope);
2766     }
2767 
before_block_statement<T>(&mut self, block: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,2768     pub fn before_block_statement<T>(&mut self, block: &T)
2769     where
2770         T: SourceLocationAccessor + NodeTypeIdAccessor,
2771     {
2772         if self.is_syntax_only_mode() {
2773             let builder = BaseScopeBuilder::new();
2774             self.builder_stack.push_syntax_only_block(builder);
2775             return;
2776         }
2777 
2778         // Runtime Semantics: Evaluation
2779         // https://tc39.es/ecma262/#sec-block-runtime-semantics-evaluation
2780         //
2781         // Block : { StatementList }
2782         //
2783         // Step 1. Let oldEnv be the running execution context's
2784         //         LexicalEnvironment.
2785         // (implicit)
2786 
2787         // Step 2. Let blockEnv be NewDeclarativeEnvironment(oldEnv).
2788         let index = self.scopes.allocate();
2789         let builder = BlockScopeBuilder::new(index);
2790         self.non_global.insert(block, index);
2791 
2792         // Step 3. Perform
2793         //         BlockDeclarationInstantiation(StatementList, blockEnv).
2794         // (done in leave_enum_statement_variant_block_statement)
2795 
2796         // Step 4. Set the running execution context's LexicalEnvironment to
2797         //         blockEnv.
2798         self.builder_stack.push_block(builder);
2799 
2800         // Step 5. Let blockValue be the result of evaluating StatementList.
2801         // (done in runtime)
2802     }
2803 
after_block_statement(&mut self)2804     pub fn after_block_statement(&mut self) {
2805         if self.is_syntax_only_mode() {
2806             self.builder_stack.pop_syntax_only_block();
2807             return;
2808         }
2809 
2810         let builder = self.builder_stack.pop_block();
2811         let enclosing = self.builder_stack.current_scope_index();
2812 
2813         // Runtime Semantics: Evaluation
2814         // https://tc39.es/ecma262/#sec-block-runtime-semantics-evaluation
2815         //
2816         // Block : { StatementList }
2817         //
2818         // Step 3. Perform
2819         //         BlockDeclarationInstantiation(StatementList, blockEnv).
2820         self.scopes.populate(
2821             builder.scope_index,
2822             builder.into_scope_data(enclosing, &mut self.possibly_annex_b_functions),
2823         );
2824 
2825         // Step 6. Set the running execution context's LexicalEnvironment to
2826         //         oldEnv.
2827 
2828         // Step 7. Return blockValue.
2829         // (implicit)
2830     }
2831 
before_var_declaration(&mut self)2832     pub fn before_var_declaration(&mut self) {
2833         self.scope_kind_stack.push(ScopeKind::Var);
2834     }
2835 
after_var_declaration(&mut self)2836     pub fn after_var_declaration(&mut self) {
2837         self.scope_kind_stack.pop(ScopeKind::Var);
2838     }
2839 
before_let_declaration(&mut self)2840     pub fn before_let_declaration(&mut self) {
2841         self.scope_kind_stack.push(ScopeKind::Let);
2842     }
2843 
after_let_declaration(&mut self)2844     pub fn after_let_declaration(&mut self) {
2845         self.scope_kind_stack.pop(ScopeKind::Let);
2846     }
2847 
before_const_declaration(&mut self)2848     pub fn before_const_declaration(&mut self) {
2849         self.scope_kind_stack.push(ScopeKind::Const);
2850     }
2851 
after_const_declaration(&mut self)2852     pub fn after_const_declaration(&mut self) {
2853         self.scope_kind_stack.pop(ScopeKind::Const);
2854     }
2855 
on_binding_identifier(&mut self, name: SourceAtomSetIndex)2856     pub fn on_binding_identifier(&mut self, name: SourceAtomSetIndex) {
2857         if self.scope_kind_stack.is_empty() {
2858             // FIXME
2859             // Do nothing for unsupported case.
2860             self.set_error(ScopeBuildError::NotImplemented(
2861                 "Unsupported binding identifier",
2862             ));
2863             return;
2864         }
2865 
2866         match self.scope_kind_stack.innermost() {
2867             ScopeKind::Var => self.builder_stack.innermost_var().declare_var(name),
2868             ScopeKind::Let => self.builder_stack.innermost_lexical().declare_let(name),
2869             ScopeKind::Const => self.builder_stack.innermost_lexical().declare_const(name),
2870             ScopeKind::FunctionName => {
2871                 self.builder_stack.innermost().set_function_name(name);
2872                 self.function_stencil_builder.set_function_name(name);
2873             }
2874             ScopeKind::FunctionParametersAndBody => {
2875                 // FIXME
2876                 // Do nothing for unsupported case.
2877                 self.set_error(ScopeBuildError::NotImplemented(
2878                     "Unsupported binding identifier",
2879                 ));
2880                 return;
2881             }
2882             ScopeKind::FormalParameter => self.builder_stack.innermost().declare_param(name),
2883             _ => panic!("Not implemeneted"),
2884         }
2885     }
2886 
on_non_binding_identifier(&mut self, name: SourceAtomSetIndex)2887     pub fn on_non_binding_identifier(&mut self, name: SourceAtomSetIndex) {
2888         self.builder_stack
2889             .innermost()
2890             .base_mut()
2891             .name_tracker
2892             .note_use(name);
2893     }
2894 
before_function_declaration<T>( &mut self, name: SourceAtomSetIndex, fun: &T, is_generator: bool, is_async: bool, ) -> ScriptStencilIndex where T: SourceLocationAccessor + NodeTypeIdAccessor,2895     pub fn before_function_declaration<T>(
2896         &mut self,
2897         name: SourceAtomSetIndex,
2898         fun: &T,
2899         is_generator: bool,
2900         is_async: bool,
2901     ) -> ScriptStencilIndex
2902     where
2903         T: SourceLocationAccessor + NodeTypeIdAccessor,
2904     {
2905         if is_generator || is_async {
2906             // FIXME: Generator and async should mark all bindings closed over.
2907             self.set_error(ScopeBuildError::NotImplemented(
2908                 "Generator or async function",
2909             ));
2910         }
2911 
2912         let fun_index = self.function_stencil_builder.enter(
2913             fun,
2914             FunctionSyntaxKind::function_declaration(is_generator, is_async),
2915             self.builder_stack.maybe_current_scope_index(),
2916         );
2917 
2918         match self.builder_stack.innermost_lexical() {
2919             ScopeBuilder::Global(ref mut builder) => builder.declare_function(name, fun_index),
2920             ScopeBuilder::SyntaxOnlyGlobal(ref mut builder) => builder.declare_function(name),
2921             ScopeBuilder::Block(ref mut builder) => builder.declare_function(name, fun_index),
2922             ScopeBuilder::SyntaxOnlyBlock(ref mut builder) => builder.declare_function(name),
2923             ScopeBuilder::FunctionBody(ref mut builder) => {
2924                 builder.declare_function(name, fun_index)
2925             }
2926             ScopeBuilder::SyntaxOnlyFunctionBody(ref mut builder) => builder.declare_function(name),
2927             _ => panic!("unexpected lexical for FunctionDeclaration"),
2928         }
2929 
2930         self.scope_kind_stack.push(ScopeKind::FunctionName);
2931 
2932         fun_index
2933     }
2934 
after_function_declaration<T>(&mut self, fun: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,2935     pub fn after_function_declaration<T>(&mut self, fun: &T)
2936     where
2937         T: SourceLocationAccessor + NodeTypeIdAccessor,
2938     {
2939         self.function_stencil_builder.leave(fun);
2940 
2941         self.scope_kind_stack.pop(ScopeKind::FunctionName);
2942     }
2943 
before_function_expression<T>(&mut self, fun: &T, is_generator: bool, is_async: bool) where T: SourceLocationAccessor + NodeTypeIdAccessor,2944     pub fn before_function_expression<T>(&mut self, fun: &T, is_generator: bool, is_async: bool)
2945     where
2946         T: SourceLocationAccessor + NodeTypeIdAccessor,
2947     {
2948         // FIXME: Anonymous function expression needs inferred name.
2949         self.set_error(ScopeBuildError::NotImplemented(
2950             "Function expression (name analysis)",
2951         ));
2952 
2953         self.scope_kind_stack.push(ScopeKind::FunctionName);
2954 
2955         self.function_stencil_builder.enter(
2956             fun,
2957             FunctionSyntaxKind::function_expression(is_generator, is_async),
2958             self.builder_stack.maybe_current_scope_index(),
2959         );
2960 
2961         if self.is_syntax_only_mode() {
2962             let builder = BaseScopeBuilder::new();
2963             self.builder_stack
2964                 .push_syntax_only_function_expression(builder);
2965             return;
2966         }
2967 
2968         let index = self.scopes.allocate();
2969         let builder = FunctionExpressionScopeBuilder::new(index);
2970         self.non_global.insert(fun, index);
2971 
2972         self.builder_stack.push_function_expression(builder);
2973     }
2974 
after_function_expression<T>(&mut self, fun: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,2975     pub fn after_function_expression<T>(&mut self, fun: &T)
2976     where
2977         T: SourceLocationAccessor + NodeTypeIdAccessor,
2978     {
2979         self.function_stencil_builder.leave(fun);
2980 
2981         self.scope_kind_stack.pop(ScopeKind::FunctionName);
2982 
2983         if self.is_syntax_only_mode() {
2984             self.builder_stack.pop_syntax_only_function_expression();
2985             self.maybe_exit_syntax_only_mode();
2986             return;
2987         }
2988 
2989         let builder = self.builder_stack.pop_function_expression();
2990         let enclosing = self.builder_stack.current_scope_index();
2991 
2992         self.scopes
2993             .populate(builder.scope_index, builder.into_scope_data(enclosing));
2994     }
2995 
before_method<T>(&mut self, fun: &T, is_generator: bool, is_async: bool) where T: SourceLocationAccessor + NodeTypeIdAccessor,2996     pub fn before_method<T>(&mut self, fun: &T, is_generator: bool, is_async: bool)
2997     where
2998         T: SourceLocationAccessor + NodeTypeIdAccessor,
2999     {
3000         // FIXME: Support PropertyName as function name.
3001         self.set_error(ScopeBuildError::NotImplemented("Method (name calculation)"));
3002 
3003         self.function_stencil_builder.enter(
3004             fun,
3005             FunctionSyntaxKind::method(is_generator, is_async),
3006             self.builder_stack.maybe_current_scope_index(),
3007         );
3008     }
3009 
after_method<T>(&mut self, fun: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3010     pub fn after_method<T>(&mut self, fun: &T)
3011     where
3012         T: SourceLocationAccessor + NodeTypeIdAccessor,
3013     {
3014         self.function_stencil_builder.leave(fun);
3015     }
3016 
before_getter<T>(&mut self, fun: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3017     pub fn before_getter<T>(&mut self, fun: &T)
3018     where
3019         T: SourceLocationAccessor + NodeTypeIdAccessor,
3020     {
3021         // FIXME: Support PropertyName as function name.
3022         self.set_error(ScopeBuildError::NotImplemented("Getter (name calculation)"));
3023 
3024         self.function_stencil_builder.enter(
3025             fun,
3026             FunctionSyntaxKind::getter(),
3027             self.builder_stack.maybe_current_scope_index(),
3028         );
3029     }
3030 
on_getter_parameter<T>(&mut self, param: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3031     pub fn on_getter_parameter<T>(&mut self, param: &T)
3032     where
3033         T: SourceLocationAccessor + NodeTypeIdAccessor,
3034     {
3035         self.before_function_parameters(param);
3036         self.after_function_parameters();
3037     }
3038 
after_getter<T>(&mut self, fun: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3039     pub fn after_getter<T>(&mut self, fun: &T)
3040     where
3041         T: SourceLocationAccessor + NodeTypeIdAccessor,
3042     {
3043         self.function_stencil_builder.leave(fun);
3044     }
3045 
before_setter<T>(&mut self, fun: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3046     pub fn before_setter<T>(&mut self, fun: &T)
3047     where
3048         T: SourceLocationAccessor + NodeTypeIdAccessor,
3049     {
3050         // FIXME: Support PropertyName as function name.
3051         self.set_error(ScopeBuildError::NotImplemented("Setter (name calculation)"));
3052 
3053         self.function_stencil_builder.enter(
3054             fun,
3055             FunctionSyntaxKind::setter(),
3056             self.builder_stack.maybe_current_scope_index(),
3057         );
3058     }
3059 
before_setter_parameter<T>(&mut self, param: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3060     pub fn before_setter_parameter<T>(&mut self, param: &T)
3061     where
3062         T: SourceLocationAccessor + NodeTypeIdAccessor,
3063     {
3064         self.before_function_parameters(param);
3065         self.before_parameter();
3066     }
3067 
after_setter_parameter(&mut self)3068     pub fn after_setter_parameter(&mut self) {
3069         self.after_function_parameters();
3070     }
3071 
after_setter<T>(&mut self, fun: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3072     pub fn after_setter<T>(&mut self, fun: &T)
3073     where
3074         T: SourceLocationAccessor + NodeTypeIdAccessor,
3075     {
3076         self.function_stencil_builder.leave(fun);
3077     }
3078 
before_arrow_function<T>(&mut self, is_async: bool, params: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3079     pub fn before_arrow_function<T>(&mut self, is_async: bool, params: &T)
3080     where
3081         T: SourceLocationAccessor + NodeTypeIdAccessor,
3082     {
3083         // FIXME: Arrow function needs to access enclosing scope's
3084         //        `this` and `arguments`.
3085         self.set_error(ScopeBuildError::NotImplemented(
3086             "Arrow function (special name handling)",
3087         ));
3088 
3089         self.function_stencil_builder.enter(
3090             params,
3091             FunctionSyntaxKind::arrow(is_async),
3092             self.builder_stack.maybe_current_scope_index(),
3093         );
3094     }
3095 
after_arrow_function<T>(&mut self, body: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3096     pub fn after_arrow_function<T>(&mut self, body: &T)
3097     where
3098         T: SourceLocationAccessor + NodeTypeIdAccessor,
3099     {
3100         self.function_stencil_builder.leave(body);
3101     }
3102 
before_function_parameters<T>(&mut self, params: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3103     pub fn before_function_parameters<T>(&mut self, params: &T)
3104     where
3105         T: SourceLocationAccessor + NodeTypeIdAccessor,
3106     {
3107         self.scope_kind_stack
3108             .push(ScopeKind::FunctionParametersAndBody);
3109 
3110         self.builder_stack
3111             .closed_over_bindings_for_lazy
3112             .push(Vec::new());
3113 
3114         self.function_stencil_builder.on_function_parameters(params);
3115 
3116         self.scope_kind_stack.push(ScopeKind::FormalParameter);
3117 
3118         let is_arrow = self.function_stencil_builder.current().is_arrow_function();
3119 
3120         if self.is_syntax_only_mode() {
3121             let builder = SharedFunctionParametersScopeBuilder::new(is_arrow);
3122             self.builder_stack
3123                 .push_syntax_only_function_parameters(builder);
3124             return;
3125         }
3126 
3127         let index = self.scopes.allocate();
3128 
3129         let builder = FunctionParametersScopeBuilder::new(
3130             index,
3131             is_arrow,
3132             self.function_stencil_builder.current_index(),
3133         );
3134         self.non_global.insert(params, index);
3135 
3136         self.builder_stack.push_function_parameters(builder);
3137     }
3138 
after_function_parameters(&mut self)3139     pub fn after_function_parameters(&mut self) {
3140         self.scope_kind_stack.pop(ScopeKind::FormalParameter);
3141     }
3142 
before_parameter(&mut self)3143     pub fn before_parameter(&mut self) {
3144         self.function_stencil_builder.on_non_rest_parameter();
3145 
3146         if self.is_syntax_only_mode() {
3147             return;
3148         }
3149 
3150         let builder = self.builder_stack.get_function_parameters();
3151         builder.before_parameter();
3152     }
3153 
before_binding_pattern(&mut self)3154     pub fn before_binding_pattern(&mut self) {
3155         match self.builder_stack.innermost() {
3156             ScopeBuilder::FunctionParameters(builder) => {
3157                 builder.before_binding_pattern();
3158             }
3159             ScopeBuilder::SyntaxOnlyFunctionParameters(builder) => {
3160                 builder.before_binding_pattern();
3161             }
3162             _ => {}
3163         }
3164     }
3165 
after_initializer(&mut self)3166     pub fn after_initializer(&mut self) {
3167         match self.builder_stack.innermost() {
3168             ScopeBuilder::FunctionParameters(builder) => {
3169                 builder.after_initializer();
3170             }
3171             ScopeBuilder::SyntaxOnlyFunctionParameters(builder) => {
3172                 builder.after_initializer();
3173             }
3174             _ => {}
3175         }
3176     }
3177 
before_computed_property_name(&mut self)3178     pub fn before_computed_property_name(&mut self) {
3179         match self.builder_stack.innermost() {
3180             ScopeBuilder::FunctionParameters(builder) => {
3181                 builder.before_computed_property_name();
3182             }
3183             ScopeBuilder::SyntaxOnlyFunctionParameters(builder) => {
3184                 builder.before_computed_property_name();
3185             }
3186             _ => {}
3187         }
3188     }
3189 
before_rest_parameter(&mut self)3190     pub fn before_rest_parameter(&mut self) {
3191         self.function_stencil_builder.on_rest_parameter();
3192 
3193         if self.is_syntax_only_mode() {
3194             let builder = self.builder_stack.get_syntax_only_function_parameters();
3195             builder.before_rest_parameter();
3196             return;
3197         }
3198 
3199         let builder = self.builder_stack.get_function_parameters();
3200         builder.before_rest_parameter();
3201     }
3202 
before_function_body<T>(&mut self, body: &T) where T: SourceLocationAccessor + NodeTypeIdAccessor,3203     pub fn before_function_body<T>(&mut self, body: &T)
3204     where
3205         T: SourceLocationAccessor + NodeTypeIdAccessor,
3206     {
3207         if self.is_syntax_only_mode() {
3208             let builder = SharedFunctionBodyScopeBuilder::new();
3209             self.builder_stack.push_syntax_only_function_body(builder);
3210             return;
3211         }
3212 
3213         let var_index = self.scopes.allocate();
3214         let lexical_index = self.scopes.allocate();
3215         debug_assert!(lexical_index == var_index.next());
3216 
3217         let builder = FunctionBodyScopeBuilder::new(var_index, lexical_index);
3218         self.non_global.insert(body, var_index);
3219 
3220         self.builder_stack.push_function_body(builder);
3221     }
3222 
add_closed_over_bindings(&mut self)3223     fn add_closed_over_bindings(&mut self) {
3224         self.function_stencil_builder.add_closed_over_bindings(
3225             self.builder_stack
3226                 .closed_over_bindings_for_lazy
3227                 .pop()
3228                 .expect("Vector should be pushed by before_function_parameters"),
3229         );
3230     }
3231 
update_function_stencil( &mut self, parameter_scope_builder: &SharedFunctionParametersScopeBuilder, body_scope_builder: &SharedFunctionBodyScopeBuilder, )3232     fn update_function_stencil(
3233         &mut self,
3234         parameter_scope_builder: &SharedFunctionParametersScopeBuilder,
3235         body_scope_builder: &SharedFunctionBodyScopeBuilder,
3236     ) {
3237         let has_extra_body_var_scope = parameter_scope_builder.has_parameter_expressions;
3238 
3239         let bindings_accessed_dynamically =
3240             parameter_scope_builder.base.bindings_accessed_dynamically;
3241 
3242         let needs_environment_object = if has_extra_body_var_scope {
3243             bindings_accessed_dynamically || parameter_scope_builder.is_parameter_closed_over()
3244         } else {
3245             bindings_accessed_dynamically
3246                 || parameter_scope_builder.is_parameter_closed_over()
3247                 || body_scope_builder.is_var_closed_over()
3248         };
3249 
3250         let fun_stencil = self.function_stencil_builder.current_mut();
3251 
3252         if needs_environment_object {
3253             fun_stencil.set_needs_function_environment_objects();
3254         }
3255 
3256         if has_extra_body_var_scope {
3257             if body_scope_builder.var_names.len() > 0 {
3258                 fun_stencil.set_function_has_extra_body_var_scope();
3259             }
3260         }
3261 
3262         let strict = parameter_scope_builder.strict;
3263         let simple_parameter_list = parameter_scope_builder.simple_parameter_list;
3264         let has_mapped_arguments = !strict && simple_parameter_list;
3265         if has_mapped_arguments {
3266             fun_stencil.set_has_mapped_args_obj();
3267         }
3268 
3269         if !fun_stencil.is_arrow_function() {
3270             let has_used_this = parameter_scope_builder
3271                 .base
3272                 .name_tracker
3273                 .is_used_or_closed_over(CommonSourceAtomSetIndices::this())
3274                 || bindings_accessed_dynamically;
3275 
3276             if has_used_this {
3277                 fun_stencil.set_function_has_this_binding();
3278             }
3279 
3280             let has_used_arguments = parameter_scope_builder
3281                 .base
3282                 .name_tracker
3283                 .is_used_or_closed_over(CommonSourceAtomSetIndices::arguments())
3284                 || bindings_accessed_dynamically;
3285 
3286             let mut uses_arguments = false;
3287             let mut try_declare_arguments = has_used_arguments;
3288 
3289             let parameter_has_arguments = parameter_scope_builder.parameter_has_arguments;
3290 
3291             let var_names_has_arguments = body_scope_builder
3292                 .var_names
3293                 .contains(&CommonSourceAtomSetIndices::arguments());
3294 
3295             let body_has_defined_arguments =
3296                 var_names_has_arguments || body_scope_builder.function_or_lexical_has_arguments;
3297 
3298             // FunctionDeclarationInstantiation ( func, argumentsList )
3299             // https://tc39.es/ecma262/#sec-functiondeclarationinstantiation
3300             //
3301             // Step 17 (Else if "arguments" is an element of parameterNames...)
3302             // and step 18 (Else if hasParameterExpressions is false...) say
3303             // formal parameters, lexical bindings, and body-level functions
3304             // named 'arguments' shadow the arguments object.
3305             //
3306             // So even if there wasn't a free use of 'arguments' but there is a
3307             // var binding of 'arguments', we still might need the arguments
3308             // object.
3309             //
3310             // If we have an extra var scope due to parameter expressions and
3311             // the body declared 'var arguments', we still need to declare
3312             // 'arguments' in the function scope.
3313             //
3314             // NOTE: This is implementation-specfic optimization, and has
3315             //       no corresponding steps in the spec.
3316             if var_names_has_arguments {
3317                 if has_extra_body_var_scope {
3318                     try_declare_arguments = true;
3319                 } else if !parameter_has_arguments {
3320                     uses_arguments = true;
3321                 }
3322             }
3323 
3324             if try_declare_arguments {
3325                 // if extra body var scope exists, the existence of `arguments`
3326                 // binding in function body doesn't affect.
3327                 let declare_arguments = !parameter_has_arguments
3328                     && (has_extra_body_var_scope || !body_has_defined_arguments);
3329 
3330                 if declare_arguments {
3331                     fun_stencil.set_should_declare_arguments();
3332                     uses_arguments = true;
3333                 }
3334             }
3335 
3336             if uses_arguments {
3337                 fun_stencil.set_needs_args_obj();
3338 
3339                 if has_used_this {
3340                     // FIXME
3341                     // IsLikelyConstructorWrapper should be set if
3342                     // `.apply()` is used and `return` isn't used.
3343                     self.set_error(ScopeBuildError::NotImplemented(
3344                         "IsLikelyConstructorWrapper condition",
3345                     ));
3346                 }
3347             }
3348         }
3349     }
3350 
after_function_body(&mut self)3351     pub fn after_function_body(&mut self) {
3352         self.scope_kind_stack
3353             .pop(ScopeKind::FunctionParametersAndBody);
3354 
3355         if self.is_syntax_only_mode() {
3356             let (parameter_scope_builder, body_scope_builder) = self
3357                 .builder_stack
3358                 .pop_syntax_only_function_parameters_and_body(
3359                     &mut self.function_declaration_properties,
3360                     &mut self.possibly_annex_b_functions,
3361                 );
3362             self.possibly_annex_b_functions.clear();
3363             self.add_closed_over_bindings();
3364             self.update_function_stencil(&parameter_scope_builder, &body_scope_builder);
3365 
3366             self.maybe_exit_syntax_only_mode();
3367             return;
3368         }
3369 
3370         let (parameter_scope_builder, body_scope_builder) =
3371             self.builder_stack.pop_function_parameters_and_body(
3372                 &mut self.function_declaration_properties,
3373                 &mut self.possibly_annex_b_functions,
3374             );
3375         self.possibly_annex_b_functions.clear();
3376         self.add_closed_over_bindings();
3377         self.update_function_stencil(&parameter_scope_builder.shared, &body_scope_builder.shared);
3378 
3379         let enclosing = self.builder_stack.current_scope_index();
3380 
3381         let function_scope_index = parameter_scope_builder.scope_index;
3382         let var_scope_index = body_scope_builder.var_scope_index;
3383         let lexical_scope_index = body_scope_builder.lexical_scope_index;
3384 
3385         // Runtime Semantics: EvaluateBody
3386         // https://tc39.es/ecma262/#sec-function-definitions-runtime-semantics-evaluatebody
3387         //
3388         // With parameters functionObject and List argumentsList.
3389         //
3390         // FunctionBody : FunctionStatementList
3391         //
3392         // Step 1. Perform ? FunctionDeclarationInstantiation(functionObject,
3393         //         argumentsList).
3394         let scope_data_set =
3395             parameter_scope_builder.into_scope_data_set(enclosing, body_scope_builder);
3396 
3397         self.scopes
3398             .populate(function_scope_index, scope_data_set.function);
3399         self.scopes
3400             .populate(var_scope_index, scope_data_set.extra_body_var);
3401         self.scopes
3402             .populate(lexical_scope_index, scope_data_set.lexical);
3403     }
3404 
before_catch_clause(&mut self)3405     pub fn before_catch_clause(&mut self) {
3406         // FIXME: NewDeclarativeEnvironment for catch parameter.
3407         self.set_error(ScopeBuildError::NotImplemented("try-catch"));
3408     }
3409 
on_direct_eval(&mut self)3410     pub fn on_direct_eval(&mut self) {
3411         // FIXME: Propagate to script flags.
3412         self.set_error(ScopeBuildError::NotImplemented(
3413             "direct eval (script flags)",
3414         ));
3415 
3416         if let Some(parameter_scope_builder) =
3417             self.builder_stack.maybe_innermost_function_parameters()
3418         {
3419             parameter_scope_builder.has_direct_eval = true;
3420         }
3421 
3422         self.builder_stack
3423             .innermost()
3424             .base_mut()
3425             .bindings_accessed_dynamically = true;
3426     }
3427 
on_class(&mut self)3428     pub fn on_class(&mut self) {
3429         // FIXME: NewDeclarativeEnvironment for class tail.
3430         self.set_error(ScopeBuildError::NotImplemented("class"));
3431     }
3432 
on_with(&mut self)3433     pub fn on_with(&mut self) {
3434         // FIXME: Propagate to script flags.
3435         self.set_error(ScopeBuildError::NotImplemented("with statement"));
3436     }
3437 
on_delete(&mut self)3438     pub fn on_delete(&mut self) {
3439         // FIXME: Propagate to script flags.
3440         self.set_error(ScopeBuildError::NotImplemented("delete operator"));
3441     }
3442 
on_lexical_for(&mut self)3443     pub fn on_lexical_for(&mut self) {
3444         // FIXME: NewDeclarativeEnvironment in for statement
3445         self.set_error(ScopeBuildError::NotImplemented("lexical for"));
3446     }
3447 
on_switch(&mut self)3448     pub fn on_switch(&mut self) {
3449         // FIXME: NewDeclarativeEnvironment in for case block
3450         self.set_error(ScopeBuildError::NotImplemented("switch"));
3451     }
3452 }
3453 
3454 pub struct ScopeDataMapAndScriptStencilList {
3455     pub scope_data_map: ScopeDataMap,
3456     pub function_stencil_indices: AssociatedData<ScriptStencilIndex>,
3457     pub function_declaration_properties: FunctionDeclarationPropertyMap,
3458     pub scripts: ScriptStencilList,
3459     pub error: Option<ScopeBuildError>,
3460 }
3461 
3462 impl From<ScopeDataMapBuilder> for ScopeDataMapAndScriptStencilList {
from(builder: ScopeDataMapBuilder) -> ScopeDataMapAndScriptStencilList3463     fn from(builder: ScopeDataMapBuilder) -> ScopeDataMapAndScriptStencilList {
3464         ScopeDataMapAndScriptStencilList {
3465             scope_data_map: ScopeDataMap::new(
3466                 builder.scopes,
3467                 builder.global.expect("There should be global scope data"),
3468                 builder.non_global,
3469             ),
3470             function_stencil_indices: builder.function_stencil_builder.function_stencil_indices,
3471             function_declaration_properties: builder.function_declaration_properties,
3472             scripts: builder.function_stencil_builder.scripts,
3473             error: builder.error,
3474         }
3475     }
3476 }
3477