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(¶meter_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(¶meter_scope_builder.base); 2286 } else { 2287 self.update_closed_over_bindings_for_lazy_with_parameters_and_body( 2288 ¶meter_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(¶meter_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(¶meter_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