Line data Source code
1 : // Copyright 2012 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/ast/scopes.h"
6 :
7 : #include <set>
8 :
9 : #include "src/accessors.h"
10 : #include "src/ast/ast.h"
11 : #include "src/base/optional.h"
12 : #include "src/bootstrapper.h"
13 : #include "src/counters.h"
14 : #include "src/message-template.h"
15 : #include "src/objects-inl.h"
16 : #include "src/objects/module-inl.h"
17 : #include "src/objects/scope-info.h"
18 : #include "src/parsing/parse-info.h"
19 : #include "src/parsing/parser.h"
20 : #include "src/parsing/preparse-data.h"
21 : #include "src/zone/zone-list-inl.h"
22 :
23 : namespace v8 {
24 : namespace internal {
25 :
26 : // ----------------------------------------------------------------------------
27 : // Implementation of LocalsMap
28 : //
29 : // Note: We are storing the handle locations as key values in the hash map.
30 : // When inserting a new variable via Declare(), we rely on the fact that
31 : // the handle location remains alive for the duration of that variable
32 : // use. Because a Variable holding a handle with the same location exists
33 : // this is ensured.
34 :
35 0 : VariableMap::VariableMap(Zone* zone)
36 0 : : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {}
37 :
38 43061222 : Variable* VariableMap::Declare(Zone* zone, Scope* scope,
39 43061222 : const AstRawString* name, VariableMode mode,
40 : VariableKind kind,
41 : InitializationFlag initialization_flag,
42 : MaybeAssignedFlag maybe_assigned_flag,
43 : base::ThreadedList<Variable>* variable_list) {
44 : // AstRawStrings are unambiguous, i.e., the same string is always represented
45 : // by the same AstRawString*.
46 : // FIXME(marja): fix the type of Lookup.
47 : Entry* p =
48 : ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
49 86124015 : ZoneAllocationPolicy(zone));
50 43062793 : if (p->value == nullptr) {
51 : // The variable has not been declared yet -> insert it.
52 : DCHECK_EQ(name, p->key);
53 : Variable* variable = new (zone) Variable(
54 : scope, name, mode, kind, initialization_flag, maybe_assigned_flag);
55 42753631 : if (variable_list) variable_list->Add(variable);
56 42753631 : p->value = variable;
57 : }
58 43060671 : return reinterpret_cast<Variable*>(p->value);
59 : }
60 :
61 4115 : void VariableMap::Remove(Variable* var) {
62 4115 : const AstRawString* name = var->raw_name();
63 4115 : ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->Hash());
64 0 : }
65 :
66 908146 : void VariableMap::Add(Zone* zone, Variable* var) {
67 908146 : const AstRawString* name = var->raw_name();
68 : Entry* p =
69 : ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
70 1816313 : ZoneAllocationPolicy(zone));
71 : DCHECK_NULL(p->value);
72 : DCHECK_EQ(name, p->key);
73 908167 : p->value = var;
74 908167 : }
75 :
76 103167143 : Variable* VariableMap::Lookup(const AstRawString* name) {
77 103167143 : Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->Hash());
78 103168954 : if (p != nullptr) {
79 : DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
80 : DCHECK_NOT_NULL(p->value);
81 42608810 : return reinterpret_cast<Variable*>(p->value);
82 : }
83 : return nullptr;
84 : }
85 :
86 0 : void SloppyBlockFunctionMap::Delegate::set_statement(Statement* statement) {
87 7472 : if (statement_ != nullptr) {
88 : statement_->set_statement(statement);
89 : }
90 0 : }
91 :
92 0 : SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone)
93 10279 : : ZoneHashMap(8, ZoneAllocationPolicy(zone)), count_(0) {}
94 :
95 23100 : void SloppyBlockFunctionMap::Declare(Zone* zone, const AstRawString* name,
96 : Scope* scope,
97 : SloppyBlockFunctionStatement* statement) {
98 11550 : auto* delegate = new (zone) Delegate(scope, statement, count_++);
99 : // AstRawStrings are unambiguous, i.e., the same string is always represented
100 : // by the same AstRawString*.
101 : Entry* p =
102 : ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
103 23100 : ZoneAllocationPolicy(zone));
104 11550 : delegate->set_next(static_cast<SloppyBlockFunctionMap::Delegate*>(p->value));
105 11550 : p->value = delegate;
106 11550 : }
107 :
108 : // ----------------------------------------------------------------------------
109 : // Implementation of Scope
110 :
111 2950633 : Scope::Scope(Zone* zone)
112 : : zone_(zone),
113 : outer_scope_(nullptr),
114 : variables_(zone),
115 5901276 : scope_type_(SCRIPT_SCOPE) {
116 : SetDefaults();
117 2950643 : }
118 :
119 12831899 : Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
120 : : zone_(zone),
121 : outer_scope_(outer_scope),
122 : variables_(zone),
123 25664472 : scope_type_(scope_type) {
124 : DCHECK_NE(SCRIPT_SCOPE, scope_type);
125 : SetDefaults();
126 : set_language_mode(outer_scope->language_mode());
127 12832573 : outer_scope_->AddInnerScope(this);
128 12832573 : }
129 :
130 2950634 : DeclarationScope::DeclarationScope(Zone* zone,
131 2950615 : AstValueFactory* ast_value_factory)
132 2950634 : : Scope(zone), function_kind_(kNormalFunction), params_(4, zone) {
133 : DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
134 : SetDefaults();
135 :
136 : // Make sure that if we don't find the global 'this', it won't be declared as
137 : // a regular dynamic global by predeclaring it with the right variable kind.
138 2950615 : DeclareDynamicGlobal(ast_value_factory->this_string(), THIS_VARIABLE, this);
139 2950604 : }
140 :
141 6633683 : DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
142 : ScopeType scope_type,
143 : FunctionKind function_kind)
144 : : Scope(zone, outer_scope, scope_type),
145 : function_kind_(function_kind),
146 6633683 : params_(4, zone) {
147 : DCHECK_NE(scope_type, SCRIPT_SCOPE);
148 : SetDefaults();
149 6634233 : }
150 :
151 61571 : ModuleScope::ModuleScope(DeclarationScope* script_scope,
152 123142 : AstValueFactory* ast_value_factory)
153 : : DeclarationScope(ast_value_factory->zone(), script_scope, MODULE_SCOPE,
154 61571 : kModule) {
155 : Zone* zone = ast_value_factory->zone();
156 61571 : module_descriptor_ = new (zone) ModuleDescriptor(zone);
157 : set_language_mode(LanguageMode::kStrict);
158 61571 : DeclareThis(ast_value_factory);
159 61571 : }
160 :
161 3217 : ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
162 6434 : AstValueFactory* avfactory)
163 3217 : : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info) {
164 : Zone* zone = avfactory->zone();
165 6434 : Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate);
166 :
167 : set_language_mode(LanguageMode::kStrict);
168 3217 : module_descriptor_ = new (zone) ModuleDescriptor(zone);
169 :
170 : // Deserialize special exports.
171 6434 : Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
172 3217 : for (int i = 0, n = special_exports->length(); i < n; ++i) {
173 : Handle<ModuleInfoEntry> serialized_entry(
174 : ModuleInfoEntry::cast(special_exports->get(i)), isolate);
175 : module_descriptor_->AddSpecialExport(
176 : ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
177 0 : serialized_entry),
178 0 : avfactory->zone());
179 : }
180 :
181 : // Deserialize regular exports.
182 : module_descriptor_->DeserializeRegularExports(isolate, avfactory,
183 3217 : module_info);
184 :
185 : // Deserialize namespace imports.
186 : Handle<FixedArray> namespace_imports(module_info->namespace_imports(),
187 6434 : isolate);
188 3512 : for (int i = 0, n = namespace_imports->length(); i < n; ++i) {
189 : Handle<ModuleInfoEntry> serialized_entry(
190 : ModuleInfoEntry::cast(namespace_imports->get(i)), isolate);
191 : module_descriptor_->AddNamespaceImport(
192 : ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
193 295 : serialized_entry),
194 295 : avfactory->zone());
195 : }
196 :
197 : // Deserialize regular imports.
198 6434 : Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
199 5698 : for (int i = 0, n = regular_imports->length(); i < n; ++i) {
200 : Handle<ModuleInfoEntry> serialized_entry(
201 : ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
202 : module_descriptor_->AddRegularImport(ModuleDescriptor::Entry::Deserialize(
203 2481 : isolate, avfactory, serialized_entry));
204 : }
205 3217 : }
206 :
207 1059609 : Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
208 : : zone_(zone),
209 : outer_scope_(nullptr),
210 : variables_(zone),
211 : scope_info_(scope_info),
212 2119227 : scope_type_(scope_type) {
213 : DCHECK(!scope_info.is_null());
214 : SetDefaults();
215 : #ifdef DEBUG
216 : already_resolved_ = true;
217 : #endif
218 1059617 : if (scope_info->CallsSloppyEval()) scope_calls_eval_ = true;
219 2119237 : set_language_mode(scope_info->language_mode());
220 1059623 : num_heap_slots_ = scope_info->ContextLength();
221 : DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
222 : // We don't really need to use the preparsed scope data; this is just to
223 : // shorten the recursion in SetMustUsePreparseData.
224 1059619 : must_use_preparsed_scope_data_ = true;
225 1059619 : }
226 :
227 873449 : DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
228 : Handle<ScopeInfo> scope_info)
229 : : Scope(zone, scope_type, scope_info),
230 1746901 : function_kind_(scope_info->function_kind()),
231 2620351 : params_(0, zone) {
232 : DCHECK_NE(scope_type, SCRIPT_SCOPE);
233 : SetDefaults();
234 873451 : }
235 :
236 1853 : Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
237 : MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
238 : : zone_(zone),
239 : outer_scope_(nullptr),
240 : variables_(zone),
241 : scope_info_(scope_info),
242 3706 : scope_type_(CATCH_SCOPE) {
243 : SetDefaults();
244 : #ifdef DEBUG
245 : already_resolved_ = true;
246 : #endif
247 : // Cache the catch variable, even though it's also available via the
248 : // scope_info, as the parser expects that a catch scope always has the catch
249 : // variable as first and only variable.
250 : Variable* variable =
251 : Declare(zone, catch_variable_name, VariableMode::kVar, NORMAL_VARIABLE,
252 : kCreatedInitialized, maybe_assigned);
253 : AllocateHeapSlot(variable);
254 1853 : }
255 :
256 0 : void DeclarationScope::SetDefaults() {
257 10458299 : is_declaration_scope_ = true;
258 10458299 : has_simple_parameters_ = true;
259 10458299 : is_asm_module_ = false;
260 10458299 : force_eager_compilation_ = false;
261 10458299 : has_arguments_parameter_ = false;
262 10458299 : scope_uses_super_property_ = false;
263 10458299 : has_rest_ = false;
264 10458299 : sloppy_block_function_map_ = nullptr;
265 10458299 : receiver_ = nullptr;
266 10458299 : new_target_ = nullptr;
267 10458299 : function_ = nullptr;
268 10458299 : arguments_ = nullptr;
269 0 : rare_data_ = nullptr;
270 10458299 : should_eager_compile_ = false;
271 10458299 : was_lazily_parsed_ = false;
272 10458299 : is_skipped_function_ = false;
273 10458299 : preparse_data_builder_ = nullptr;
274 : #ifdef DEBUG
275 : DeclarationScope* outer_declaration_scope =
276 : outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
277 : is_being_lazily_parsed_ =
278 : outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
279 : : false;
280 : #endif
281 0 : }
282 :
283 0 : void Scope::SetDefaults() {
284 : #ifdef DEBUG
285 : scope_name_ = nullptr;
286 : already_resolved_ = false;
287 : needs_migration_ = false;
288 : #endif
289 16844687 : inner_scope_ = nullptr;
290 16844687 : sibling_ = nullptr;
291 : unresolved_list_.Clear();
292 :
293 16844687 : start_position_ = kNoSourcePosition;
294 16844687 : end_position_ = kNoSourcePosition;
295 :
296 16844687 : num_stack_slots_ = 0;
297 16844687 : num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
298 :
299 : set_language_mode(LanguageMode::kSloppy);
300 :
301 16844687 : scope_calls_eval_ = false;
302 16844687 : scope_nonlinear_ = false;
303 16844687 : is_hidden_ = false;
304 16844687 : is_debug_evaluate_scope_ = false;
305 :
306 16844687 : inner_scope_calls_eval_ = false;
307 16844687 : force_context_allocation_ = false;
308 16844687 : force_context_allocation_for_parameters_ = false;
309 :
310 16844687 : is_declaration_scope_ = false;
311 :
312 16844687 : must_use_preparsed_scope_data_ = false;
313 0 : }
314 :
315 430764 : bool Scope::HasSimpleParameters() {
316 : DeclarationScope* scope = GetClosureScope();
317 585049 : return !scope->is_function_scope() || scope->has_simple_parameters();
318 : }
319 :
320 6418558 : bool DeclarationScope::ShouldEagerCompile() const {
321 9000233 : return force_eager_compilation_ || should_eager_compile_;
322 : }
323 :
324 722929 : void DeclarationScope::set_should_eager_compile() {
325 2535088 : should_eager_compile_ = !was_lazily_parsed_;
326 722929 : }
327 :
328 6299 : void DeclarationScope::set_is_asm_module() { is_asm_module_ = true; }
329 :
330 2119755 : bool Scope::IsAsmModule() const {
331 8024472 : return is_function_scope() && AsDeclarationScope()->is_asm_module();
332 : }
333 :
334 7164 : bool Scope::ContainsAsmModule() const {
335 7164 : if (IsAsmModule()) return true;
336 :
337 : // Check inner scopes recursively
338 2819 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
339 : // Don't check inner functions which won't be eagerly compiled.
340 5545 : if (!scope->is_function_scope() ||
341 : scope->AsDeclarationScope()->ShouldEagerCompile()) {
342 2395 : if (scope->ContainsAsmModule()) return true;
343 : }
344 : }
345 :
346 : return false;
347 : }
348 :
349 1011002 : Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
350 : ScopeInfo scope_info,
351 : DeclarationScope* script_scope,
352 : AstValueFactory* ast_value_factory,
353 : DeserializationMode deserialization_mode) {
354 : // Reconstruct the outer scope chain from a closure's context chain.
355 : Scope* current_scope = nullptr;
356 : Scope* innermost_scope = nullptr;
357 : Scope* outer_scope = nullptr;
358 3083477 : while (!scope_info.is_null()) {
359 1404276 : if (scope_info->scope_type() == WITH_SCOPE) {
360 : // For scope analysis, debug-evaluate is equivalent to a with scope.
361 : outer_scope =
362 29454 : new (zone) Scope(zone, WITH_SCOPE, handle(scope_info, isolate));
363 :
364 : // TODO(yangguo): Remove once debug-evaluate properly keeps track of the
365 : // function scope in which we are evaluating.
366 14727 : if (scope_info->IsDebugEvaluateScope()) {
367 : outer_scope->set_is_debug_evaluate_scope();
368 : }
369 1389557 : } else if (scope_info->scope_type() == SCRIPT_SCOPE) {
370 : // If we reach a script scope, it's the outermost scope. Install the
371 : // scope info of this script context onto the existing script scope to
372 : // avoid nesting script scopes.
373 342826 : if (deserialization_mode == DeserializationMode::kIncludingVariables) {
374 : script_scope->SetScriptScopeInfo(handle(scope_info, isolate));
375 : }
376 : DCHECK(!scope_info->HasOuterScopeInfo());
377 : break;
378 1046743 : } else if (scope_info->scope_type() == FUNCTION_SCOPE) {
379 : outer_scope = new (zone)
380 1668122 : DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
381 834061 : if (scope_info->IsAsmModule()) {
382 : outer_scope->AsDeclarationScope()->set_is_asm_module();
383 : }
384 212679 : } else if (scope_info->scope_type() == EVAL_SCOPE) {
385 : outer_scope = new (zone)
386 52898 : DeclarationScope(zone, EVAL_SCOPE, handle(scope_info, isolate));
387 186226 : } else if (scope_info->scope_type() == BLOCK_SCOPE) {
388 181155 : if (scope_info->is_declaration_scope()) {
389 : outer_scope = new (zone)
390 19447 : DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
391 : } else {
392 : outer_scope =
393 342871 : new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
394 : }
395 5070 : } else if (scope_info->scope_type() == MODULE_SCOPE) {
396 : outer_scope = new (zone)
397 6434 : ModuleScope(isolate, handle(scope_info, isolate), ast_value_factory);
398 : } else {
399 : DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
400 : DCHECK_EQ(scope_info->ContextLocalCount(), 1);
401 : DCHECK_EQ(scope_info->ContextLocalMode(0), VariableMode::kVar);
402 : DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
403 1853 : String name = scope_info->ContextLocalName(0);
404 : MaybeAssignedFlag maybe_assigned =
405 1853 : scope_info->ContextLocalMaybeAssignedFlag(0);
406 : outer_scope = new (zone)
407 : Scope(zone, ast_value_factory->GetString(handle(name, isolate)),
408 5559 : maybe_assigned, handle(scope_info, isolate));
409 : }
410 1061472 : if (deserialization_mode == DeserializationMode::kScopesOnly) {
411 0 : outer_scope->scope_info_ = Handle<ScopeInfo>::null();
412 : }
413 1061472 : if (current_scope != nullptr) {
414 : outer_scope->AddInnerScope(current_scope);
415 : }
416 : current_scope = outer_scope;
417 1061472 : if (innermost_scope == nullptr) innermost_scope = current_scope;
418 1061472 : scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo()
419 1061471 : : ScopeInfo();
420 : }
421 :
422 2022049 : if (deserialization_mode == DeserializationMode::kIncludingVariables &&
423 : script_scope->scope_info_.is_null()) {
424 : Handle<ScriptContextTable> table(
425 2004594 : isolate->native_context()->script_context_table(), isolate);
426 668198 : Handle<Context> first = ScriptContextTable::GetContext(isolate, table, 0);
427 1336396 : Handle<ScopeInfo> scope_info(first->scope_info(), isolate);
428 : script_scope->SetScriptScopeInfo(scope_info);
429 : }
430 :
431 1011025 : if (innermost_scope == nullptr) return script_scope;
432 839192 : script_scope->AddInnerScope(current_scope);
433 839192 : return innermost_scope;
434 : }
435 :
436 143890672 : DeclarationScope* Scope::AsDeclarationScope() {
437 : DCHECK(is_declaration_scope());
438 143890672 : return static_cast<DeclarationScope*>(this);
439 : }
440 :
441 0 : const DeclarationScope* Scope::AsDeclarationScope() const {
442 : DCHECK(is_declaration_scope());
443 0 : return static_cast<const DeclarationScope*>(this);
444 : }
445 :
446 94972 : ModuleScope* Scope::AsModuleScope() {
447 : DCHECK(is_module_scope());
448 94972 : return static_cast<ModuleScope*>(this);
449 : }
450 :
451 0 : const ModuleScope* Scope::AsModuleScope() const {
452 : DCHECK(is_module_scope());
453 0 : return static_cast<const ModuleScope*>(this);
454 : }
455 :
456 2214992 : int Scope::num_parameters() const {
457 2214992 : return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0;
458 : }
459 :
460 11550 : void DeclarationScope::DeclareSloppyBlockFunction(
461 : const AstRawString* name, Scope* scope,
462 : SloppyBlockFunctionStatement* statement) {
463 11550 : if (sloppy_block_function_map_ == nullptr) {
464 : sloppy_block_function_map_ =
465 : new (zone()->New(sizeof(SloppyBlockFunctionMap)))
466 20558 : SloppyBlockFunctionMap(zone());
467 : }
468 11550 : sloppy_block_function_map_->Declare(zone(), name, scope, statement);
469 11550 : }
470 :
471 4962280 : void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
472 : DCHECK(is_sloppy(language_mode()));
473 : DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
474 : (is_block_scope() && outer_scope()->is_function_scope()));
475 : DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
476 : DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
477 :
478 : SloppyBlockFunctionMap* map = sloppy_block_function_map();
479 9872164 : if (map == nullptr) return;
480 :
481 : // In case of complex parameters the current scope is the body scope and the
482 : // parameters are stored in the outer scope.
483 10227 : Scope* parameter_scope = HasSimpleParameters() ? this : outer_scope_;
484 : DCHECK(parameter_scope->is_function_scope() || is_eval_scope() ||
485 : is_script_scope());
486 :
487 : // The declarations need to be added in the order they were seen,
488 : // so accumulate declared names sorted by index.
489 : ZoneMap<int, const AstRawString*> names_to_declare(zone());
490 :
491 : // For each variable which is used as a function declaration in a sloppy
492 : // block,
493 31548 : for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
494 11096 : const AstRawString* name = static_cast<AstRawString*>(p->key);
495 :
496 : // If the variable wouldn't conflict with a lexical declaration
497 : // or parameter,
498 :
499 : // Check if there's a conflict with a parameter.
500 : Variable* maybe_parameter = parameter_scope->LookupLocal(name);
501 13492 : if (maybe_parameter != nullptr && maybe_parameter->is_parameter()) {
502 : continue;
503 : }
504 :
505 : bool declaration_queued = false;
506 :
507 : // Write in assignments to var for each block-scoped function declaration
508 10903 : auto delegates = static_cast<SloppyBlockFunctionMap::Delegate*>(p->value);
509 :
510 : DeclarationScope* decl_scope = this;
511 23174 : while (decl_scope->is_eval_scope()) {
512 24542 : decl_scope = decl_scope->outer_scope()->GetDeclarationScope();
513 : }
514 : Scope* outer_scope = decl_scope->outer_scope();
515 :
516 46648 : for (SloppyBlockFunctionMap::Delegate* delegate = delegates;
517 : delegate != nullptr; delegate = delegate->next()) {
518 : // Check if there's a conflict with a lexical declaration
519 26048 : Scope* query_scope = delegate->scope()->outer_scope();
520 2890 : Variable* var = nullptr;
521 : bool should_hoist = true;
522 :
523 : // Note that we perform this loop for each delegate named 'name',
524 : // which may duplicate work if those delegates share scopes.
525 : // It is not sufficient to just do a Lookup on query_scope: for
526 : // example, that does not prevent hoisting of the function in
527 : // `{ let e; try {} catch (e) { function e(){} } }`
528 14753 : do {
529 16161 : var = query_scope->LookupInScopeOrScopeInfo(name);
530 19049 : if (var != nullptr && IsLexicalVariableMode(var->mode())) {
531 : should_hoist = false;
532 : break;
533 : }
534 : query_scope = query_scope->outer_scope();
535 : } while (query_scope != outer_scope);
536 :
537 11293 : if (!should_hoist) continue;
538 :
539 9889 : if (!declaration_queued) {
540 : declaration_queued = true;
541 9509 : names_to_declare.insert({delegate->index(), name});
542 : }
543 :
544 9890 : if (factory) {
545 : DCHECK(!is_being_lazily_parsed_);
546 : int pos = delegate->position();
547 : Assignment* assignment = factory->NewAssignment(
548 7471 : Token::ASSIGN, NewUnresolved(factory, name, pos),
549 14943 : delegate->scope()->NewUnresolved(factory, name, pos), pos);
550 : assignment->set_lookup_hoisting_mode(LookupHoistingMode::kLegacySloppy);
551 : Statement* statement = factory->NewExpressionStatement(assignment, pos);
552 : delegate->set_statement(statement);
553 : }
554 : }
555 : }
556 :
557 10226 : if (names_to_declare.empty()) return;
558 :
559 26796 : for (const auto& index_and_name : names_to_declare) {
560 9507 : const AstRawString* name = index_and_name.second;
561 9507 : if (factory) {
562 : DCHECK(!is_being_lazily_parsed_);
563 7197 : VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE);
564 : auto declaration = factory->NewVariableDeclaration(kNoSourcePosition);
565 : // Based on the preceding checks, it doesn't matter what we pass as
566 : // sloppy_mode_block_scope_function_redefinition.
567 7198 : bool ok = true;
568 : DeclareVariable(declaration, proxy, VariableMode::kVar, NORMAL_VARIABLE,
569 : Variable::DefaultInitializationFlag(VariableMode::kVar),
570 7198 : nullptr, &ok);
571 : DCHECK(ok);
572 : } else {
573 : DCHECK(is_being_lazily_parsed_);
574 2310 : Variable* var = DeclareVariableName(name, VariableMode::kVar);
575 : var->set_maybe_assigned();
576 : }
577 : }
578 : }
579 :
580 5436455 : bool DeclarationScope::Analyze(ParseInfo* info) {
581 : RuntimeCallTimerScope runtimeTimer(
582 : info->runtime_call_stats(),
583 : info->on_background_thread()
584 : ? RuntimeCallCounterId::kCompileBackgroundScopeAnalysis
585 3624296 : : RuntimeCallCounterId::kCompileScopeAnalysis);
586 : DCHECK_NOT_NULL(info->literal());
587 1812159 : DeclarationScope* scope = info->literal()->scope();
588 :
589 : base::Optional<AllowHandleDereference> allow_deref;
590 : if (!info->maybe_outer_scope_info().is_null()) {
591 : // Allow dereferences to the scope info if there is one.
592 : allow_deref.emplace();
593 : }
594 :
595 2668665 : if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
596 730387 : AstNodeFactory factory(info->ast_value_factory(), info->zone());
597 730387 : scope->HoistSloppyBlockFunctions(&factory);
598 : }
599 :
600 : // We are compiling one of four cases:
601 : // 1) top-level code,
602 : // 2) a function/eval/module on the top-level
603 : // 3) a function/eval in a scope that was already resolved.
604 : DCHECK(scope->scope_type() == SCRIPT_SCOPE ||
605 : scope->outer_scope()->scope_type() == SCRIPT_SCOPE ||
606 : scope->outer_scope()->already_resolved_);
607 :
608 : // The outer scope is never lazy.
609 : scope->set_should_eager_compile();
610 :
611 1812159 : if (scope->must_use_preparsed_scope_data_) {
612 : DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
613 : allow_deref.emplace();
614 36868 : info->consumed_preparse_data()->RestoreScopeAllocationData(scope);
615 : }
616 :
617 1812159 : if (!scope->AllocateVariables(info)) return false;
618 :
619 : #ifdef DEBUG
620 : if (info->is_native() ? FLAG_print_builtin_scopes : FLAG_print_scopes) {
621 : PrintF("Global scope:\n");
622 : scope->Print();
623 : }
624 : scope->CheckScopePositions();
625 : scope->CheckZones();
626 : #endif
627 :
628 1812015 : return true;
629 : }
630 :
631 9007568 : void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
632 : DCHECK(!already_resolved_);
633 : DCHECK(is_declaration_scope());
634 : DCHECK(has_this_declaration());
635 :
636 4503784 : bool derived_constructor = IsDerivedConstructor(function_kind_);
637 : Variable* var =
638 : Declare(zone(), ast_value_factory->this_string(),
639 : derived_constructor ? VariableMode::kConst : VariableMode::kVar,
640 : THIS_VARIABLE,
641 9007568 : derived_constructor ? kNeedsInitialization : kCreatedInitialized);
642 4503800 : receiver_ = var;
643 4503800 : }
644 :
645 8011992 : void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
646 : DCHECK(is_function_scope());
647 : DCHECK(!is_arrow_scope());
648 :
649 8012040 : arguments_ = LookupLocal(ast_value_factory->arguments_string());
650 4010100 : if (arguments_ == nullptr) {
651 : // Declare 'arguments' variable which exists in all non arrow functions.
652 : // Note that it might never be accessed, in which case it won't be
653 : // allocated during variable allocation.
654 : arguments_ = Declare(zone(), ast_value_factory->arguments_string(),
655 8009343 : VariableMode::kVar);
656 2720 : } else if (IsLexicalVariableMode(arguments_->mode())) {
657 : // Check if there's lexically declared variable named arguments to avoid
658 : // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
659 582 : arguments_ = nullptr;
660 : }
661 4007403 : }
662 :
663 4442208 : void DeclarationScope::DeclareDefaultFunctionVariables(
664 6273625 : AstValueFactory* ast_value_factory) {
665 : DCHECK(is_function_scope());
666 : DCHECK(!is_arrow_scope());
667 :
668 4442208 : DeclareThis(ast_value_factory);
669 : new_target_ = Declare(zone(), ast_value_factory->new_target_string(),
670 9800161 : VariableMode::kConst);
671 :
672 16299922 : if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
673 : IsAccessorFunction(function_kind_)) {
674 : EnsureRareData()->this_function =
675 : Declare(zone(), ast_value_factory->this_function_string(),
676 915698 : VariableMode::kConst);
677 : }
678 4442234 : }
679 :
680 972186 : Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name,
681 : Scope* cache) {
682 : DCHECK(is_function_scope());
683 : DCHECK_NULL(function_);
684 972186 : if (cache == nullptr) cache = this;
685 : DCHECK_NULL(cache->variables_.Lookup(name));
686 1880334 : VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
687 972186 : : NORMAL_VARIABLE;
688 : function_ = new (zone())
689 1944372 : Variable(this, name, VariableMode::kConst, kind, kCreatedInitialized);
690 972186 : if (calls_sloppy_eval()) {
691 64038 : cache->NonLocal(name, VariableMode::kDynamic);
692 : } else {
693 908148 : cache->variables_.Add(zone(), function_);
694 : }
695 972211 : return function_;
696 : }
697 :
698 134450 : Variable* DeclarationScope::DeclareGeneratorObjectVar(
699 134450 : const AstRawString* name) {
700 : DCHECK(is_function_scope() || is_module_scope());
701 : DCHECK_NULL(generator_object_var());
702 :
703 : Variable* result = EnsureRareData()->generator_object =
704 134449 : NewTemporary(name, kNotAssigned);
705 : result->set_is_used();
706 134450 : return result;
707 : }
708 :
709 15466201 : Scope* Scope::FinalizeBlockScope() {
710 : DCHECK(is_block_scope());
711 : #ifdef DEBUG
712 : DCHECK_NE(sibling_, this);
713 : #endif
714 :
715 15255560 : if (variables_.occupancy() > 0 ||
716 75267 : (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval())) {
717 : return this;
718 : }
719 :
720 : // Remove this scope from outer scope.
721 : outer_scope()->RemoveInnerScope(this);
722 :
723 : // Reparent inner scopes.
724 4566929 : if (inner_scope_ != nullptr) {
725 : Scope* scope = inner_scope_;
726 548538 : scope->outer_scope_ = outer_scope();
727 1139825 : while (scope->sibling_ != nullptr) {
728 : scope = scope->sibling_;
729 42749 : scope->outer_scope_ = outer_scope();
730 : }
731 548538 : scope->sibling_ = outer_scope()->inner_scope_;
732 548538 : outer_scope()->inner_scope_ = inner_scope_;
733 548538 : inner_scope_ = nullptr;
734 : }
735 :
736 : // Move unresolved variables
737 4566929 : if (!unresolved_list_.is_empty()) {
738 : outer_scope()->unresolved_list_.Prepend(std::move(unresolved_list_));
739 : unresolved_list_.Clear();
740 : }
741 :
742 4791975 : if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
743 :
744 : // No need to propagate scope_calls_eval_, since if it was relevant to
745 : // this scope we would have had to bail out at the top.
746 : DCHECK(!scope_calls_eval_ || !is_declaration_scope() ||
747 : !is_sloppy(language_mode()));
748 :
749 : // This block does not need a context.
750 4566929 : num_heap_slots_ = 0;
751 :
752 : // Mark scope as removed by making it its own sibling.
753 : #ifdef DEBUG
754 : sibling_ = this;
755 : #endif
756 :
757 4566929 : return nullptr;
758 : }
759 :
760 0 : void DeclarationScope::AddLocal(Variable* var) {
761 : DCHECK(!already_resolved_);
762 : // Temporaries are only placed in ClosureScopes.
763 : DCHECK_EQ(GetClosureScope(), this);
764 : locals_.Add(var);
765 0 : }
766 :
767 126136 : void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
768 : DCHECK(!IsCleared());
769 : DCHECK_EQ(new_parent, outer_scope_and_calls_eval_.GetPointer()->inner_scope_);
770 : DCHECK_EQ(new_parent->outer_scope_, outer_scope_and_calls_eval_.GetPointer());
771 : DCHECK_EQ(new_parent, new_parent->GetClosureScope());
772 : DCHECK_NULL(new_parent->inner_scope_);
773 : DCHECK(new_parent->unresolved_list_.is_empty());
774 : DCHECK(new_parent->locals_.is_empty());
775 126136 : Scope* inner_scope = new_parent->sibling_;
776 126136 : if (inner_scope != top_inner_scope_) {
777 3632 : for (; inner_scope->sibling() != top_inner_scope_;
778 : inner_scope = inner_scope->sibling()) {
779 0 : inner_scope->outer_scope_ = new_parent;
780 0 : if (inner_scope->inner_scope_calls_eval_) {
781 0 : new_parent->inner_scope_calls_eval_ = true;
782 : }
783 : DCHECK_NE(inner_scope, new_parent);
784 : }
785 3632 : inner_scope->outer_scope_ = new_parent;
786 3632 : if (inner_scope->inner_scope_calls_eval_) {
787 128 : new_parent->inner_scope_calls_eval_ = true;
788 : }
789 3632 : new_parent->inner_scope_ = new_parent->sibling_;
790 3632 : inner_scope->sibling_ = nullptr;
791 : // Reset the sibling rather than the inner_scope_ since we
792 : // want to keep new_parent there.
793 3632 : new_parent->sibling_ = top_inner_scope_;
794 : }
795 :
796 : Scope* outer_scope_ = outer_scope_and_calls_eval_.GetPointer();
797 : new_parent->unresolved_list_.MoveTail(&outer_scope_->unresolved_list_,
798 : top_unresolved_);
799 :
800 : // Move temporaries allocated for complex parameter initializers.
801 : DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
802 : new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
803 252284 : for (Variable* local : new_parent->locals_) {
804 : DCHECK_EQ(VariableMode::kTemporary, local->mode());
805 : DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
806 : DCHECK_NE(local->scope(), new_parent);
807 : local->set_scope(new_parent);
808 : }
809 : outer_closure->locals_.Rewind(top_local_);
810 :
811 : // Move eval calls since Snapshot's creation into new_parent.
812 126136 : if (outer_scope_and_calls_eval_->scope_calls_eval_) {
813 413 : new_parent->scope_calls_eval_ = true;
814 413 : new_parent->inner_scope_calls_eval_ = true;
815 : }
816 :
817 : // We are in the arrow function case. The calls eval we may have recorded
818 : // is intended for the inner scope and we should simply restore the
819 : // original "calls eval" flag of the outer scope.
820 : RestoreEvalFlag();
821 : Clear();
822 126136 : }
823 :
824 91 : void Scope::ReplaceOuterScope(Scope* outer) {
825 : DCHECK_NOT_NULL(outer);
826 : DCHECK_NOT_NULL(outer_scope_);
827 : DCHECK(!already_resolved_);
828 91 : outer_scope_->RemoveInnerScope(this);
829 : outer->AddInnerScope(this);
830 : outer_scope_ = outer;
831 91 : }
832 :
833 5022980 : Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
834 : DCHECK(!scope_info_.is_null());
835 : DCHECK_NULL(cache->variables_.Lookup(name));
836 :
837 : Handle<String> name_handle = name->string();
838 : // The Scope is backed up by ScopeInfo. This means it cannot operate in a
839 : // heap-independent mode, and all strings must be internalized immediately. So
840 : // it's ok to get the Handle<String> here.
841 : bool found = false;
842 :
843 : VariableLocation location;
844 : int index;
845 : VariableMode mode;
846 : InitializationFlag init_flag;
847 : MaybeAssignedFlag maybe_assigned_flag;
848 :
849 : {
850 : location = VariableLocation::CONTEXT;
851 : index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
852 2511264 : &init_flag, &maybe_assigned_flag);
853 2511286 : found = index >= 0;
854 : }
855 :
856 4628186 : if (!found && scope_type() == MODULE_SCOPE) {
857 : location = VariableLocation::MODULE;
858 : index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
859 1982 : &maybe_assigned_flag);
860 1982 : found = index != 0;
861 : }
862 :
863 2511286 : if (!found) {
864 2116470 : index = scope_info_->FunctionContextSlotIndex(*name_handle);
865 2116470 : if (index < 0) return nullptr; // Nowhere found.
866 1040 : Variable* var = AsDeclarationScope()->DeclareFunctionVar(name, cache);
867 : DCHECK_EQ(VariableMode::kConst, var->mode());
868 : var->AllocateTo(VariableLocation::CONTEXT, index);
869 1040 : return cache->variables_.Lookup(name);
870 : }
871 :
872 : VariableKind kind = NORMAL_VARIABLE;
873 1184450 : if (location == VariableLocation::CONTEXT &&
874 1183590 : index == scope_info_->ReceiverContextSlotIndex()) {
875 : kind = THIS_VARIABLE;
876 : }
877 : // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
878 : // ARGUMENTS bindings as their corresponding VariableKind.
879 :
880 : Variable* var = cache->variables_.Declare(zone(), this, name, mode, kind,
881 789632 : init_flag, maybe_assigned_flag);
882 : var->AllocateTo(location, index);
883 394817 : return var;
884 : }
885 :
886 2904184 : Variable* DeclarationScope::DeclareParameter(const AstRawString* name,
887 : VariableMode mode,
888 : bool is_optional, bool is_rest,
889 2904189 : AstValueFactory* ast_value_factory,
890 : int position) {
891 : DCHECK(!already_resolved_);
892 : DCHECK(is_function_scope() || is_module_scope());
893 : DCHECK(!has_rest_);
894 : DCHECK(!is_optional || !is_rest);
895 : DCHECK(!is_being_lazily_parsed_);
896 : DCHECK(!was_lazily_parsed_);
897 : Variable* var;
898 2904184 : if (mode == VariableMode::kTemporary) {
899 3117169 : var = NewTemporary(name);
900 : } else {
901 : DCHECK_EQ(mode, VariableMode::kVar);
902 5595399 : var = Declare(zone(), name, mode, PARAMETER_VARIABLE);
903 : }
904 2904192 : has_rest_ = is_rest;
905 2904192 : var->set_initializer_position(position);
906 2904192 : params_.Add(var, zone());
907 2904189 : if (!is_rest) ++num_parameters_;
908 2904189 : if (name == ast_value_factory->arguments_string()) {
909 1454 : has_arguments_parameter_ = true;
910 : }
911 : // Params are automatically marked as used to make sure that the debugger and
912 : // function.arguments sees them.
913 : // TODO(verwaest): Reevaluate whether we always need to do this, since
914 : // strict-mode function.arguments does not make the arguments available.
915 2904189 : var->set_is_used();
916 2904189 : return var;
917 : }
918 :
919 3739153 : void DeclarationScope::RecordParameter(bool is_rest) {
920 : DCHECK(!already_resolved_);
921 : DCHECK(is_function_scope() || is_module_scope());
922 : DCHECK(is_being_lazily_parsed_);
923 : DCHECK(!has_rest_);
924 3739153 : has_rest_ = is_rest;
925 3739153 : if (!is_rest) ++num_parameters_;
926 3739153 : }
927 :
928 4042806 : void DeclarationScope::DeclareParameterName(const AstRawString* name) {
929 : DCHECK(!already_resolved_);
930 : DCHECK(is_function_scope() || is_module_scope());
931 : DCHECK(is_being_lazily_parsed_);
932 : // The resulting variable isn't added to params. In the case of non-simple
933 : // params, a dummy temp variable is added in AddNonSimpleParameterTemp.
934 4042806 : Variable* var = Declare(zone(), name, VariableMode::kVar, PARAMETER_VARIABLE);
935 : // Params are automatically marked as used to make sure that the debugger and
936 : // function.arguments sees them.
937 : // TODO(verwaest): Reevaluate whether we always need to do this, since
938 : // strict-mode function.arguments does not make the arguments available.
939 : var->set_is_used();
940 4042906 : }
941 :
942 68082 : Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
943 15269194 : VariableKind kind, InitializationFlag init_flag) {
944 : DCHECK(!already_resolved_);
945 : // This function handles VariableMode::kVar, VariableMode::kLet, and
946 : // VariableMode::kConst modes. VariableMode::kDynamic variables are
947 : // introduced during variable allocation, and VariableMode::kTemporary
948 : // variables are allocated via NewTemporary().
949 : DCHECK(IsDeclaredVariableMode(mode));
950 : DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
951 : mode == VariableMode::kVar || mode == VariableMode::kLet ||
952 : mode == VariableMode::kConst);
953 : DCHECK(!GetDeclarationScope()->was_lazily_parsed());
954 68083 : return Declare(zone(), name, mode, kind, init_flag);
955 : }
956 :
957 : // TODO(leszeks): Avoid passing the proxy into here, passing the raw_name alone
958 : // instead.
959 11056089 : void Scope::DeclareVariable(Declaration* declaration, VariableProxy* proxy,
960 : VariableMode mode, VariableKind kind,
961 : InitializationFlag init,
962 : bool* sloppy_mode_block_scope_function_redefinition,
963 20908655 : bool* ok) {
964 : DCHECK(IsDeclaredVariableMode(mode));
965 : DCHECK(!already_resolved_);
966 : DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
967 : DCHECK(!GetDeclarationScope()->was_lazily_parsed());
968 :
969 20343343 : if (mode == VariableMode::kVar && !is_declaration_scope()) {
970 : return GetDeclarationScope()->DeclareVariable(
971 : declaration, proxy, mode, kind, init,
972 11878054 : sloppy_mode_block_scope_function_redefinition, ok);
973 : }
974 : DCHECK(!is_catch_scope());
975 : DCHECK(!is_with_scope());
976 : DCHECK(is_declaration_scope() ||
977 : (IsLexicalVariableMode(mode) && is_block_scope()));
978 :
979 : DCHECK_NOT_NULL(proxy->raw_name());
980 235 : const AstRawString* name = proxy->raw_name();
981 :
982 : // Pessimistically assume that top-level variables will be assigned.
983 : //
984 : // Top-level variables in a script can be accessed by other scripts or even
985 : // become global properties. While this does not apply to top-level variables
986 : // in a module (assuming they are not exported), we must still mark these as
987 : // assigned because they might be accessed by a lazily parsed top-level
988 : // function, which, for efficiency, we preparse without variable tracking.
989 10645126 : if (is_script_scope() || is_module_scope()) {
990 3002403 : if (mode != VariableMode::kConst) proxy->set_is_assigned();
991 : }
992 :
993 : Variable* var = LookupLocal(name);
994 : // Declare the variable in the declaration scope.
995 10645407 : if (V8_LIKELY(var == nullptr)) {
996 11069119 : if (V8_UNLIKELY(is_eval_scope() && is_sloppy(language_mode()) &&
997 : mode == VariableMode::kVar)) {
998 : // In a var binding in a sloppy direct eval, pollute the enclosing scope
999 : // with this new binding by doing the following:
1000 : // The proxy is bound to a lookup variable to force a dynamic declaration
1001 : // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
1002 : DCHECK_EQ(NORMAL_VARIABLE, kind);
1003 306281 : var = NonLocal(proxy->raw_name(), VariableMode::kDynamic);
1004 : } else {
1005 : // Declare the name.
1006 : var = DeclareLocal(name, mode, kind, init);
1007 : }
1008 : } else {
1009 : var->set_maybe_assigned();
1010 712336 : if (V8_UNLIKELY(IsLexicalVariableMode(mode) ||
1011 : IsLexicalVariableMode(var->mode()))) {
1012 : // The name was declared in this scope before; check for conflicting
1013 : // re-declarations. We have a conflict if either of the declarations is
1014 : // not a var (in script scope, we also have to ignore legacy const for
1015 : // compatibility). There is similar code in runtime.cc in the Declare
1016 : // functions. The function CheckConflictingVarDeclarations checks for
1017 : // var and let bindings from different scopes whereas this is a check
1018 : // for conflicting declarations within the same scope. This check also
1019 : // covers the special case
1020 : //
1021 : // function () { let x; { var x; } }
1022 : //
1023 : // because the var declaration is hoisted to the function scope where
1024 : // 'x' is already bound.
1025 : //
1026 : // In harmony we treat re-declarations as early errors. See ES5 16 for a
1027 : // definition of early errors.
1028 : //
1029 : // Allow duplicate function decls for web compat, see bug 4693. If the
1030 : // duplication is allowed, then the var will show up in the
1031 : // SloppyBlockFunctionMap.
1032 : SloppyBlockFunctionMap* map =
1033 65575 : GetDeclarationScope()->sloppy_block_function_map();
1034 : *ok =
1035 756 : map != nullptr && declaration->IsFunctionDeclaration() &&
1036 : declaration->AsFunctionDeclaration()
1037 66440 : ->declares_sloppy_block_function() &&
1038 65810 : map->Lookup(const_cast<AstRawString*>(name), name->Hash()) != nullptr;
1039 65575 : *sloppy_mode_block_scope_function_redefinition = *ok;
1040 : }
1041 : }
1042 : DCHECK_NOT_NULL(var);
1043 :
1044 : // We add a declaration node for every declaration. The compiler
1045 : // will only generate code if necessary. In particular, declarations
1046 : // for inner local variables that do not represent functions won't
1047 : // result in any generated code.
1048 : //
1049 : // This will lead to multiple declaration nodes for the
1050 : // same variable if it is declared several times. This is not a
1051 : // semantic issue, but it may be a performance issue since it may
1052 : // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
1053 : decls_.Add(declaration);
1054 : declaration->set_var(var);
1055 10645186 : proxy->BindTo(var);
1056 : }
1057 :
1058 5467211 : Variable* Scope::DeclareVariableName(const AstRawString* name,
1059 : VariableMode mode) {
1060 : DCHECK(IsDeclaredVariableMode(mode));
1061 : DCHECK(!already_resolved_);
1062 : DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
1063 :
1064 10795448 : if (mode == VariableMode::kVar && !is_declaration_scope()) {
1065 575238 : return GetDeclarationScope()->DeclareVariableName(name, mode);
1066 : }
1067 : DCHECK(!is_with_scope());
1068 : DCHECK(!is_eval_scope());
1069 : DCHECK(is_declaration_scope() || IsLexicalVariableMode(mode));
1070 : DCHECK(scope_info_.is_null());
1071 :
1072 : // Declare the variable in the declaration scope.
1073 222960 : Variable* var = LookupLocal(name);
1074 5467330 : if (var == nullptr) {
1075 : var = DeclareLocal(name, mode);
1076 446426 : } else if (IsLexicalVariableMode(mode) ||
1077 : IsLexicalVariableMode(var->mode())) {
1078 : // Duplicate functions are allowed in the sloppy mode, but if this is not
1079 : // a function declaration, it's an error. This is an error PreParser
1080 : // hasn't previously detected.
1081 : return nullptr;
1082 222946 : } else if (mode == VariableMode::kVar) {
1083 : var->set_maybe_assigned();
1084 : }
1085 : var->set_is_used();
1086 5466825 : return var;
1087 : }
1088 :
1089 370864 : Variable* Scope::DeclareCatchVariableName(const AstRawString* name) {
1090 : DCHECK(!already_resolved_);
1091 : DCHECK(is_catch_scope());
1092 : DCHECK(scope_info_.is_null());
1093 :
1094 370907 : return Declare(zone(), name, VariableMode::kVar);
1095 : }
1096 :
1097 53749769 : void Scope::AddUnresolved(VariableProxy* proxy) {
1098 : DCHECK(!already_resolved_);
1099 : DCHECK(!proxy->is_resolved());
1100 : unresolved_list_.Add(proxy);
1101 53748844 : }
1102 :
1103 5516013 : Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
1104 : VariableKind kind,
1105 : Scope* cache) {
1106 : DCHECK(is_script_scope());
1107 : return cache->variables_.Declare(zone(), this, name,
1108 5516013 : VariableMode::kDynamicGlobal, kind);
1109 : // TODO(neis): Mark variable as maybe-assigned?
1110 : }
1111 :
1112 1269 : bool Scope::RemoveUnresolved(VariableProxy* var) {
1113 1269 : return unresolved_list_.Remove(var);
1114 : }
1115 :
1116 15783 : void Scope::DeleteUnresolved(VariableProxy* var) {
1117 : DCHECK(unresolved_list_.Contains(var));
1118 : var->mark_removed_from_unresolved();
1119 15783 : }
1120 :
1121 1239689 : Variable* Scope::NewTemporary(const AstRawString* name) {
1122 1346176 : return NewTemporary(name, kMaybeAssigned);
1123 : }
1124 :
1125 1480624 : Variable* Scope::NewTemporary(const AstRawString* name,
1126 1480624 : MaybeAssignedFlag maybe_assigned) {
1127 : DeclarationScope* scope = GetClosureScope();
1128 : Variable* var = new (zone()) Variable(scope, name, VariableMode::kTemporary,
1129 : NORMAL_VARIABLE, kCreatedInitialized);
1130 : scope->AddLocal(var);
1131 1480631 : if (maybe_assigned == kMaybeAssigned) var->set_maybe_assigned();
1132 1480631 : return var;
1133 : }
1134 :
1135 14870084 : Declaration* Scope::CheckConflictingVarDeclarations() {
1136 22298294 : for (Declaration* decl : decls_) {
1137 : // Lexical vs lexical conflicts within the same scope have already been
1138 : // captured in Parser::Declare. The only conflicts we still need to check
1139 : // are lexical vs nested var.
1140 1228788 : Scope* current = nullptr;
1141 18675560 : if (decl->IsVariableDeclaration() &&
1142 8922133 : decl->AsVariableDeclaration()->AsNested() != nullptr) {
1143 783608 : current = decl->AsVariableDeclaration()->AsNested()->scope();
1144 10089577 : } else if (is_eval_scope() && is_sloppy(language_mode())) {
1145 600396 : if (IsLexicalVariableMode(decl->var()->mode())) continue;
1146 288675 : current = outer_scope_;
1147 : }
1148 9741904 : if (current == nullptr) continue;
1149 : DCHECK(decl->var()->mode() == VariableMode::kVar ||
1150 : decl->var()->mode() == VariableMode::kDynamic);
1151 : // Iterate through all scopes until and including the declaration scope.
1152 : while (true) {
1153 : // There is a conflict if there exists a non-VAR binding.
1154 393625 : Variable* other_var =
1155 1241026 : current->LookupInScopeOrScopeInfo(decl->var()->raw_name());
1156 1634637 : if (other_var != nullptr && IsLexicalVariableMode(other_var->mode())) {
1157 : return decl;
1158 : }
1159 3123733 : if (current->is_declaration_scope() &&
1160 1851 : !(current->is_eval_scope() && is_sloppy(current->language_mode()))) {
1161 : break;
1162 : }
1163 : current = current->outer_scope();
1164 : }
1165 560549 : }
1166 : return nullptr;
1167 : }
1168 :
1169 85322 : const AstRawString* Scope::FindVariableDeclaredIn(Scope* scope,
1170 : VariableMode mode_limit) {
1171 : const VariableMap& variables = scope->variables_;
1172 649266 : for (ZoneHashMap::Entry* p = variables.Start(); p != nullptr;
1173 : p = variables.Next(p)) {
1174 478882 : const AstRawString* name = static_cast<const AstRawString*>(p->key);
1175 1585 : Variable* var = LookupLocal(name);
1176 480472 : if (var != nullptr && var->mode() <= mode_limit) return name;
1177 : }
1178 : return nullptr;
1179 : }
1180 :
1181 1812151 : bool DeclarationScope::AllocateVariables(ParseInfo* info) {
1182 : // Module variables must be allocated before variable resolution
1183 : // to ensure that UpdateNeedsHoleCheck() can detect import variables.
1184 1812151 : if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
1185 :
1186 1812151 : if (!ResolveVariablesRecursively(info)) {
1187 : DCHECK(info->pending_error_handler()->has_pending_error());
1188 : return false;
1189 : }
1190 1812019 : AllocateVariablesRecursively();
1191 :
1192 1812018 : return true;
1193 : }
1194 :
1195 4066833 : bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
1196 : const Scope* outer) const {
1197 : // If none of the outer scopes need to decide whether to context allocate
1198 : // specific variables, we can preparse inner functions without unresolved
1199 : // variables. Otherwise we need to find unresolved variables to force context
1200 : // allocation of the matching declarations. We can stop at the outer scope for
1201 : // the parse, since context allocation of those variables is already
1202 : // guaranteed to be correct.
1203 4066962 : for (const Scope* s = this; s != outer; s = s->outer_scope_) {
1204 : // Eval forces context allocation on all outer scopes, so we don't need to
1205 : // look at those scopes. Sloppy eval makes top-level non-lexical variables
1206 : // dynamic, whereas strict-mode requires context allocation.
1207 3031229 : if (s->is_eval_scope()) return is_sloppy(s->language_mode());
1208 : // Catch scopes force context allocation of all variables.
1209 2005685 : if (s->is_catch_scope()) continue;
1210 : // With scopes do not introduce variables that need allocation.
1211 2005691 : if (s->is_with_scope()) continue;
1212 : DCHECK(s->is_module_scope() || s->is_block_scope() ||
1213 : s->is_function_scope());
1214 : return false;
1215 : }
1216 : return true;
1217 : }
1218 :
1219 3564344 : bool DeclarationScope::AllowsLazyCompilation() const {
1220 3564344 : return !force_eager_compilation_;
1221 : }
1222 :
1223 2785650 : int Scope::ContextChainLength(Scope* scope) const {
1224 : int n = 0;
1225 3413443 : for (const Scope* s = this; s != scope; s = s->outer_scope_) {
1226 : DCHECK_NOT_NULL(s); // scope must be in the scope chain
1227 627793 : if (s->NeedsContext()) n++;
1228 : }
1229 2785650 : return n;
1230 : }
1231 :
1232 372469 : int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
1233 : int result = 0;
1234 : int length = 0;
1235 :
1236 1540319 : for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
1237 1167850 : if (!s->NeedsContext()) continue;
1238 868341 : length++;
1239 1700153 : if (s->is_declaration_scope() &&
1240 : s->AsDeclarationScope()->calls_sloppy_eval()) {
1241 : result = length;
1242 : }
1243 : }
1244 :
1245 372469 : return result;
1246 : }
1247 :
1248 3730590 : DeclarationScope* Scope::GetDeclarationScope() {
1249 3971009 : Scope* scope = this;
1250 12880804 : while (!scope->is_declaration_scope()) {
1251 : scope = scope->outer_scope();
1252 : }
1253 3730590 : return scope->AsDeclarationScope();
1254 : }
1255 :
1256 0 : const DeclarationScope* Scope::GetClosureScope() const {
1257 0 : const Scope* scope = this;
1258 0 : while (!scope->is_declaration_scope() || scope->is_block_scope()) {
1259 : scope = scope->outer_scope();
1260 : }
1261 0 : return scope->AsDeclarationScope();
1262 : }
1263 :
1264 3787381 : DeclarationScope* Scope::GetClosureScope() {
1265 17986800 : Scope* scope = this;
1266 34926226 : while (!scope->is_declaration_scope() || scope->is_block_scope()) {
1267 : scope = scope->outer_scope();
1268 : }
1269 3787381 : return scope->AsDeclarationScope();
1270 : }
1271 :
1272 2415046 : bool Scope::NeedsScopeInfo() const {
1273 : DCHECK(!already_resolved_);
1274 : DCHECK(GetClosureScope()->ShouldEagerCompile());
1275 : // The debugger expects all functions to have scope infos.
1276 : // TODO(jochen|yangguo): Remove this requirement.
1277 2415046 : if (is_function_scope()) return true;
1278 0 : return NeedsContext();
1279 : }
1280 :
1281 86943 : bool Scope::ShouldBanArguments() {
1282 173888 : return GetReceiverScope()->should_ban_arguments();
1283 : }
1284 :
1285 123307 : DeclarationScope* Scope::GetReceiverScope() {
1286 133651 : Scope* scope = this;
1287 637223 : while (!scope->is_script_scope() &&
1288 117855 : (!scope->is_function_scope() ||
1289 : scope->AsDeclarationScope()->is_arrow_scope())) {
1290 : scope = scope->outer_scope();
1291 : }
1292 123307 : return scope->AsDeclarationScope();
1293 : }
1294 :
1295 2557481 : Scope* Scope::GetOuterScopeWithContext() {
1296 3494437 : Scope* scope = outer_scope_;
1297 9150085 : while (scope && !scope->NeedsContext()) {
1298 : scope = scope->outer_scope();
1299 : }
1300 2557481 : return scope;
1301 : }
1302 :
1303 16784 : void Scope::CollectNonLocals(DeclarationScope* max_outer_scope,
1304 : Isolate* isolate, ParseInfo* info,
1305 17517 : Handle<StringSet>* non_locals) {
1306 : // Module variables must be allocated before variable resolution
1307 : // to ensure that UpdateNeedsHoleCheck() can detect import variables.
1308 16784 : if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
1309 :
1310 : // Lazy parsed declaration scopes are already partially analyzed. If there are
1311 : // unresolved references remaining, they just need to be resolved in outer
1312 : // scopes.
1313 : Scope* lookup =
1314 14898 : is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()
1315 : ? outer_scope()
1316 17517 : : this;
1317 :
1318 91242 : for (VariableProxy* proxy : unresolved_list_) {
1319 : DCHECK(!proxy->is_resolved());
1320 : Variable* var =
1321 57674 : Lookup<kParsedScope>(proxy, lookup, max_outer_scope->outer_scope());
1322 57674 : if (var == nullptr) {
1323 16507 : *non_locals = StringSet::Add(isolate, *non_locals, proxy->name());
1324 : } else {
1325 : // In this case we need to leave scopes in a way that they can be
1326 : // allocated. If we resolved variables from lazy parsed scopes, we need
1327 : // to context allocate the var.
1328 : ResolveTo(info, proxy, var);
1329 41167 : if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation();
1330 : }
1331 : }
1332 :
1333 : // Clear unresolved_list_ as it's in an inconsistent state.
1334 : unresolved_list_.Clear();
1335 :
1336 21235 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1337 4451 : scope->CollectNonLocals(max_outer_scope, isolate, info, non_locals);
1338 : }
1339 16784 : }
1340 :
1341 2956767 : void Scope::AnalyzePartially(DeclarationScope* max_outer_scope,
1342 5679836 : AstNodeFactory* ast_node_factory,
1343 : UnresolvedList* new_unresolved_list) {
1344 : DCHECK_IMPLIES(is_declaration_scope(),
1345 : !AsDeclarationScope()->was_lazily_parsed());
1346 :
1347 43910290 : for (VariableProxy* proxy = unresolved_list_.first(); proxy != nullptr;
1348 : proxy = proxy->next_unresolved()) {
1349 : DCHECK(!proxy->is_resolved());
1350 : Variable* var =
1351 29261352 : Lookup<kParsedScope>(proxy, this, max_outer_scope->outer_scope());
1352 23404971 : if (var == nullptr) {
1353 : // Don't copy unresolved references to the script scope, unless it's a
1354 : // reference to a private name or method. In that case keep it so we
1355 : // can fail later.
1356 6034997 : if (!max_outer_scope->outer_scope()->is_script_scope() ||
1357 178599 : proxy->IsPrivateName()) {
1358 : VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
1359 : new_unresolved_list->Add(copy);
1360 : }
1361 : } else {
1362 : var->set_is_used();
1363 17548579 : if (proxy->is_assigned()) var->set_maybe_assigned();
1364 : }
1365 : }
1366 :
1367 : // Clear unresolved_list_ as it's in an inconsistent state.
1368 : unresolved_list_.Clear();
1369 :
1370 4120907 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1371 : scope->AnalyzePartially(max_outer_scope, ast_node_factory,
1372 1164124 : new_unresolved_list);
1373 : }
1374 2956783 : }
1375 :
1376 12333 : Handle<StringSet> DeclarationScope::CollectNonLocals(
1377 : Isolate* isolate, ParseInfo* info, Handle<StringSet> non_locals) {
1378 12333 : Scope::CollectNonLocals(this, isolate, info, &non_locals);
1379 12333 : return non_locals;
1380 : }
1381 :
1382 2540338 : void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
1383 : bool aborted) {
1384 : DCHECK(is_function_scope());
1385 :
1386 : // Reset all non-trivial members.
1387 : params_.Clear();
1388 : decls_.Clear();
1389 : locals_.Clear();
1390 2497421 : inner_scope_ = nullptr;
1391 : unresolved_list_.Clear();
1392 2497421 : sloppy_block_function_map_ = nullptr;
1393 2497421 : rare_data_ = nullptr;
1394 2497421 : has_rest_ = false;
1395 :
1396 : DCHECK_NE(zone_, ast_value_factory->zone());
1397 2497421 : zone_->ReleaseMemory();
1398 :
1399 2497694 : if (aborted) {
1400 : // Prepare scope for use in the outer zone.
1401 42917 : zone_ = ast_value_factory->zone();
1402 42917 : variables_.Reset(ZoneAllocationPolicy(zone_));
1403 85834 : if (!IsArrowFunction(function_kind_)) {
1404 40306 : has_simple_parameters_ = true;
1405 40306 : DeclareDefaultFunctionVariables(ast_value_factory);
1406 : }
1407 : } else {
1408 : // Make sure this scope isn't used for allocation anymore.
1409 2454777 : zone_ = nullptr;
1410 : variables_.Invalidate();
1411 : }
1412 :
1413 : #ifdef DEBUG
1414 : needs_migration_ = false;
1415 : is_being_lazily_parsed_ = false;
1416 : #endif
1417 :
1418 2497694 : was_lazily_parsed_ = !aborted;
1419 2497694 : }
1420 :
1421 2956714 : void Scope::SavePreparseData(Parser* parser) {
1422 2956714 : if (PreparseDataBuilder::ScopeIsSkippableFunctionScope(this)) {
1423 : AsDeclarationScope()->SavePreparseDataForDeclarationScope(parser);
1424 : }
1425 :
1426 4120805 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1427 1164130 : scope->SavePreparseData(parser);
1428 : }
1429 2956675 : }
1430 :
1431 0 : void DeclarationScope::SavePreparseDataForDeclarationScope(Parser* parser) {
1432 1935981 : if (preparse_data_builder_ == nullptr) return;
1433 1935987 : preparse_data_builder_->SaveScopeAllocationData(this, parser);
1434 : }
1435 :
1436 2392149 : void DeclarationScope::AnalyzePartially(Parser* parser,
1437 3213109 : AstNodeFactory* ast_node_factory) {
1438 : DCHECK(!force_eager_compilation_);
1439 : UnresolvedList new_unresolved_list;
1440 9544344 : if (!IsArrowFunction(function_kind_) &&
1441 3003809 : (!outer_scope_->is_script_scope() ||
1442 1271842 : (preparse_data_builder_ != nullptr &&
1443 635930 : preparse_data_builder_->HasInnerFunctions()))) {
1444 : // Try to resolve unresolved variables for this Scope and migrate those
1445 : // which cannot be resolved inside. It doesn't make sense to try to resolve
1446 : // them in the outer Scopes here, because they are incomplete.
1447 1792697 : Scope::AnalyzePartially(this, ast_node_factory, &new_unresolved_list);
1448 :
1449 : // Migrate function_ to the right Zone.
1450 1792688 : if (function_ != nullptr) {
1451 821007 : function_ = ast_node_factory->CopyVariable(function_);
1452 : }
1453 :
1454 1792682 : SavePreparseData(parser);
1455 : }
1456 :
1457 : #ifdef DEBUG
1458 : if (FLAG_print_scopes) {
1459 : PrintF("Inner function scope:\n");
1460 : Print();
1461 : }
1462 : #endif
1463 :
1464 2392096 : ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
1465 :
1466 : unresolved_list_ = std::move(new_unresolved_list);
1467 2392437 : }
1468 :
1469 : #ifdef DEBUG
1470 : namespace {
1471 :
1472 : const char* Header(ScopeType scope_type, FunctionKind function_kind,
1473 : bool is_declaration_scope) {
1474 : switch (scope_type) {
1475 : case EVAL_SCOPE: return "eval";
1476 : // TODO(adamk): Should we print concise method scopes specially?
1477 : case FUNCTION_SCOPE:
1478 : if (IsGeneratorFunction(function_kind)) return "function*";
1479 : if (IsAsyncFunction(function_kind)) return "async function";
1480 : if (IsArrowFunction(function_kind)) return "arrow";
1481 : return "function";
1482 : case MODULE_SCOPE: return "module";
1483 : case SCRIPT_SCOPE: return "global";
1484 : case CATCH_SCOPE: return "catch";
1485 : case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block";
1486 : case WITH_SCOPE: return "with";
1487 : }
1488 : UNREACHABLE();
1489 : }
1490 :
1491 : void Indent(int n, const char* str) { PrintF("%*s%s", n, "", str); }
1492 :
1493 : void PrintName(const AstRawString* name) {
1494 : PrintF("%.*s", name->length(), name->raw_data());
1495 : }
1496 :
1497 : void PrintLocation(Variable* var) {
1498 : switch (var->location()) {
1499 : case VariableLocation::UNALLOCATED:
1500 : break;
1501 : case VariableLocation::PARAMETER:
1502 : PrintF("parameter[%d]", var->index());
1503 : break;
1504 : case VariableLocation::LOCAL:
1505 : PrintF("local[%d]", var->index());
1506 : break;
1507 : case VariableLocation::CONTEXT:
1508 : PrintF("context[%d]", var->index());
1509 : break;
1510 : case VariableLocation::LOOKUP:
1511 : PrintF("lookup");
1512 : break;
1513 : case VariableLocation::MODULE:
1514 : PrintF("module");
1515 : break;
1516 : }
1517 : }
1518 :
1519 : void PrintVar(int indent, Variable* var) {
1520 : Indent(indent, VariableMode2String(var->mode()));
1521 : PrintF(" ");
1522 : if (var->raw_name()->IsEmpty())
1523 : PrintF(".%p", reinterpret_cast<void*>(var));
1524 : else
1525 : PrintName(var->raw_name());
1526 : PrintF("; // (%p) ", reinterpret_cast<void*>(var));
1527 : PrintLocation(var);
1528 : bool comma = !var->IsUnallocated();
1529 : if (var->has_forced_context_allocation()) {
1530 : if (comma) PrintF(", ");
1531 : PrintF("forced context allocation");
1532 : comma = true;
1533 : }
1534 : if (var->maybe_assigned() == kNotAssigned) {
1535 : if (comma) PrintF(", ");
1536 : PrintF("never assigned");
1537 : comma = true;
1538 : }
1539 : if (var->initialization_flag() == kNeedsInitialization &&
1540 : !var->binding_needs_init()) {
1541 : if (comma) PrintF(", ");
1542 : PrintF("hole initialization elided");
1543 : }
1544 : PrintF("\n");
1545 : }
1546 :
1547 : void PrintMap(int indent, const char* label, VariableMap* map, bool locals,
1548 : Variable* function_var) {
1549 : bool printed_label = false;
1550 : for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
1551 : Variable* var = reinterpret_cast<Variable*>(p->value);
1552 : if (var == function_var) continue;
1553 : bool local = !IsDynamicVariableMode(var->mode());
1554 : if ((locals ? local : !local) &&
1555 : (var->is_used() || !var->IsUnallocated())) {
1556 : if (!printed_label) {
1557 : Indent(indent, label);
1558 : printed_label = true;
1559 : }
1560 : PrintVar(indent, var);
1561 : }
1562 : }
1563 : }
1564 :
1565 : } // anonymous namespace
1566 :
1567 : void DeclarationScope::PrintParameters() {
1568 : PrintF(" (");
1569 : for (int i = 0; i < params_.length(); i++) {
1570 : if (i > 0) PrintF(", ");
1571 : const AstRawString* name = params_[i]->raw_name();
1572 : if (name->IsEmpty()) {
1573 : PrintF(".%p", reinterpret_cast<void*>(params_[i]));
1574 : } else {
1575 : PrintName(name);
1576 : }
1577 : }
1578 : PrintF(")");
1579 : }
1580 :
1581 : void Scope::Print(int n) {
1582 : int n0 = (n > 0 ? n : 0);
1583 : int n1 = n0 + 2; // indentation
1584 :
1585 : // Print header.
1586 : FunctionKind function_kind = is_function_scope()
1587 : ? AsDeclarationScope()->function_kind()
1588 : : kNormalFunction;
1589 : Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
1590 : if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
1591 : PrintF(" ");
1592 : PrintName(scope_name_);
1593 : }
1594 :
1595 : // Print parameters, if any.
1596 : Variable* function = nullptr;
1597 : if (is_function_scope()) {
1598 : AsDeclarationScope()->PrintParameters();
1599 : function = AsDeclarationScope()->function_var();
1600 : }
1601 :
1602 : PrintF(" { // (%p) (%d, %d)\n", reinterpret_cast<void*>(this),
1603 : start_position(), end_position());
1604 : if (is_hidden()) {
1605 : Indent(n1, "// is hidden\n");
1606 : }
1607 :
1608 : // Function name, if any (named function literals, only).
1609 : if (function != nullptr) {
1610 : Indent(n1, "// (local) function name: ");
1611 : PrintName(function->raw_name());
1612 : PrintF("\n");
1613 : }
1614 :
1615 : // Scope info.
1616 : if (is_strict(language_mode())) {
1617 : Indent(n1, "// strict mode scope\n");
1618 : }
1619 : if (IsAsmModule()) Indent(n1, "// scope is an asm module\n");
1620 : if (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval()) {
1621 : Indent(n1, "// scope calls sloppy 'eval'\n");
1622 : }
1623 : if (is_declaration_scope() && AsDeclarationScope()->NeedsHomeObject()) {
1624 : Indent(n1, "// scope needs home object\n");
1625 : }
1626 : if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
1627 : if (is_declaration_scope()) {
1628 : DeclarationScope* scope = AsDeclarationScope();
1629 : if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n");
1630 : if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
1631 : }
1632 : if (num_stack_slots_ > 0) {
1633 : Indent(n1, "// ");
1634 : PrintF("%d stack slots\n", num_stack_slots_);
1635 : }
1636 : if (num_heap_slots_ > 0) {
1637 : Indent(n1, "// ");
1638 : PrintF("%d heap slots\n", num_heap_slots_);
1639 : }
1640 :
1641 : // Print locals.
1642 : if (function != nullptr) {
1643 : Indent(n1, "// function var:\n");
1644 : PrintVar(n1, function);
1645 : }
1646 :
1647 : // Print temporaries.
1648 : {
1649 : bool printed_header = false;
1650 : for (Variable* local : locals_) {
1651 : if (local->mode() != VariableMode::kTemporary) continue;
1652 : if (!printed_header) {
1653 : printed_header = true;
1654 : Indent(n1, "// temporary vars:\n");
1655 : }
1656 : PrintVar(n1, local);
1657 : }
1658 : }
1659 :
1660 : if (variables_.occupancy() > 0) {
1661 : PrintMap(n1, "// local vars:\n", &variables_, true, function);
1662 : PrintMap(n1, "// dynamic vars:\n", &variables_, false, function);
1663 : }
1664 :
1665 : // Print inner scopes (disable by providing negative n).
1666 : if (n >= 0) {
1667 : for (Scope* scope = inner_scope_; scope != nullptr;
1668 : scope = scope->sibling_) {
1669 : PrintF("\n");
1670 : scope->Print(n1);
1671 : }
1672 : }
1673 :
1674 : Indent(n0, "}\n");
1675 : }
1676 :
1677 : void Scope::CheckScopePositions() {
1678 : // Visible leaf scopes must have real positions.
1679 : if (!is_hidden() && inner_scope_ == nullptr) {
1680 : DCHECK_NE(kNoSourcePosition, start_position());
1681 : DCHECK_NE(kNoSourcePosition, end_position());
1682 : }
1683 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1684 : scope->CheckScopePositions();
1685 : }
1686 : }
1687 :
1688 : void Scope::CheckZones() {
1689 : DCHECK(!needs_migration_);
1690 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1691 : if (scope->is_declaration_scope() &&
1692 : scope->AsDeclarationScope()->was_lazily_parsed()) {
1693 : DCHECK_NULL(scope->zone());
1694 : DCHECK_NULL(scope->inner_scope_);
1695 : continue;
1696 : }
1697 : scope->CheckZones();
1698 : }
1699 : }
1700 : #endif // DEBUG
1701 :
1702 808932 : Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
1703 : // Declare a new non-local.
1704 : DCHECK(IsDynamicVariableMode(mode));
1705 808932 : Variable* var = variables_.Declare(zone(), this, name, mode);
1706 : // Allocate it by giving it a dynamic lookup.
1707 : var->AllocateTo(VariableLocation::LOOKUP, -1);
1708 808933 : return var;
1709 : }
1710 :
1711 : // static
1712 : template <Scope::ScopeLookupMode mode>
1713 53342185 : Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
1714 : Scope* outer_scope_end, Scope* entry_point,
1715 : bool force_context_allocation) {
1716 : if (mode == kDeserializedScope) {
1717 2121909 : Variable* var = entry_point->variables_.Lookup(proxy->raw_name());
1718 2121913 : if (var != nullptr) return var;
1719 : }
1720 :
1721 : while (true) {
1722 : DCHECK_IMPLIES(mode == kParsedScope, !scope->is_debug_evaluate_scope_);
1723 : // Short-cut: whenever we find a debug-evaluate scope, just look everything
1724 : // up dynamically. Debug-evaluate doesn't properly create scope info for the
1725 : // lookups it does. It may not have a valid 'this' declaration, and anything
1726 : // accessed through debug-evaluate might invalidly resolve to
1727 : // stack-allocated variables.
1728 : // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for
1729 : // the scopes in which it's evaluating.
1730 2239214 : if (mode == kDeserializedScope &&
1731 2239214 : V8_UNLIKELY(scope->is_debug_evaluate_scope_)) {
1732 11339 : return entry_point->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
1733 : }
1734 :
1735 : // Try to find the variable in this scope.
1736 : Variable* var = mode == kParsedScope ? scope->LookupLocal(proxy->raw_name())
1737 : : scope->LookupInScopeInfo(
1738 2227875 : proxy->raw_name(), entry_point);
1739 :
1740 : // We found a variable and we are done. (Even if there is an 'eval' in this
1741 : // scope which introduces the same variable again, the resulting variable
1742 : // remains the same.)
1743 73581473 : if (var != nullptr) {
1744 51144585 : if (mode == kParsedScope && force_context_allocation &&
1745 : !var->is_dynamic()) {
1746 : var->ForceContextAllocation();
1747 : }
1748 41162601 : return var;
1749 : }
1750 :
1751 32023605 : if (scope->outer_scope_ == outer_scope_end) break;
1752 :
1753 : DCHECK(!scope->is_script_scope());
1754 23583385 : if (V8_UNLIKELY(scope->is_with_scope())) {
1755 : return LookupWith(proxy, scope, outer_scope_end, entry_point,
1756 46987 : force_context_allocation);
1757 : }
1758 42184299 : if (V8_UNLIKELY(scope->is_declaration_scope() &&
1759 : scope->AsDeclarationScope()->calls_sloppy_eval())) {
1760 : return LookupSloppyEval(proxy, scope, outer_scope_end, entry_point,
1761 406567 : force_context_allocation);
1762 : }
1763 :
1764 23129831 : force_context_allocation |= scope->is_function_scope();
1765 : scope = scope->outer_scope_;
1766 : // TODO(verwaest): Separate through AnalyzePartially.
1767 22662947 : if (mode == kParsedScope && !scope->scope_info_.is_null()) {
1768 1782587 : return Lookup<kDeserializedScope>(proxy, scope, outer_scope_end, scope);
1769 : }
1770 : }
1771 :
1772 : // We may just be trying to find all free variables. In that case, don't
1773 : // declare them in the outer scope.
1774 : // TODO(marja): Separate Lookup for preparsed scopes better.
1775 7371362 : if (mode == kParsedScope && !scope->is_script_scope()) {
1776 : return nullptr;
1777 : }
1778 2565580 : if (V8_UNLIKELY(proxy->IsPrivateName())) return nullptr;
1779 :
1780 : // No binding has been found. Declare a variable on the global object.
1781 : return scope->AsDeclarationScope()->DeclareDynamicGlobal(
1782 : proxy->raw_name(), NORMAL_VARIABLE,
1783 3032294 : mode == kDeserializedScope ? entry_point : scope);
1784 : }
1785 :
1786 : template Variable* Scope::Lookup<Scope::kParsedScope>(
1787 : VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
1788 : Scope* entry_point, bool force_context_allocation);
1789 : template Variable* Scope::Lookup<Scope::kDeserializedScope>(
1790 : VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
1791 : Scope* entry_point, bool force_context_allocation);
1792 :
1793 : namespace {
1794 : bool CanBeShadowed(Scope* scope, Variable* var) {
1795 453555 : if (var == nullptr) return false;
1796 :
1797 : // "this" can't be shadowed by "eval"-introduced bindings or by "with" scopes.
1798 : // TODO(wingo): There are other variables in this category; add them.
1799 429815 : return !var->is_this();
1800 : }
1801 : }; // namespace
1802 :
1803 58834 : Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
1804 : Scope* outer_scope_end, Scope* entry_point,
1805 : bool force_context_allocation) {
1806 : DCHECK(scope->is_with_scope());
1807 :
1808 : Variable* var =
1809 46987 : scope->outer_scope_->scope_info_.is_null()
1810 : ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
1811 44924 : nullptr, force_context_allocation)
1812 : : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
1813 91911 : outer_scope_end, entry_point);
1814 :
1815 46989 : if (!CanBeShadowed(scope, var)) return var;
1816 :
1817 : // The current scope is a with scope, so the variable binding can not be
1818 : // statically resolved. However, note that it was necessary to do a lookup
1819 : // in the outer scope anyway, because if a binding exists in an outer
1820 : // scope, the associated variable has to be marked as potentially being
1821 : // accessed from inside of an inner with scope (the property may not be in
1822 : // the 'with' object).
1823 41222 : if (!var->is_dynamic() && var->IsUnallocated()) {
1824 : DCHECK(!scope->already_resolved_);
1825 : var->set_is_used();
1826 : var->ForceContextAllocation();
1827 11847 : if (proxy->is_assigned()) var->set_maybe_assigned();
1828 : }
1829 29124 : if (entry_point != nullptr) entry_point->variables_.Remove(var);
1830 29124 : Scope* target = entry_point == nullptr ? scope : entry_point;
1831 29124 : return target->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
1832 : }
1833 :
1834 406567 : Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
1835 : Scope* outer_scope_end, Scope* entry_point,
1836 : bool force_context_allocation) {
1837 : DCHECK(scope->is_declaration_scope() &&
1838 : scope->AsDeclarationScope()->calls_sloppy_eval());
1839 :
1840 : // If we're compiling eval, it's possible that the outer scope is the first
1841 : // ScopeInfo-backed scope.
1842 406567 : Scope* entry = entry_point == nullptr ? scope->outer_scope_ : entry_point;
1843 : Variable* var =
1844 406567 : scope->outer_scope_->scope_info_.is_null()
1845 : ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
1846 69304 : nullptr, force_context_allocation)
1847 : : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
1848 475871 : outer_scope_end, entry);
1849 406566 : if (!CanBeShadowed(scope, var)) return var;
1850 :
1851 : // A variable binding may have been found in an outer scope, but the current
1852 : // scope makes a sloppy 'eval' call, so the found variable may not be the
1853 : // correct one (the 'eval' may introduce a binding with the same name). In
1854 : // that case, change the lookup result to reflect this situation. Only
1855 : // scopes that can host var bindings (declaration scopes) need be considered
1856 : // here (this excludes block and catch scopes), and variable lookups at
1857 : // script scope are always dynamic.
1858 400081 : if (var->IsGlobalObjectProperty()) {
1859 393532 : Scope* target = entry_point == nullptr ? scope : entry_point;
1860 393532 : return target->NonLocal(proxy->raw_name(), VariableMode::kDynamicGlobal);
1861 : }
1862 :
1863 6549 : if (var->is_dynamic()) return var;
1864 :
1865 : Variable* invalidated = var;
1866 4618 : if (entry_point != nullptr) entry_point->variables_.Remove(invalidated);
1867 :
1868 4618 : Scope* target = entry_point == nullptr ? scope : entry_point;
1869 4618 : var = target->NonLocal(proxy->raw_name(), VariableMode::kDynamicLocal);
1870 : var->set_local_if_not_shadowed(invalidated);
1871 :
1872 4618 : return var;
1873 : }
1874 :
1875 21224327 : bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
1876 : DCHECK(info->script_scope()->is_script_scope());
1877 : DCHECK(!proxy->is_resolved());
1878 21224327 : Variable* var = Lookup<kParsedScope>(proxy, this, nullptr);
1879 21224466 : if (var == nullptr) {
1880 : DCHECK(proxy->IsPrivateName());
1881 : info->pending_error_handler()->ReportMessageAt(
1882 133 : proxy->position(), proxy->position() + 1,
1883 : MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
1884 133 : kSyntaxError);
1885 133 : return false;
1886 : }
1887 : ResolveTo(info, proxy, var);
1888 21224298 : return true;
1889 : }
1890 :
1891 : namespace {
1892 :
1893 : void SetNeedsHoleCheck(Variable* var, VariableProxy* proxy) {
1894 : proxy->set_needs_hole_check();
1895 : var->ForceHoleInitialization();
1896 : }
1897 :
1898 25867481 : void UpdateNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
1899 21269583 : if (var->mode() == VariableMode::kDynamicLocal) {
1900 : // Dynamically introduced variables never need a hole check (since they're
1901 : // VariableMode::kVar bindings, either from var or function declarations),
1902 : // but the variable they shadow might need a hole check, which we want to do
1903 : // if we decide that no shadowing variable was dynamically introoduced.
1904 : DCHECK_EQ(kCreatedInitialized, var->initialization_flag());
1905 4058 : return UpdateNeedsHoleCheck(var->local_if_not_shadowed(), proxy, scope);
1906 : }
1907 :
1908 21265525 : if (var->initialization_flag() == kCreatedInitialized) return;
1909 :
1910 : // It's impossible to eliminate module import hole checks here, because it's
1911 : // unknown at compilation time whether the binding referred to in the
1912 : // exporting module itself requires hole checks.
1913 3666968 : if (var->location() == VariableLocation::MODULE && !var->IsExport()) {
1914 : return SetNeedsHoleCheck(var, proxy);
1915 : }
1916 :
1917 : // Check if the binding really needs an initialization check. The check
1918 : // can be skipped in the following situation: we have a VariableMode::kLet or
1919 : // VariableMode::kConst binding, both the Variable and the VariableProxy have
1920 : // the same declaration scope (i.e. they are both in global code, in the same
1921 : // function or in the same eval code), the VariableProxy is in the source
1922 : // physically located after the initializer of the variable, and that the
1923 : // initializer cannot be skipped due to a nonlinear scope.
1924 : //
1925 : // The condition on the closure scopes is a conservative check for
1926 : // nested functions that access a binding and are called before the
1927 : // binding is initialized:
1928 : // function() { f(); let x = 1; function f() { x = 2; } }
1929 : //
1930 : // The check cannot be skipped on non-linear scopes, namely switch
1931 : // scopes, to ensure tests are done in cases like the following:
1932 : // switch (1) { case 0: let x = 2; case 1: f(x); }
1933 : // The scope of the variable needs to be checked, in case the use is
1934 : // in a sub-block which may be linear.
1935 3663570 : if (var->scope()->GetClosureScope() != scope->GetClosureScope()) {
1936 : return SetNeedsHoleCheck(var, proxy);
1937 : }
1938 :
1939 3117655 : if (var->is_this()) {
1940 : DCHECK(IsDerivedConstructor(scope->GetClosureScope()->function_kind()));
1941 : // TODO(littledan): implement 'this' hole check elimination.
1942 : return SetNeedsHoleCheck(var, proxy);
1943 : }
1944 :
1945 : // We should always have valid source positions.
1946 : DCHECK_NE(var->initializer_position(), kNoSourcePosition);
1947 : DCHECK_NE(proxy->position(), kNoSourcePosition);
1948 :
1949 1868763 : if (var->scope()->is_nonlinear() ||
1950 934328 : var->initializer_position() >= proxy->position()) {
1951 : return SetNeedsHoleCheck(var, proxy);
1952 : }
1953 : }
1954 :
1955 : } // anonymous namespace
1956 :
1957 0 : void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
1958 : #ifdef DEBUG
1959 : if (info->is_native()) {
1960 : // To avoid polluting the global object in native scripts
1961 : // - Variables must not be allocated to the global scope.
1962 : DCHECK_NOT_NULL(outer_scope());
1963 : // - Variables must be bound locally or unallocated.
1964 : if (var->IsGlobalObjectProperty()) {
1965 : // The following variable name may be minified. If so, disable
1966 : // minification in js2c.py for better output.
1967 : Handle<String> name = proxy->raw_name()->string();
1968 : FATAL("Unbound variable: '%s' in native script.",
1969 : name->ToCString().get());
1970 : }
1971 : VariableLocation location = var->location();
1972 : DCHECK(location == VariableLocation::LOCAL ||
1973 : location == VariableLocation::CONTEXT ||
1974 : location == VariableLocation::PARAMETER ||
1975 : location == VariableLocation::UNALLOCATED);
1976 : }
1977 : #endif
1978 :
1979 : DCHECK_NOT_NULL(var);
1980 21265500 : UpdateNeedsHoleCheck(var, proxy, this);
1981 21265602 : proxy->BindTo(var);
1982 0 : }
1983 :
1984 11262765 : bool Scope::ResolveVariablesRecursively(ParseInfo* info) {
1985 : DCHECK(info->script_scope()->is_script_scope());
1986 : // Lazy parsed declaration scopes are already partially analyzed. If there are
1987 : // unresolved references remaining, they just need to be resolved in outer
1988 : // scopes.
1989 10677524 : if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
1990 : DCHECK_EQ(variables_.occupancy(), 0);
1991 14411141 : for (VariableProxy* proxy : unresolved_list_) {
1992 5674528 : Variable* var = Lookup<kParsedScope>(proxy, outer_scope(), nullptr);
1993 5674382 : if (var == nullptr) {
1994 : info->pending_error_handler()->ReportMessageAt(
1995 40 : proxy->position(), proxy->position() + 1,
1996 : MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
1997 40 : kSyntaxError);
1998 : DCHECK(proxy->IsPrivateName());
1999 : return false;
2000 : }
2001 5674342 : if (!var->is_dynamic()) {
2002 : var->set_is_used();
2003 : var->ForceContextAllocation();
2004 4029018 : if (proxy->is_assigned()) var->set_maybe_assigned();
2005 : }
2006 : }
2007 : } else {
2008 : // Resolve unresolved variables for this scope.
2009 27693119 : for (VariableProxy* proxy : unresolved_list_) {
2010 21224441 : if (!ResolveVariable(info, proxy)) return false;
2011 : }
2012 :
2013 : // Resolve unresolved variables for inner scopes.
2014 7010165 : for (Scope* scope = inner_scope_; scope != nullptr;
2015 : scope = scope->sibling_) {
2016 3776018 : if (!scope->ResolveVariablesRecursively(info)) return false;
2017 : }
2018 : }
2019 : return true;
2020 : }
2021 :
2022 72185191 : bool Scope::MustAllocate(Variable* var) {
2023 : DCHECK(var->location() != VariableLocation::MODULE);
2024 : // Give var a read/write use if there is a chance it might be accessed
2025 : // via an eval() call. This is only possible if the variable has a
2026 : // visible name.
2027 57506926 : if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
2028 16439182 : (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
2029 : var->set_is_used();
2030 4088199 : if (inner_scope_calls_eval_) var->set_maybe_assigned();
2031 : }
2032 : DCHECK(!var->has_forced_context_allocation() || var->is_used());
2033 : // Global variables do not need to be allocated.
2034 37925359 : return !var->IsGlobalObjectProperty() && var->is_used();
2035 : }
2036 :
2037 :
2038 22171451 : bool Scope::MustAllocateInContext(Variable* var) {
2039 : // If var is accessed from an inner scope, or if there is a possibility
2040 : // that it might be accessed from the current or an inner scope (through
2041 : // an eval() call or a runtime with lookup), it must be allocated in the
2042 : // context.
2043 : //
2044 : // Temporary variables are always stack-allocated. Catch-bound variables are
2045 : // always context-allocated.
2046 11715073 : if (var->mode() == VariableMode::kTemporary) return false;
2047 10456378 : if (is_catch_scope()) return true;
2048 10359907 : if ((is_script_scope() || is_eval_scope()) &&
2049 : IsLexicalVariableMode(var->mode())) {
2050 : return true;
2051 : }
2052 9695512 : return var->has_forced_context_allocation() || inner_scope_calls_eval_;
2053 : }
2054 :
2055 :
2056 7315679 : void Scope::AllocateStackSlot(Variable* var) {
2057 7315679 : if (is_block_scope()) {
2058 395471 : outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
2059 : } else {
2060 6920208 : var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
2061 : }
2062 6920208 : }
2063 :
2064 :
2065 0 : void Scope::AllocateHeapSlot(Variable* var) {
2066 2290132 : var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
2067 0 : }
2068 :
2069 3238602 : void DeclarationScope::AllocateParameterLocals() {
2070 : DCHECK(is_function_scope());
2071 :
2072 : bool has_mapped_arguments = false;
2073 1619292 : if (arguments_ != nullptr) {
2074 : DCHECK(!is_arrow_scope());
2075 1063309 : if (MustAllocate(arguments_) && !has_arguments_parameter_) {
2076 : // 'arguments' is used and does not refer to a function
2077 : // parameter of the same name. If the arguments object
2078 : // aliases formal parameters, we conservatively allocate
2079 : // them specially in the loop below.
2080 : has_mapped_arguments =
2081 116135 : GetArgumentsType() == CreateArgumentsType::kMappedArguments;
2082 : } else {
2083 : // 'arguments' is unused. Tell the code generator that it does not need to
2084 : // allocate the arguments object by nulling out arguments_.
2085 947192 : arguments_ = nullptr;
2086 : }
2087 : }
2088 :
2089 : // The same parameter may occur multiple times in the parameters_ list.
2090 : // If it does, and if it is not copied into the context object, it must
2091 : // receive the highest parameter index for that parameter; thus iteration
2092 : // order is relevant!
2093 4087072 : for (int i = num_parameters() - 1; i >= 0; --i) {
2094 4935514 : Variable* var = params_[i];
2095 : DCHECK_NOT_NULL(var);
2096 : DCHECK(!has_rest_ || var != rest_parameter());
2097 : DCHECK_EQ(this, var->scope());
2098 2467757 : if (has_mapped_arguments) {
2099 : var->set_is_used();
2100 : var->set_maybe_assigned();
2101 : var->ForceContextAllocation();
2102 : }
2103 2467757 : AllocateParameter(var, i);
2104 : }
2105 1619315 : }
2106 :
2107 3583828 : void DeclarationScope::AllocateParameter(Variable* var, int index) {
2108 3583828 : if (MustAllocate(var)) {
2109 5354447 : if (has_forced_context_allocation_for_parameters() ||
2110 2677225 : MustAllocateInContext(var)) {
2111 : DCHECK(var->IsUnallocated() || var->IsContextSlot());
2112 172760 : if (var->IsUnallocated()) {
2113 : AllocateHeapSlot(var);
2114 : }
2115 : } else {
2116 : DCHECK(var->IsUnallocated() || var->IsParameter());
2117 2504462 : if (var->IsUnallocated()) {
2118 : var->AllocateTo(VariableLocation::PARAMETER, index);
2119 : }
2120 : }
2121 : }
2122 3583835 : }
2123 :
2124 3851338 : void DeclarationScope::AllocateReceiver() {
2125 5470550 : if (!has_this_declaration()) return;
2126 : DCHECK_NOT_NULL(receiver());
2127 : DCHECK_EQ(receiver()->scope(), this);
2128 1116068 : AllocateParameter(receiver(), -1);
2129 : }
2130 :
2131 16510906 : void Scope::AllocateNonParameterLocal(Variable* var) {
2132 : DCHECK(var->scope() == this);
2133 16510906 : if (var->IsUnallocated() && MustAllocate(var)) {
2134 9035800 : if (MustAllocateInContext(var)) {
2135 : AllocateHeapSlot(var);
2136 : DCHECK_IMPLIES(is_catch_scope(),
2137 : var->index() == Context::THROWN_OBJECT_INDEX);
2138 : } else {
2139 6920214 : AllocateStackSlot(var);
2140 : }
2141 : }
2142 16510995 : }
2143 :
2144 3234069 : void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
2145 22952831 : for (Variable* local : locals_) {
2146 16484677 : AllocateNonParameterLocal(local);
2147 : }
2148 :
2149 3234085 : if (is_declaration_scope()) {
2150 2735298 : AsDeclarationScope()->AllocateLocals();
2151 : }
2152 3234060 : }
2153 :
2154 5470527 : void DeclarationScope::AllocateLocals() {
2155 : // For now, function_ must be allocated at the very end. If it gets
2156 : // allocated in the context, it must be the last slot in the context,
2157 : // because of the current ScopeInfo implementation (see
2158 : // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
2159 2735255 : if (function_ != nullptr && MustAllocate(function_)) {
2160 26217 : AllocateNonParameterLocal(function_);
2161 : } else {
2162 2709045 : function_ = nullptr;
2163 : }
2164 :
2165 : DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
2166 : !rest_parameter()->IsUnallocated());
2167 :
2168 2735271 : if (new_target_ != nullptr && !MustAllocate(new_target_)) {
2169 985458 : new_target_ = nullptr;
2170 : }
2171 :
2172 : NullifyRareVariableIf(RareVariable::kThisFunction,
2173 165942 : [=](Variable* var) { return !MustAllocate(var); });
2174 2735273 : }
2175 :
2176 17942 : void ModuleScope::AllocateModuleVariables() {
2177 19073 : for (const auto& it : module()->regular_imports()) {
2178 1131 : Variable* var = LookupLocal(it.first);
2179 1131 : var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
2180 : DCHECK(!var->IsExport());
2181 : }
2182 :
2183 36598 : for (const auto& it : module()->regular_exports()) {
2184 18656 : Variable* var = LookupLocal(it.first);
2185 18656 : var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
2186 : DCHECK(var->IsExport());
2187 : }
2188 8971 : }
2189 :
2190 11557309 : void Scope::AllocateVariablesRecursively() {
2191 : DCHECK(!already_resolved_);
2192 :
2193 : // Don't allocate variables of preparsed scopes.
2194 10677055 : if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
2195 5587906 : return;
2196 : }
2197 :
2198 : // Allocate variables for inner scopes.
2199 7010042 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
2200 3775958 : scope->AllocateVariablesRecursively();
2201 : }
2202 :
2203 : DCHECK(!already_resolved_);
2204 : DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
2205 :
2206 : // Allocate variables for this scope.
2207 : // Parameters must be allocated first, if any.
2208 3234084 : if (is_declaration_scope()) {
2209 2735299 : if (is_function_scope()) {
2210 1619331 : AsDeclarationScope()->AllocateParameterLocals();
2211 : }
2212 2735288 : AsDeclarationScope()->AllocateReceiver();
2213 : }
2214 3234089 : AllocateNonParameterLocalsAndDeclaredGlobals();
2215 :
2216 : // Force allocation of a context for this scope if necessary. For a 'with'
2217 : // scope and for a function scope that makes an 'eval' call we need a context,
2218 : // even if no local variables were statically allocated in the scope.
2219 : // Likewise for modules and function scopes representing asm.js modules.
2220 : // Also force a context, if the scope is stricter than the outer scope.
2221 : bool must_have_context =
2222 9567134 : is_with_scope() || is_module_scope() || IsAsmModule() ||
2223 3137226 : ForceContextForLanguageMode() ||
2224 4848583 : (is_function_scope() && AsDeclarationScope()->calls_sloppy_eval()) ||
2225 365415 : (is_block_scope() && is_declaration_scope() &&
2226 : AsDeclarationScope()->calls_sloppy_eval());
2227 :
2228 : // If we didn't allocate any locals in the local context, then we only
2229 : // need the minimal number of slots if we must have a context.
2230 3234069 : if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
2231 2789095 : num_heap_slots_ = 0;
2232 : }
2233 :
2234 : // Allocation done.
2235 : DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
2236 : }
2237 :
2238 2415046 : void Scope::AllocateScopeInfosRecursively(Isolate* isolate,
2239 1263369 : MaybeHandle<ScopeInfo> outer_scope) {
2240 : DCHECK(scope_info_.is_null());
2241 2415046 : MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
2242 :
2243 2415046 : if (NeedsScopeInfo()) {
2244 1263369 : scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
2245 : // The ScopeInfo chain should mirror the context chain, so we only link to
2246 : // the next outer scope that needs a context.
2247 1263382 : if (NeedsContext()) next_outer_scope = scope_info_;
2248 : }
2249 :
2250 : // Allocate ScopeInfos for inner scopes.
2251 5318907 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
2252 5482737 : if (!scope->is_function_scope() ||
2253 : scope->AsDeclarationScope()->ShouldEagerCompile()) {
2254 839195 : scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
2255 : }
2256 : }
2257 2415076 : }
2258 :
2259 : // static
2260 3151752 : void DeclarationScope::AllocateScopeInfos(ParseInfo* info, Isolate* isolate) {
2261 1575864 : DeclarationScope* scope = info->literal()->scope();
2262 1575864 : if (!scope->scope_info_.is_null()) return; // Allocated by outer function.
2263 :
2264 1575864 : MaybeHandle<ScopeInfo> outer_scope;
2265 1575864 : if (scope->outer_scope_ != nullptr) {
2266 1420126 : outer_scope = scope->outer_scope_->scope_info_;
2267 : }
2268 :
2269 2527506 : scope->AllocateScopeInfosRecursively(isolate, outer_scope);
2270 :
2271 : // The debugger expects all shared function infos to contain a scope info.
2272 : // Since the top-most scope will end up in a shared function info, make sure
2273 : // it has one, even if it doesn't need a scope info.
2274 : // TODO(jochen|yangguo): Remove this requirement.
2275 1575885 : if (scope->scope_info_.is_null()) {
2276 : scope->scope_info_ =
2277 951642 : ScopeInfo::Create(isolate, scope->zone(), scope, outer_scope);
2278 : }
2279 :
2280 : // Ensuring that the outer script scope has a scope info avoids having
2281 : // special case for native contexts vs other contexts.
2282 3151779 : if (info->script_scope() && info->script_scope()->scope_info_.is_null()) {
2283 : info->script_scope()->scope_info_ =
2284 1069768 : handle(ScopeInfo::Empty(isolate), isolate);
2285 : }
2286 : }
2287 :
2288 145 : int Scope::ContextLocalCount() const {
2289 90 : if (num_heap_slots() == 0) return 0;
2290 : Variable* function =
2291 55 : is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
2292 : bool is_function_var_in_context =
2293 55 : function != nullptr && function->IsContextSlot();
2294 55 : return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
2295 55 : (is_function_var_in_context ? 1 : 0);
2296 : }
2297 :
2298 : } // namespace internal
2299 183867 : } // namespace v8
|