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 40192551 : Variable* VariableMap::Declare(Zone* zone, Scope* scope,
39 : const AstRawString* name, VariableMode mode,
40 : VariableKind kind,
41 : InitializationFlag initialization_flag,
42 : MaybeAssignedFlag maybe_assigned_flag,
43 : bool* was_added) {
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 80384916 : ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
49 : ZoneAllocationPolicy(zone));
50 40192365 : *was_added = p->value == nullptr;
51 40192365 : if (*was_added) {
52 : // The variable has not been declared yet -> insert it.
53 : DCHECK_EQ(name, p->key);
54 : Variable* variable = new (zone) Variable(
55 : scope, name, mode, kind, initialization_flag, maybe_assigned_flag);
56 39033339 : p->value = variable;
57 : }
58 40191900 : return reinterpret_cast<Variable*>(p->value);
59 : }
60 :
61 0 : void VariableMap::Remove(Variable* var) {
62 : const AstRawString* name = var->raw_name();
63 3904 : ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->Hash());
64 0 : }
65 :
66 1005835 : void VariableMap::Add(Zone* zone, Variable* var) {
67 : const AstRawString* name = var->raw_name();
68 : Entry* p =
69 1005839 : ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->Hash(),
70 : ZoneAllocationPolicy(zone));
71 : DCHECK_NULL(p->value);
72 : DCHECK_EQ(name, p->key);
73 1005839 : p->value = var;
74 1005839 : }
75 :
76 88795627 : Variable* VariableMap::Lookup(const AstRawString* name) {
77 : Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->Hash());
78 88795627 : if (p != nullptr) {
79 : DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
80 : DCHECK_NOT_NULL(p->value);
81 39017493 : return reinterpret_cast<Variable*>(p->value);
82 : }
83 : return nullptr;
84 : }
85 :
86 : // ----------------------------------------------------------------------------
87 : // Implementation of Scope
88 :
89 2974419 : Scope::Scope(Zone* zone)
90 : : zone_(zone),
91 : outer_scope_(nullptr),
92 : variables_(zone),
93 5948836 : scope_type_(SCRIPT_SCOPE) {
94 : SetDefaults();
95 2974417 : }
96 :
97 12902644 : Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
98 : : zone_(zone),
99 : outer_scope_(outer_scope),
100 : variables_(zone),
101 25805340 : scope_type_(scope_type) {
102 : DCHECK_NE(SCRIPT_SCOPE, scope_type);
103 : SetDefaults();
104 : set_language_mode(outer_scope->language_mode());
105 12902696 : outer_scope_->AddInnerScope(this);
106 12902696 : }
107 :
108 2974420 : DeclarationScope::DeclarationScope(Zone* zone,
109 : AstValueFactory* ast_value_factory)
110 5948835 : : Scope(zone), function_kind_(kNormalFunction), params_(4, zone) {
111 : DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
112 2974415 : SetDefaults();
113 : receiver_ = DeclareDynamicGlobal(ast_value_factory->this_string(),
114 2974419 : THIS_VARIABLE, this);
115 2974419 : }
116 :
117 6822103 : DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
118 : ScopeType scope_type,
119 : FunctionKind function_kind)
120 : : Scope(zone, outer_scope, scope_type),
121 : function_kind_(function_kind),
122 13644254 : params_(4, zone) {
123 : DCHECK_NE(scope_type, SCRIPT_SCOPE);
124 6822151 : SetDefaults();
125 6822139 : }
126 :
127 71720 : ModuleScope::ModuleScope(DeclarationScope* script_scope,
128 : AstValueFactory* avfactory)
129 : : DeclarationScope(avfactory->zone(), script_scope, MODULE_SCOPE, kModule),
130 : module_descriptor_(new (avfactory->zone())
131 143440 : ModuleDescriptor(avfactory->zone())) {
132 : set_language_mode(LanguageMode::kStrict);
133 71720 : DeclareThis(avfactory);
134 71720 : }
135 :
136 0 : ModuleScope::ModuleScope(Isolate* isolate, Handle<ScopeInfo> scope_info,
137 : AstValueFactory* avfactory)
138 : : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info),
139 3263 : module_descriptor_(nullptr) {
140 : set_language_mode(LanguageMode::kStrict);
141 0 : }
142 :
143 1078372 : Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
144 : : zone_(zone),
145 : outer_scope_(nullptr),
146 : variables_(zone),
147 : scope_info_(scope_info),
148 2156745 : scope_type_(scope_type) {
149 : DCHECK(!scope_info.is_null());
150 : SetDefaults();
151 : #ifdef DEBUG
152 : already_resolved_ = true;
153 : #endif
154 1078373 : if (scope_info->CallsSloppyEval()) scope_calls_eval_ = true;
155 2156745 : set_language_mode(scope_info->language_mode());
156 1078373 : num_heap_slots_ = scope_info->ContextLength();
157 : DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
158 : // We don't really need to use the preparsed scope data; this is just to
159 : // shorten the recursion in SetMustUsePreparseData.
160 1078373 : must_use_preparsed_scope_data_ = true;
161 1078373 : }
162 :
163 900849 : DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
164 : Handle<ScopeInfo> scope_info)
165 : : Scope(zone, scope_type, scope_info),
166 1801698 : function_kind_(scope_info->function_kind()),
167 3603396 : params_(0, zone) {
168 : DCHECK_NE(scope_type, SCRIPT_SCOPE);
169 900849 : SetDefaults();
170 900849 : }
171 :
172 5334 : Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
173 : MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
174 : : zone_(zone),
175 : outer_scope_(nullptr),
176 : variables_(zone),
177 : scope_info_(scope_info),
178 10668 : scope_type_(CATCH_SCOPE) {
179 : SetDefaults();
180 : #ifdef DEBUG
181 : already_resolved_ = true;
182 : #endif
183 : // Cache the catch variable, even though it's also available via the
184 : // scope_info, as the parser expects that a catch scope always has the catch
185 : // variable as first and only variable.
186 : bool was_added;
187 : Variable* variable =
188 : Declare(zone, catch_variable_name, VariableMode::kVar, NORMAL_VARIABLE,
189 : kCreatedInitialized, maybe_assigned, &was_added);
190 : DCHECK(was_added);
191 : AllocateHeapSlot(variable);
192 5334 : }
193 :
194 10697392 : void DeclarationScope::SetDefaults() {
195 10697392 : is_declaration_scope_ = true;
196 10697392 : has_simple_parameters_ = true;
197 10697392 : is_asm_module_ = false;
198 10697392 : force_eager_compilation_ = false;
199 10697392 : has_arguments_parameter_ = false;
200 10697392 : scope_uses_super_property_ = false;
201 10697392 : has_checked_syntax_ = false;
202 10697392 : has_this_reference_ = false;
203 : has_this_declaration_ =
204 17183261 : (is_function_scope() && !is_arrow_scope()) || is_module_scope();
205 10697392 : has_rest_ = false;
206 10697392 : receiver_ = nullptr;
207 10697392 : new_target_ = nullptr;
208 10697392 : function_ = nullptr;
209 10697392 : arguments_ = nullptr;
210 10697392 : rare_data_ = nullptr;
211 10697392 : should_eager_compile_ = false;
212 10697392 : was_lazily_parsed_ = false;
213 10697392 : is_skipped_function_ = false;
214 10697392 : preparse_data_builder_ = nullptr;
215 : #ifdef DEBUG
216 : DeclarationScope* outer_declaration_scope =
217 : outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
218 : is_being_lazily_parsed_ =
219 : outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
220 : : false;
221 : #endif
222 10697392 : }
223 :
224 0 : void Scope::SetDefaults() {
225 : #ifdef DEBUG
226 : scope_name_ = nullptr;
227 : already_resolved_ = false;
228 : needs_migration_ = false;
229 : #endif
230 16960820 : inner_scope_ = nullptr;
231 16960820 : sibling_ = nullptr;
232 : unresolved_list_.Clear();
233 :
234 16960820 : start_position_ = kNoSourcePosition;
235 16960820 : end_position_ = kNoSourcePosition;
236 :
237 16960820 : num_stack_slots_ = 0;
238 16960820 : num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
239 :
240 : set_language_mode(LanguageMode::kSloppy);
241 :
242 16960820 : scope_calls_eval_ = false;
243 16960820 : scope_nonlinear_ = false;
244 16960820 : is_hidden_ = false;
245 16960820 : is_debug_evaluate_scope_ = false;
246 :
247 16960820 : inner_scope_calls_eval_ = false;
248 16960820 : force_context_allocation_ = false;
249 16960820 : force_context_allocation_for_parameters_ = false;
250 :
251 16960820 : is_declaration_scope_ = false;
252 :
253 16960820 : must_use_preparsed_scope_data_ = false;
254 0 : }
255 :
256 420773 : bool Scope::HasSimpleParameters() {
257 : DeclarationScope* scope = GetClosureScope();
258 585358 : return !scope->is_function_scope() || scope->has_simple_parameters();
259 : }
260 :
261 717408 : void DeclarationScope::set_should_eager_compile() {
262 2522106 : should_eager_compile_ = !was_lazily_parsed_;
263 717408 : }
264 :
265 5870 : void DeclarationScope::set_is_asm_module() { is_asm_module_ = true; }
266 :
267 1788095 : bool Scope::IsAsmModule() const {
268 7487439 : return is_function_scope() && AsDeclarationScope()->is_asm_module();
269 : }
270 :
271 6335 : bool Scope::ContainsAsmModule() const {
272 6335 : if (IsAsmModule()) return true;
273 :
274 : // Check inner scopes recursively
275 2531 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
276 : // Don't check inner functions which won't be eagerly compiled.
277 4971 : if (!scope->is_function_scope() ||
278 : scope->AsDeclarationScope()->ShouldEagerCompile()) {
279 2108 : if (scope->ContainsAsmModule()) return true;
280 : }
281 : }
282 :
283 : return false;
284 : }
285 :
286 1014547 : Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
287 : ScopeInfo scope_info,
288 : DeclarationScope* script_scope,
289 : AstValueFactory* ast_value_factory,
290 : DeserializationMode deserialization_mode) {
291 : // Reconstruct the outer scope chain from a closure's context chain.
292 : Scope* current_scope = nullptr;
293 : Scope* innermost_scope = nullptr;
294 : Scope* outer_scope = nullptr;
295 2098254 : while (!scope_info.is_null()) {
296 1413882 : if (scope_info->scope_type() == WITH_SCOPE) {
297 14837 : if (scope_info->IsDebugEvaluateScope()) {
298 : outer_scope = new (zone)
299 25478 : DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
300 : outer_scope->set_is_debug_evaluate_scope();
301 : } else {
302 : // For scope analysis, debug-evaluate is equivalent to a with scope.
303 : outer_scope =
304 4196 : new (zone) Scope(zone, WITH_SCOPE, handle(scope_info, isolate));
305 : }
306 :
307 1399046 : } else if (scope_info->scope_type() == SCRIPT_SCOPE) {
308 : // If we reach a script scope, it's the outermost scope. Install the
309 : // scope info of this script context onto the existing script scope to
310 : // avoid nesting script scopes.
311 330177 : if (deserialization_mode == DeserializationMode::kIncludingVariables) {
312 : script_scope->SetScriptScopeInfo(handle(scope_info, isolate));
313 : }
314 : DCHECK(!scope_info->HasOuterScopeInfo());
315 : break;
316 1068869 : } else if (scope_info->scope_type() == FUNCTION_SCOPE) {
317 : outer_scope = new (zone)
318 1698644 : DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info, isolate));
319 849322 : if (scope_info->IsAsmModule()) {
320 : outer_scope->AsDeclarationScope()->set_is_asm_module();
321 : }
322 219547 : } else if (scope_info->scope_type() == EVAL_SCOPE) {
323 : outer_scope = new (zone)
324 52836 : DeclarationScope(zone, EVAL_SCOPE, handle(scope_info, isolate));
325 193130 : } else if (scope_info->scope_type() == BLOCK_SCOPE) {
326 184533 : if (scope_info->is_declaration_scope()) {
327 : outer_scope = new (zone)
328 18214 : DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
329 : } else {
330 : outer_scope =
331 350853 : new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info, isolate));
332 : }
333 8597 : } else if (scope_info->scope_type() == MODULE_SCOPE) {
334 : outer_scope = new (zone)
335 : ModuleScope(isolate, handle(scope_info, isolate), ast_value_factory);
336 : } else {
337 : DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
338 : DCHECK_EQ(scope_info->ContextLocalCount(), 1);
339 : DCHECK_EQ(scope_info->ContextLocalMode(0), VariableMode::kVar);
340 : DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
341 5334 : String name = scope_info->ContextLocalName(0);
342 : MaybeAssignedFlag maybe_assigned =
343 5334 : scope_info->ContextLocalMaybeAssignedFlag(0);
344 : outer_scope = new (zone)
345 : Scope(zone, ast_value_factory->GetString(handle(name, isolate)),
346 16002 : maybe_assigned, handle(scope_info, isolate));
347 : }
348 1083708 : if (deserialization_mode == DeserializationMode::kScopesOnly) {
349 0 : outer_scope->scope_info_ = Handle<ScopeInfo>::null();
350 : }
351 1083708 : if (current_scope != nullptr) {
352 : outer_scope->AddInnerScope(current_scope);
353 : }
354 : current_scope = outer_scope;
355 1083708 : if (innermost_scope == nullptr) innermost_scope = current_scope;
356 1083708 : scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo()
357 1083706 : : ScopeInfo();
358 : }
359 :
360 2029098 : if (deserialization_mode == DeserializationMode::kIncludingVariables &&
361 : script_scope->scope_info_.is_null()) {
362 : Handle<ScriptContextTable> table(
363 2053116 : isolate->native_context()->script_context_table(), isolate);
364 684372 : Handle<Context> first = ScriptContextTable::GetContext(isolate, table, 0);
365 1368744 : Handle<ScopeInfo> scope_info(first->scope_info(), isolate);
366 : script_scope->SetScriptScopeInfo(scope_info);
367 : }
368 :
369 1014549 : if (innermost_scope == nullptr) return script_scope;
370 858432 : script_scope->AddInnerScope(current_scope);
371 858432 : return innermost_scope;
372 : }
373 :
374 147977565 : DeclarationScope* Scope::AsDeclarationScope() {
375 : DCHECK(is_declaration_scope());
376 147977565 : return static_cast<DeclarationScope*>(this);
377 : }
378 :
379 0 : const DeclarationScope* Scope::AsDeclarationScope() const {
380 : DCHECK(is_declaration_scope());
381 0 : return static_cast<const DeclarationScope*>(this);
382 : }
383 :
384 55331 : ModuleScope* Scope::AsModuleScope() {
385 : DCHECK(is_module_scope());
386 55331 : return static_cast<ModuleScope*>(this);
387 : }
388 :
389 0 : const ModuleScope* Scope::AsModuleScope() const {
390 : DCHECK(is_module_scope());
391 0 : return static_cast<const ModuleScope*>(this);
392 : }
393 :
394 11584 : void DeclarationScope::DeclareSloppyBlockFunction(
395 : SloppyBlockFunctionStatement* sloppy_block_function) {
396 : sloppy_block_functions_.Add(sloppy_block_function);
397 11584 : }
398 :
399 5106002 : void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
400 : DCHECK(is_sloppy(language_mode()));
401 : DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
402 : (is_block_scope() && outer_scope()->is_function_scope()));
403 : DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
404 : DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
405 :
406 5106002 : if (sloppy_block_functions_.is_empty()) return;
407 :
408 : // In case of complex parameters the current scope is the body scope and the
409 : // parameters are stored in the outer scope.
410 20498 : Scope* parameter_scope = HasSimpleParameters() ? this : outer_scope_;
411 : DCHECK(parameter_scope->is_function_scope() || is_eval_scope() ||
412 : is_script_scope());
413 :
414 : DeclarationScope* decl_scope = this;
415 11611 : while (decl_scope->is_eval_scope()) {
416 : decl_scope = decl_scope->outer_scope()->GetDeclarationScope();
417 : }
418 : Scope* outer_scope = decl_scope->outer_scope();
419 :
420 : // For each variable which is used as a function declaration in a sloppy
421 : // block,
422 21755 : for (SloppyBlockFunctionStatement* sloppy_block_function :
423 11505 : sloppy_block_functions_) {
424 : const AstRawString* name = sloppy_block_function->name();
425 :
426 : // If the variable wouldn't conflict with a lexical declaration
427 : // or parameter,
428 :
429 : // Check if there's a conflict with a parameter.
430 : Variable* maybe_parameter = parameter_scope->LookupLocal(name);
431 14290 : if (maybe_parameter != nullptr && maybe_parameter->is_parameter()) {
432 : continue;
433 : }
434 :
435 : // Check if there's a conflict with a lexical declaration
436 : Scope* query_scope = sloppy_block_function->scope()->outer_scope();
437 : Variable* var = nullptr;
438 : bool should_hoist = true;
439 :
440 : // It is not sufficient to just do a Lookup on query_scope: for
441 : // example, that does not prevent hoisting of the function in
442 : // `{ let e; try {} catch (e) { function e(){} } }`
443 : do {
444 16198 : var = query_scope->LookupInScopeOrScopeInfo(name);
445 19465 : if (var != nullptr && IsLexicalVariableMode(var->mode())) {
446 : should_hoist = false;
447 : break;
448 : }
449 : query_scope = query_scope->outer_scope();
450 14792 : } while (query_scope != outer_scope);
451 :
452 11312 : if (!should_hoist) continue;
453 :
454 9906 : if (factory) {
455 : DCHECK(!is_being_lazily_parsed_);
456 : int pos = sloppy_block_function->position();
457 7480 : bool ok = true;
458 : bool was_added;
459 : auto declaration = factory->NewVariableDeclaration(pos);
460 : // Based on the preceding checks, it doesn't matter what we pass as
461 : // sloppy_mode_block_scope_function_redefinition.
462 : Variable* var = DeclareVariable(
463 : declaration, name, pos, VariableMode::kVar, NORMAL_VARIABLE,
464 : Variable::DefaultInitializationFlag(VariableMode::kVar), &was_added,
465 7480 : nullptr, &ok);
466 : DCHECK(ok);
467 : VariableProxy* source =
468 : factory->NewVariableProxy(sloppy_block_function->var());
469 : VariableProxy* target = factory->NewVariableProxy(var);
470 7481 : Assignment* assignment = factory->NewAssignment(
471 7481 : sloppy_block_function->init(), target, source, pos);
472 : assignment->set_lookup_hoisting_mode(LookupHoistingMode::kLegacySloppy);
473 : Statement* statement = factory->NewExpressionStatement(assignment, pos);
474 : sloppy_block_function->set_statement(statement);
475 : } else {
476 : DCHECK(is_being_lazily_parsed_);
477 : bool was_added;
478 2426 : Variable* var = DeclareVariableName(name, VariableMode::kVar, &was_added);
479 2426 : if (sloppy_block_function->init() == Token::ASSIGN)
480 : var->set_maybe_assigned();
481 : }
482 : }
483 : }
484 :
485 1804696 : bool DeclarationScope::Analyze(ParseInfo* info) {
486 : RuntimeCallTimerScope runtimeTimer(
487 : info->runtime_call_stats(),
488 : info->on_background_thread()
489 : ? RuntimeCallCounterId::kCompileBackgroundScopeAnalysis
490 1804696 : : RuntimeCallCounterId::kCompileScopeAnalysis);
491 : DCHECK_NOT_NULL(info->literal());
492 : DeclarationScope* scope = info->literal()->scope();
493 :
494 : base::Optional<AllowHandleDereference> allow_deref;
495 : if (!info->maybe_outer_scope_info().is_null()) {
496 : // Allow dereferences to the scope info if there is one.
497 : allow_deref.emplace();
498 : }
499 :
500 2656237 : if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
501 725536 : AstNodeFactory factory(info->ast_value_factory(), info->zone());
502 725536 : scope->HoistSloppyBlockFunctions(&factory);
503 : }
504 :
505 : // We are compiling one of four cases:
506 : // 1) top-level code,
507 : // 2) a function/eval/module on the top-level
508 : // 3) a function/eval in a scope that was already resolved.
509 : DCHECK(scope->is_script_scope() || scope->outer_scope()->is_script_scope() ||
510 : scope->outer_scope()->already_resolved_);
511 :
512 : // The outer scope is never lazy.
513 : scope->set_should_eager_compile();
514 :
515 1804698 : if (scope->must_use_preparsed_scope_data_) {
516 : DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
517 : allow_deref.emplace();
518 36471 : info->consumed_preparse_data()->RestoreScopeAllocationData(scope);
519 : }
520 :
521 1804698 : if (!scope->AllocateVariables(info)) return false;
522 :
523 : #ifdef DEBUG
524 : if (info->is_native() ? FLAG_print_builtin_scopes : FLAG_print_scopes) {
525 : PrintF("Global scope:\n");
526 : scope->Print();
527 : }
528 : scope->CheckScopePositions();
529 : scope->CheckZones();
530 : #endif
531 :
532 1804529 : return true;
533 : }
534 :
535 5264578 : void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
536 : DCHECK(has_this_declaration());
537 :
538 5264578 : bool derived_constructor = IsDerivedConstructor(function_kind_);
539 :
540 : receiver_ = new (zone())
541 : Variable(this, ast_value_factory->this_string(),
542 : derived_constructor ? VariableMode::kConst : VariableMode::kVar,
543 : THIS_VARIABLE,
544 : derived_constructor ? kNeedsInitialization : kCreatedInitialized,
545 10529168 : kNotAssigned);
546 5264584 : }
547 :
548 4121273 : void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
549 : DCHECK(is_function_scope());
550 : DCHECK(!is_arrow_scope());
551 :
552 : // Declare 'arguments' variable which exists in all non arrow functions. Note
553 : // that it might never be accessed, in which case it won't be allocated during
554 : // variable allocation.
555 : bool was_added;
556 : arguments_ =
557 4121273 : Declare(zone(), ast_value_factory->arguments_string(), VariableMode::kVar,
558 4121295 : NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
559 4124056 : if (!was_added && IsLexicalVariableMode(arguments_->mode())) {
560 : // Check if there's lexically declared variable named arguments to avoid
561 : // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
562 622 : arguments_ = nullptr;
563 : }
564 4121295 : }
565 :
566 4554179 : void DeclarationScope::DeclareDefaultFunctionVariables(
567 : AstValueFactory* ast_value_factory) {
568 : DCHECK(is_function_scope());
569 : DCHECK(!is_arrow_scope());
570 :
571 4554179 : DeclareThis(ast_value_factory);
572 : bool was_added;
573 4554177 : new_target_ = Declare(zone(), ast_value_factory->new_target_string(),
574 : VariableMode::kConst, NORMAL_VARIABLE,
575 4554186 : kCreatedInitialized, kNotAssigned, &was_added);
576 : DCHECK(was_added);
577 :
578 16705815 : if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
579 : IsAccessorFunction(function_kind_)) {
580 : EnsureRareData()->this_function = Declare(
581 : zone(), ast_value_factory->this_function_string(), VariableMode::kConst,
582 938694 : NORMAL_VARIABLE, kCreatedInitialized, kNotAssigned, &was_added);
583 : DCHECK(was_added);
584 : }
585 4554187 : }
586 :
587 1006733 : Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name,
588 : Scope* cache) {
589 : DCHECK(is_function_scope());
590 : DCHECK_NULL(function_);
591 1006733 : if (cache == nullptr) cache = this;
592 : DCHECK_NULL(cache->variables_.Lookup(name));
593 : VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
594 1006733 : : NORMAL_VARIABLE;
595 : function_ = new (zone())
596 2013470 : Variable(this, name, VariableMode::kConst, kind, kCreatedInitialized);
597 1006735 : if (calls_sloppy_eval()) {
598 900 : cache->NonLocal(name, VariableMode::kDynamic);
599 : } else {
600 1005835 : cache->variables_.Add(zone(), function_);
601 : }
602 1006739 : return function_;
603 : }
604 :
605 142965 : Variable* DeclarationScope::DeclareGeneratorObjectVar(
606 : const AstRawString* name) {
607 : DCHECK(is_function_scope() || is_module_scope());
608 : DCHECK_NULL(generator_object_var());
609 :
610 : Variable* result = EnsureRareData()->generator_object =
611 142965 : NewTemporary(name, kNotAssigned);
612 : result->set_is_used();
613 142965 : return result;
614 : }
615 :
616 5214143 : Scope* Scope::FinalizeBlockScope() {
617 : DCHECK(is_block_scope());
618 : #ifdef DEBUG
619 : DCHECK_NE(sibling_, this);
620 : #endif
621 :
622 14862403 : if (variables_.occupancy() > 0 ||
623 69872 : (is_declaration_scope() && AsDeclarationScope()->calls_sloppy_eval())) {
624 : return this;
625 : }
626 :
627 : // Remove this scope from outer scope.
628 : outer_scope()->RemoveInnerScope(this);
629 :
630 : // Reparent inner scopes.
631 4431702 : if (inner_scope_ != nullptr) {
632 : Scope* scope = inner_scope_;
633 557275 : scope->outer_scope_ = outer_scope();
634 646975 : while (scope->sibling_ != nullptr) {
635 : scope = scope->sibling_;
636 44850 : scope->outer_scope_ = outer_scope();
637 : }
638 557275 : scope->sibling_ = outer_scope()->inner_scope_;
639 557275 : outer_scope()->inner_scope_ = inner_scope_;
640 557275 : inner_scope_ = nullptr;
641 : }
642 :
643 : // Move unresolved variables
644 4431702 : if (!unresolved_list_.is_empty()) {
645 : outer_scope()->unresolved_list_.Prepend(std::move(unresolved_list_));
646 : unresolved_list_.Clear();
647 : }
648 :
649 4431702 : if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
650 :
651 : // No need to propagate scope_calls_eval_, since if it was relevant to
652 : // this scope we would have had to bail out at the top.
653 : DCHECK(!scope_calls_eval_ || !is_declaration_scope() ||
654 : !is_sloppy(language_mode()));
655 :
656 : // This block does not need a context.
657 4431702 : num_heap_slots_ = 0;
658 :
659 : // Mark scope as removed by making it its own sibling.
660 : #ifdef DEBUG
661 : sibling_ = this;
662 : #endif
663 :
664 4431702 : return nullptr;
665 : }
666 :
667 0 : void DeclarationScope::AddLocal(Variable* var) {
668 : DCHECK(!already_resolved_);
669 : // Temporaries are only placed in ClosureScopes.
670 : DCHECK_EQ(GetClosureScope(), this);
671 : locals_.Add(var);
672 0 : }
673 :
674 133195 : void Scope::Snapshot::Reparent(DeclarationScope* new_parent) {
675 : DCHECK(!IsCleared());
676 : DCHECK_EQ(new_parent, outer_scope_and_calls_eval_.GetPointer()->inner_scope_);
677 : DCHECK_EQ(new_parent->outer_scope_, outer_scope_and_calls_eval_.GetPointer());
678 : DCHECK_EQ(new_parent, new_parent->GetClosureScope());
679 : DCHECK_NULL(new_parent->inner_scope_);
680 : DCHECK(new_parent->unresolved_list_.is_empty());
681 133195 : Scope* inner_scope = new_parent->sibling_;
682 133195 : if (inner_scope != top_inner_scope_) {
683 3644 : for (; inner_scope->sibling() != top_inner_scope_;
684 : inner_scope = inner_scope->sibling()) {
685 0 : inner_scope->outer_scope_ = new_parent;
686 0 : if (inner_scope->inner_scope_calls_eval_) {
687 0 : new_parent->inner_scope_calls_eval_ = true;
688 : }
689 : DCHECK_NE(inner_scope, new_parent);
690 : }
691 3644 : inner_scope->outer_scope_ = new_parent;
692 3644 : if (inner_scope->inner_scope_calls_eval_) {
693 128 : new_parent->inner_scope_calls_eval_ = true;
694 : }
695 3644 : new_parent->inner_scope_ = new_parent->sibling_;
696 3644 : inner_scope->sibling_ = nullptr;
697 : // Reset the sibling rather than the inner_scope_ since we
698 : // want to keep new_parent there.
699 3644 : new_parent->sibling_ = top_inner_scope_;
700 : }
701 :
702 : Scope* outer_scope_ = outer_scope_and_calls_eval_.GetPointer();
703 : new_parent->unresolved_list_.MoveTail(&outer_scope_->unresolved_list_,
704 : top_unresolved_);
705 :
706 : // Move temporaries allocated for complex parameter initializers.
707 : DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
708 133195 : for (auto it = top_local_; it != outer_closure->locals()->end(); ++it) {
709 12 : Variable* local = *it;
710 : DCHECK_EQ(VariableMode::kTemporary, local->mode());
711 : DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
712 : DCHECK_NE(local->scope(), new_parent);
713 : local->set_scope(new_parent);
714 : }
715 : new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
716 : outer_closure->locals_.Rewind(top_local_);
717 :
718 : // Move eval calls since Snapshot's creation into new_parent.
719 133195 : if (outer_scope_and_calls_eval_->scope_calls_eval_) {
720 419 : new_parent->scope_calls_eval_ = true;
721 419 : new_parent->inner_scope_calls_eval_ = true;
722 : }
723 :
724 : // We are in the arrow function case. The calls eval we may have recorded
725 : // is intended for the inner scope and we should simply restore the
726 : // original "calls eval" flag of the outer scope.
727 : RestoreEvalFlag();
728 : Clear();
729 133195 : }
730 :
731 91 : void Scope::ReplaceOuterScope(Scope* outer) {
732 : DCHECK_NOT_NULL(outer);
733 : DCHECK_NOT_NULL(outer_scope_);
734 : DCHECK(!already_resolved_);
735 91 : outer_scope_->RemoveInnerScope(this);
736 : outer->AddInnerScope(this);
737 : outer_scope_ = outer;
738 91 : }
739 :
740 2495979 : Variable* Scope::LookupInScopeInfo(const AstRawString* name, Scope* cache) {
741 : DCHECK(!scope_info_.is_null());
742 : DCHECK_NULL(cache->variables_.Lookup(name));
743 : DisallowHeapAllocation no_gc;
744 :
745 2495979 : String name_handle = *name->string();
746 : // The Scope is backed up by ScopeInfo. This means it cannot operate in a
747 : // heap-independent mode, and all strings must be internalized immediately. So
748 : // it's ok to get the Handle<String> here.
749 : bool found = false;
750 :
751 : VariableLocation location;
752 : int index;
753 : VariableMode mode;
754 : InitializationFlag init_flag;
755 : MaybeAssignedFlag maybe_assigned_flag;
756 :
757 : {
758 : location = VariableLocation::CONTEXT;
759 : index = ScopeInfo::ContextSlotIndex(*scope_info_, name_handle, &mode,
760 2495979 : &init_flag, &maybe_assigned_flag);
761 2495982 : found = index >= 0;
762 : }
763 :
764 2495982 : if (!found && is_module_scope()) {
765 : location = VariableLocation::MODULE;
766 3982 : index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
767 1991 : &maybe_assigned_flag);
768 1991 : found = index != 0;
769 : }
770 :
771 2495982 : if (!found) {
772 2033368 : index = scope_info_->FunctionContextSlotIndex(name_handle);
773 2033368 : if (index < 0) return nullptr; // Nowhere found.
774 1040 : Variable* var = AsDeclarationScope()->DeclareFunctionVar(name, cache);
775 : DCHECK_EQ(VariableMode::kConst, var->mode());
776 : var->AllocateTo(VariableLocation::CONTEXT, index);
777 1040 : return cache->variables_.Lookup(name);
778 : }
779 :
780 : if (!is_module_scope()) {
781 : DCHECK_NE(index, scope_info_->ReceiverContextSlotIndex());
782 : }
783 :
784 : bool was_added;
785 : Variable* var =
786 462614 : cache->variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE,
787 462614 : init_flag, maybe_assigned_flag, &was_added);
788 : DCHECK(was_added);
789 : var->AllocateTo(location, index);
790 462615 : return var;
791 : }
792 :
793 2923060 : Variable* DeclarationScope::DeclareParameter(const AstRawString* name,
794 : VariableMode mode,
795 : bool is_optional, bool is_rest,
796 : AstValueFactory* ast_value_factory,
797 : int position) {
798 : DCHECK(!already_resolved_);
799 : DCHECK(is_function_scope() || is_module_scope());
800 : DCHECK(!has_rest_);
801 : DCHECK(!is_optional || !is_rest);
802 : DCHECK(!is_being_lazily_parsed_);
803 : DCHECK(!was_lazily_parsed_);
804 : Variable* var;
805 2923060 : if (mode == VariableMode::kTemporary) {
806 219700 : var = NewTemporary(name);
807 : } else {
808 2813212 : var = LookupLocal(name);
809 : DCHECK_EQ(mode, VariableMode::kVar);
810 : DCHECK(var->is_parameter());
811 : }
812 2923062 : has_rest_ = is_rest;
813 2923062 : var->set_initializer_position(position);
814 2923062 : params_.Add(var, zone());
815 2923056 : if (!is_rest) ++num_parameters_;
816 2923056 : if (name == ast_value_factory->arguments_string()) {
817 1454 : has_arguments_parameter_ = true;
818 : }
819 : // Params are automatically marked as used to make sure that the debugger and
820 : // function.arguments sees them.
821 : // TODO(verwaest): Reevaluate whether we always need to do this, since
822 : // strict-mode function.arguments does not make the arguments available.
823 2923056 : var->set_is_used();
824 2923056 : return var;
825 : }
826 :
827 3974957 : void DeclarationScope::RecordParameter(bool is_rest) {
828 : DCHECK(!already_resolved_);
829 : DCHECK(is_function_scope() || is_module_scope());
830 : DCHECK(is_being_lazily_parsed_);
831 : DCHECK(!has_rest_);
832 3974957 : has_rest_ = is_rest;
833 3974957 : if (!is_rest) ++num_parameters_;
834 3974957 : }
835 :
836 24070249 : Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
837 : VariableKind kind, bool* was_added,
838 : InitializationFlag init_flag) {
839 : DCHECK(!already_resolved_);
840 : // This function handles VariableMode::kVar, VariableMode::kLet, and
841 : // VariableMode::kConst modes. VariableMode::kDynamic variables are
842 : // introduced during variable allocation, and VariableMode::kTemporary
843 : // variables are allocated via NewTemporary().
844 : DCHECK(IsDeclaredVariableMode(mode));
845 : DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
846 : mode == VariableMode::kVar || mode == VariableMode::kLet ||
847 : mode == VariableMode::kConst);
848 : DCHECK(!GetDeclarationScope()->was_lazily_parsed());
849 : Variable* var =
850 : Declare(zone(), name, mode, kind, init_flag, kNotAssigned, was_added);
851 :
852 : // Pessimistically assume that top-level variables will be assigned and used.
853 : //
854 : // Top-level variables in a script can be accessed by other scripts or even
855 : // become global properties. While this does not apply to top-level variables
856 : // in a module (assuming they are not exported), we must still mark these as
857 : // assigned because they might be accessed by a lazily parsed top-level
858 : // function, which, for efficiency, we preparse without variable tracking.
859 24069931 : if (is_script_scope() || is_module_scope()) {
860 4124731 : if (mode != VariableMode::kConst) var->set_maybe_assigned();
861 : var->set_is_used();
862 : }
863 :
864 24069931 : return var;
865 : }
866 :
867 15780866 : Variable* Scope::DeclareVariable(
868 : Declaration* declaration, const AstRawString* name, int pos,
869 : VariableMode mode, VariableKind kind, InitializationFlag init,
870 : bool* was_added, bool* sloppy_mode_block_scope_function_redefinition,
871 : bool* ok) {
872 : DCHECK(IsDeclaredVariableMode(mode));
873 : DCHECK(!already_resolved_);
874 : DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
875 : DCHECK(!GetDeclarationScope()->was_lazily_parsed());
876 :
877 29802417 : if (mode == VariableMode::kVar && !is_declaration_scope()) {
878 805618 : return GetDeclarationScope()->DeclareVariable(
879 : declaration, name, pos, mode, kind, init, was_added,
880 402809 : sloppy_mode_block_scope_function_redefinition, ok);
881 : }
882 : DCHECK(!is_catch_scope());
883 : DCHECK(!is_with_scope());
884 : DCHECK(is_declaration_scope() ||
885 : (IsLexicalVariableMode(mode) && is_block_scope()));
886 :
887 : DCHECK_NOT_NULL(name);
888 :
889 : Variable* var = LookupLocal(name);
890 : // Declare the variable in the declaration scope.
891 15378061 : *was_added = var == nullptr;
892 15378061 : if (V8_LIKELY(*was_added)) {
893 14574449 : if (V8_UNLIKELY(is_eval_scope() && is_sloppy(language_mode()) &&
894 : mode == VariableMode::kVar)) {
895 : // In a var binding in a sloppy direct eval, pollute the enclosing scope
896 : // with this new binding by doing the following:
897 : // The proxy is bound to a lookup variable to force a dynamic declaration
898 : // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
899 : DCHECK_EQ(NORMAL_VARIABLE, kind);
900 307410 : var = NonLocal(name, VariableMode::kDynamic);
901 : // Mark the var as used in case anyone outside the eval wants to use it.
902 : var->set_is_used();
903 : } else {
904 : // Declare the name.
905 13455588 : var = DeclareLocal(name, mode, kind, was_added, init);
906 : DCHECK(*was_added);
907 : }
908 : } else {
909 : var->set_maybe_assigned();
910 3179848 : if (V8_UNLIKELY(IsLexicalVariableMode(mode) ||
911 : IsLexicalVariableMode(var->mode()))) {
912 : // The name was declared in this scope before; check for conflicting
913 : // re-declarations. We have a conflict if either of the declarations is
914 : // not a var (in script scope, we also have to ignore legacy const for
915 : // compatibility). There is similar code in runtime.cc in the Declare
916 : // functions. The function CheckConflictingVarDeclarations checks for
917 : // var and let bindings from different scopes whereas this is a check
918 : // for conflicting declarations within the same scope. This check also
919 : // covers the special case
920 : //
921 : // function () { let x; { var x; } }
922 : //
923 : // because the var declaration is hoisted to the function scope where
924 : // 'x' is already bound.
925 : //
926 : // In harmony we treat re-declarations as early errors. See ES5 16 for a
927 : // definition of early errors.
928 : //
929 : // Allow duplicate function decls for web compat, see bug 4693.
930 64438 : *ok = var->is_sloppy_block_function() &&
931 64438 : kind == SLOPPY_BLOCK_FUNCTION_VARIABLE;
932 64438 : *sloppy_mode_block_scope_function_redefinition = *ok;
933 : }
934 : }
935 : DCHECK_NOT_NULL(var);
936 :
937 : // We add a declaration node for every declaration. The compiler
938 : // will only generate code if necessary. In particular, declarations
939 : // for inner local variables that do not represent functions won't
940 : // result in any generated code.
941 : //
942 : // This will lead to multiple declaration nodes for the
943 : // same variable if it is declared several times. This is not a
944 : // semantic issue, but it may be a performance issue since it may
945 : // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
946 : decls_.Add(declaration);
947 : declaration->set_var(var);
948 15377849 : return var;
949 : }
950 :
951 11070214 : Variable* Scope::DeclareVariableName(const AstRawString* name,
952 : VariableMode mode, bool* was_added,
953 : VariableKind kind) {
954 : DCHECK(IsDeclaredVariableMode(mode));
955 : DCHECK(!already_resolved_);
956 : DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
957 :
958 20710273 : if (mode == VariableMode::kVar && !is_declaration_scope()) {
959 1130988 : return GetDeclarationScope()->DeclareVariableName(name, mode, was_added,
960 565494 : kind);
961 : }
962 : DCHECK(!is_with_scope());
963 : DCHECK(!is_eval_scope());
964 : DCHECK(is_declaration_scope() || IsLexicalVariableMode(mode));
965 : DCHECK(scope_info_.is_null());
966 :
967 : // Declare the variable in the declaration scope.
968 10504720 : Variable* var = DeclareLocal(name, mode, kind, was_added);
969 10504720 : if (!*was_added) {
970 1736967 : if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(var->mode())) {
971 721 : if (!var->is_sloppy_block_function() ||
972 : kind != SLOPPY_BLOCK_FUNCTION_VARIABLE) {
973 : // Duplicate functions are allowed in the sloppy mode, but if this is
974 : // not a function declaration, it's an error. This is an error PreParser
975 : // hasn't previously detected.
976 : return nullptr;
977 : }
978 : // Sloppy block function redefinition.
979 : }
980 : var->set_maybe_assigned();
981 : }
982 : var->set_is_used();
983 10504105 : return var;
984 : }
985 :
986 368579 : Variable* Scope::DeclareCatchVariableName(const AstRawString* name) {
987 : DCHECK(!already_resolved_);
988 : DCHECK(is_catch_scope());
989 : DCHECK(scope_info_.is_null());
990 :
991 : bool was_added;
992 : Variable* result = Declare(zone(), name, VariableMode::kVar, NORMAL_VARIABLE,
993 : kCreatedInitialized, kNotAssigned, &was_added);
994 : DCHECK(was_added);
995 368584 : return result;
996 : }
997 :
998 50540277 : void Scope::AddUnresolved(VariableProxy* proxy) {
999 : DCHECK(!already_resolved_);
1000 : DCHECK(!proxy->is_resolved());
1001 : unresolved_list_.Add(proxy);
1002 50540277 : }
1003 :
1004 0 : Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
1005 : VariableKind kind,
1006 : Scope* cache) {
1007 : DCHECK(is_script_scope());
1008 : bool was_added;
1009 4947218 : return cache->variables_.Declare(
1010 : zone(), this, name, VariableMode::kDynamicGlobal, kind,
1011 4947218 : kCreatedInitialized, kNotAssigned, &was_added);
1012 : // TODO(neis): Mark variable as maybe-assigned?
1013 : }
1014 :
1015 1289 : bool Scope::RemoveUnresolved(VariableProxy* var) {
1016 1289 : return unresolved_list_.Remove(var);
1017 : }
1018 :
1019 15713 : void Scope::DeleteUnresolved(VariableProxy* var) {
1020 : DCHECK(unresolved_list_.Contains(var));
1021 : var->mark_removed_from_unresolved();
1022 15713 : }
1023 :
1024 1230524 : Variable* Scope::NewTemporary(const AstRawString* name) {
1025 1340374 : return NewTemporary(name, kMaybeAssigned);
1026 : }
1027 :
1028 1483342 : Variable* Scope::NewTemporary(const AstRawString* name,
1029 : MaybeAssignedFlag maybe_assigned) {
1030 : DeclarationScope* scope = GetClosureScope();
1031 : Variable* var = new (zone()) Variable(scope, name, VariableMode::kTemporary,
1032 : NORMAL_VARIABLE, kCreatedInitialized);
1033 : scope->AddLocal(var);
1034 1483339 : if (maybe_assigned == kMaybeAssigned) var->set_maybe_assigned();
1035 1483339 : return var;
1036 : }
1037 :
1038 6587297 : Declaration* DeclarationScope::CheckConflictingVarDeclarations() {
1039 6587297 : if (has_checked_syntax_) return nullptr;
1040 19377814 : for (Declaration* decl : decls_) {
1041 : // Lexical vs lexical conflicts within the same scope have already been
1042 : // captured in Parser::Declare. The only conflicts we still need to check
1043 : // are lexical vs nested var.
1044 25077896 : if (decl->IsVariableDeclaration() &&
1045 12097598 : decl->AsVariableDeclaration()->AsNested() != nullptr) {
1046 935784 : Scope* current = decl->AsVariableDeclaration()->AsNested()->scope();
1047 : DCHECK(decl->var()->mode() == VariableMode::kVar ||
1048 : decl->var()->mode() == VariableMode::kDynamic);
1049 : // Iterate through all scopes until the declaration scope.
1050 : do {
1051 : // There is a conflict if there exists a non-VAR binding.
1052 1356111 : if (current->is_catch_scope()) {
1053 : current = current->outer_scope();
1054 2780 : continue;
1055 : }
1056 : Variable* other_var = current->LookupLocal(decl->var()->raw_name());
1057 1353331 : if (other_var != nullptr) {
1058 : DCHECK(IsLexicalVariableMode(other_var->mode()));
1059 : return decl;
1060 : }
1061 : current = current->outer_scope();
1062 1342982 : } while (current != this);
1063 : }
1064 : }
1065 :
1066 6397516 : if (V8_LIKELY(!is_eval_scope())) return nullptr;
1067 853316 : if (!is_sloppy(language_mode())) return nullptr;
1068 :
1069 : // Var declarations in sloppy eval are hoisted to the first non-eval
1070 : // declaration scope. Check for conflicts between the eval scope that
1071 : // declaration scope.
1072 726224 : Scope* end = this;
1073 726230 : do {
1074 726230 : end = end->outer_scope_->GetDeclarationScope();
1075 : } while (end->is_eval_scope());
1076 726224 : end = end->outer_scope_;
1077 :
1078 1026977 : for (Declaration* decl : decls_) {
1079 300906 : if (IsLexicalVariableMode(decl->var()->mode())) continue;
1080 289441 : Scope* current = outer_scope_;
1081 : // Iterate through all scopes until and including the declaration scope.
1082 : do {
1083 : // There is a conflict if there exists a non-VAR binding up to the
1084 : // declaration scope in which this sloppy-eval runs.
1085 : Variable* other_var =
1086 289648 : current->LookupInScopeOrScopeInfo(decl->var()->raw_name());
1087 290208 : if (other_var != nullptr && IsLexicalVariableMode(other_var->mode())) {
1088 : DCHECK(!current->is_catch_scope());
1089 : return decl;
1090 : }
1091 : current = current->outer_scope();
1092 289495 : } while (current != end);
1093 : }
1094 : return nullptr;
1095 : }
1096 :
1097 84383 : const AstRawString* Scope::FindVariableDeclaredIn(Scope* scope,
1098 : VariableMode mode_limit) {
1099 : const VariableMap& variables = scope->variables_;
1100 873847 : for (ZoneHashMap::Entry* p = variables.Start(); p != nullptr;
1101 : p = variables.Next(p)) {
1102 395059 : const AstRawString* name = static_cast<const AstRawString*>(p->key);
1103 : Variable* var = LookupLocal(name);
1104 396550 : if (var != nullptr && var->mode() <= mode_limit) return name;
1105 : }
1106 : return nullptr;
1107 : }
1108 :
1109 779616 : void DeclarationScope::DeserializeReceiver(AstValueFactory* ast_value_factory) {
1110 779616 : if (is_script_scope()) {
1111 : DCHECK_NOT_NULL(receiver_);
1112 : return;
1113 : }
1114 : DCHECK(has_this_declaration());
1115 638680 : DeclareThis(ast_value_factory);
1116 638680 : if (is_debug_evaluate_scope()) {
1117 12223 : receiver_->AllocateTo(VariableLocation::LOOKUP, -1);
1118 : } else {
1119 1252914 : receiver_->AllocateTo(VariableLocation::CONTEXT,
1120 : scope_info_->ReceiverContextSlotIndex());
1121 : }
1122 : }
1123 :
1124 1804695 : bool DeclarationScope::AllocateVariables(ParseInfo* info) {
1125 : // Module variables must be allocated before variable resolution
1126 : // to ensure that UpdateNeedsHoleCheck() can detect import variables.
1127 1804695 : if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
1128 :
1129 1804695 : if (!ResolveVariablesRecursively(info)) {
1130 : DCHECK(info->pending_error_handler()->has_pending_error());
1131 : return false;
1132 : }
1133 :
1134 : // // Don't allocate variables of preparsed scopes.
1135 1804523 : if (!was_lazily_parsed()) AllocateVariablesRecursively();
1136 :
1137 : return true;
1138 : }
1139 :
1140 4313 : bool Scope::HasThisReference() const {
1141 7870 : if (is_declaration_scope() && AsDeclarationScope()->has_this_reference()) {
1142 : return true;
1143 : }
1144 :
1145 5062 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1146 4426 : if (!scope->is_declaration_scope() ||
1147 : !scope->AsDeclarationScope()->has_this_declaration()) {
1148 2368 : if (scope->HasThisReference()) return true;
1149 : }
1150 : }
1151 :
1152 : return false;
1153 : }
1154 :
1155 4158567 : bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
1156 : const Scope* outer) const {
1157 : // If none of the outer scopes need to decide whether to context allocate
1158 : // specific variables, we can preparse inner functions without unresolved
1159 : // variables. Otherwise we need to find unresolved variables to force context
1160 : // allocation of the matching declarations. We can stop at the outer scope for
1161 : // the parse, since context allocation of those variables is already
1162 : // guaranteed to be correct.
1163 4158825 : for (const Scope* s = this; s != outer; s = s->outer_scope_) {
1164 : // Eval forces context allocation on all outer scopes, so we don't need to
1165 : // look at those scopes. Sloppy eval makes top-level non-lexical variables
1166 : // dynamic, whereas strict-mode requires context allocation.
1167 3116768 : if (s->is_eval_scope()) return is_sloppy(s->language_mode());
1168 : // Catch scopes force context allocation of all variables.
1169 2108574 : if (s->is_catch_scope()) continue;
1170 : // With scopes do not introduce variables that need allocation.
1171 2108574 : if (s->is_with_scope()) continue;
1172 : DCHECK(s->is_module_scope() || s->is_block_scope() ||
1173 : s->is_function_scope());
1174 : return false;
1175 : }
1176 : return true;
1177 : }
1178 :
1179 3602688 : bool DeclarationScope::AllowsLazyCompilation() const {
1180 : // Functions which force eager compilation and class member initializer
1181 : // functions are not lazily compilable.
1182 3602688 : return !force_eager_compilation_ &&
1183 3602688 : !IsClassMembersInitializerFunction(function_kind());
1184 : }
1185 :
1186 2800009 : int Scope::ContextChainLength(Scope* scope) const {
1187 : int n = 0;
1188 4273489 : for (const Scope* s = this; s != scope; s = s->outer_scope_) {
1189 : DCHECK_NOT_NULL(s); // scope must be in the scope chain
1190 736740 : if (s->NeedsContext()) n++;
1191 : }
1192 2800009 : return n;
1193 : }
1194 :
1195 354574 : int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
1196 : int result = 0;
1197 : int length = 0;
1198 :
1199 2540798 : for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
1200 1093112 : if (!s->NeedsContext()) continue;
1201 794580 : length++;
1202 1574365 : if (s->is_declaration_scope() &&
1203 : s->AsDeclarationScope()->calls_sloppy_eval()) {
1204 : result = length;
1205 : }
1206 : }
1207 :
1208 354574 : return result;
1209 : }
1210 :
1211 17384062 : DeclarationScope* Scope::GetDeclarationScope() {
1212 : Scope* scope = this;
1213 24860355 : while (!scope->is_declaration_scope()) {
1214 : scope = scope->outer_scope();
1215 : }
1216 17384062 : return scope->AsDeclarationScope();
1217 : }
1218 :
1219 0 : const DeclarationScope* Scope::GetClosureScope() const {
1220 : const Scope* scope = this;
1221 0 : while (!scope->is_declaration_scope() || scope->is_block_scope()) {
1222 : scope = scope->outer_scope();
1223 : }
1224 0 : return scope->AsDeclarationScope();
1225 : }
1226 :
1227 9504413 : DeclarationScope* Scope::GetClosureScope() {
1228 : Scope* scope = this;
1229 19630893 : while (!scope->is_declaration_scope() || scope->is_block_scope()) {
1230 : scope = scope->outer_scope();
1231 : }
1232 9504413 : return scope->AsDeclarationScope();
1233 : }
1234 :
1235 0 : bool Scope::NeedsScopeInfo() const {
1236 : DCHECK(!already_resolved_);
1237 : DCHECK(GetClosureScope()->ShouldEagerCompile());
1238 : // The debugger expects all functions to have scope infos.
1239 : // TODO(jochen|yangguo): Remove this requirement.
1240 2397073 : if (is_function_scope()) return true;
1241 0 : return NeedsContext();
1242 : }
1243 :
1244 43337 : bool Scope::ShouldBanArguments() {
1245 43337 : return GetReceiverScope()->should_ban_arguments();
1246 : }
1247 :
1248 9006589 : DeclarationScope* Scope::GetReceiverScope() {
1249 : Scope* scope = this;
1250 18754912 : while (!scope->is_declaration_scope() ||
1251 9101312 : (!scope->is_script_scope() &&
1252 : !scope->AsDeclarationScope()->has_this_declaration())) {
1253 : scope = scope->outer_scope();
1254 : }
1255 9006589 : return scope->AsDeclarationScope();
1256 : }
1257 :
1258 2602735 : Scope* Scope::GetOuterScopeWithContext() {
1259 2602735 : Scope* scope = outer_scope_;
1260 3521897 : while (scope && !scope->NeedsContext()) {
1261 : scope = scope->outer_scope();
1262 : }
1263 2602735 : return scope;
1264 : }
1265 :
1266 : namespace {
1267 : bool WasLazilyParsed(Scope* scope) {
1268 21648310 : return scope->is_declaration_scope() &&
1269 : scope->AsDeclarationScope()->was_lazily_parsed();
1270 : }
1271 :
1272 : } // namespace
1273 :
1274 : template <typename FunctionType>
1275 : void Scope::ForEach(FunctionType callback) {
1276 : Scope* scope = this;
1277 : while (true) {
1278 11957099 : Iteration iteration = callback(scope);
1279 : // Try to descend into inner scopes first.
1280 11957144 : if ((iteration == Iteration::kDescend) && scope->inner_scope_ != nullptr) {
1281 : scope = scope->inner_scope_;
1282 : } else {
1283 : // Find the next outer scope with a sibling.
1284 11957144 : while (scope->sibling_ == nullptr) {
1285 5154400 : if (scope == this) return;
1286 2966231 : scope = scope->outer_scope_;
1287 : }
1288 6802744 : if (scope == this) return;
1289 : scope = scope->sibling_;
1290 : }
1291 : }
1292 : }
1293 :
1294 12560 : void Scope::CollectNonLocals(DeclarationScope* max_outer_scope,
1295 : Isolate* isolate, ParseInfo* info,
1296 : Handle<StringSet>* non_locals) {
1297 90636 : this->ForEach([max_outer_scope, isolate, info, non_locals](Scope* scope) {
1298 : // Module variables must be allocated before variable resolution
1299 : // to ensure that UpdateNeedsHoleCheck() can detect import variables.
1300 17039 : if (scope->is_module_scope()) {
1301 228 : scope->AsModuleScope()->AllocateModuleVariables();
1302 : }
1303 :
1304 : // Lazy parsed declaration scopes are already partially analyzed. If there
1305 : // are unresolved references remaining, they just need to be resolved in
1306 : // outer scopes.
1307 17039 : Scope* lookup = WasLazilyParsed(scope) ? scope->outer_scope() : scope;
1308 :
1309 74403 : for (VariableProxy* proxy : scope->unresolved_list_) {
1310 : DCHECK(!proxy->is_resolved());
1311 : Variable* var =
1312 57364 : Lookup<kParsedScope>(proxy, lookup, max_outer_scope->outer_scope());
1313 57364 : if (var == nullptr) {
1314 16233 : *non_locals = StringSet::Add(isolate, *non_locals, proxy->name());
1315 : } else {
1316 : // In this case we need to leave scopes in a way that they can be
1317 : // allocated. If we resolved variables from lazy parsed scopes, we need
1318 : // to context allocate the var.
1319 : scope->ResolveTo(info, proxy, var);
1320 41131 : if (!var->is_dynamic() && lookup != scope)
1321 : var->ForceContextAllocation();
1322 : }
1323 : }
1324 :
1325 : // Clear unresolved_list_ as it's in an inconsistent state.
1326 : scope->unresolved_list_.Clear();
1327 17039 : return Iteration::kDescend;
1328 : });
1329 12560 : }
1330 :
1331 1889597 : void Scope::AnalyzePartially(DeclarationScope* max_outer_scope,
1332 : AstNodeFactory* ast_node_factory,
1333 : UnresolvedList* new_unresolved_list) {
1334 : this->ForEach([max_outer_scope, ast_node_factory,
1335 45709087 : new_unresolved_list](Scope* scope) {
1336 : DCHECK_IMPLIES(scope->is_declaration_scope(),
1337 : !scope->AsDeclarationScope()->was_lazily_parsed());
1338 :
1339 22645578 : for (VariableProxy* proxy = scope->unresolved_list_.first();
1340 25789110 : proxy != nullptr; proxy = proxy->next_unresolved()) {
1341 : DCHECK(!proxy->is_resolved());
1342 : Variable* var =
1343 22645400 : Lookup<kParsedScope>(proxy, scope, max_outer_scope->outer_scope());
1344 22645601 : if (var == nullptr) {
1345 : // Don't copy unresolved references to the script scope, unless it's a
1346 : // reference to a private name or method. In that case keep it so we
1347 : // can fail later.
1348 6926936 : if (!max_outer_scope->outer_scope()->is_script_scope() ||
1349 172576 : proxy->IsPrivateName()) {
1350 : VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
1351 : new_unresolved_list->Add(copy);
1352 : }
1353 : } else {
1354 : var->set_is_used();
1355 15891238 : if (proxy->is_assigned()) var->set_maybe_assigned();
1356 : }
1357 : }
1358 :
1359 : // Clear unresolved_list_ as it's in an inconsistent state.
1360 : scope->unresolved_list_.Clear();
1361 3143710 : return Iteration::kDescend;
1362 : });
1363 1889587 : }
1364 :
1365 12560 : Handle<StringSet> DeclarationScope::CollectNonLocals(
1366 : Isolate* isolate, ParseInfo* info, Handle<StringSet> non_locals) {
1367 12560 : Scope::CollectNonLocals(this, isolate, info, &non_locals);
1368 12560 : return non_locals;
1369 : }
1370 :
1371 2592082 : void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
1372 : bool aborted) {
1373 : DCHECK(is_function_scope());
1374 :
1375 : // Reset all non-trivial members.
1376 : params_.Clear();
1377 : decls_.Clear();
1378 : locals_.Clear();
1379 2592082 : inner_scope_ = nullptr;
1380 : unresolved_list_.Clear();
1381 : sloppy_block_functions_.Clear();
1382 2592082 : rare_data_ = nullptr;
1383 2592082 : has_rest_ = false;
1384 :
1385 : DCHECK_NE(zone_, ast_value_factory->zone());
1386 2592082 : zone_->ReleaseMemory();
1387 :
1388 2592157 : if (aborted) {
1389 : // Prepare scope for use in the outer zone.
1390 48875 : zone_ = ast_value_factory->zone();
1391 48875 : variables_.Reset(ZoneAllocationPolicy(zone_));
1392 97750 : if (!IsArrowFunction(function_kind_)) {
1393 43128 : has_simple_parameters_ = true;
1394 43128 : DeclareDefaultFunctionVariables(ast_value_factory);
1395 : }
1396 : } else {
1397 : // Make sure this scope isn't used for allocation anymore.
1398 2543282 : zone_ = nullptr;
1399 : variables_.Invalidate();
1400 : }
1401 :
1402 : #ifdef DEBUG
1403 : needs_migration_ = false;
1404 : is_being_lazily_parsed_ = false;
1405 : #endif
1406 :
1407 2592157 : was_lazily_parsed_ = !aborted;
1408 2592157 : }
1409 :
1410 279481 : bool Scope::IsSkippableFunctionScope() {
1411 : // Lazy non-arrow function scopes are skippable. Lazy functions are exactly
1412 : // those Scopes which have their own PreparseDataBuilder object. This
1413 : // logic ensures that the scope allocation data is consistent with the
1414 : // skippable function data (both agree on where the lazy function boundaries
1415 : // are).
1416 3423166 : if (!is_function_scope()) return false;
1417 : DeclarationScope* declaration_scope = AsDeclarationScope();
1418 2759974 : return !declaration_scope->is_arrow_scope() &&
1419 : declaration_scope->preparse_data_builder() != nullptr;
1420 : }
1421 :
1422 1889548 : void Scope::SavePreparseData(Parser* parser) {
1423 5175560 : this->ForEach([parser](Scope* scope) {
1424 3143685 : if (scope->IsSkippableFunctionScope()) {
1425 : scope->AsDeclarationScope()->SavePreparseDataForDeclarationScope(parser);
1426 : }
1427 3143680 : return Iteration::kDescend;
1428 : });
1429 1889596 : }
1430 :
1431 0 : void DeclarationScope::SavePreparseDataForDeclarationScope(Parser* parser) {
1432 2031875 : if (preparse_data_builder_ == nullptr) return;
1433 2031878 : preparse_data_builder_->SaveScopeAllocationData(this, parser);
1434 : }
1435 :
1436 2482546 : void DeclarationScope::AnalyzePartially(Parser* parser,
1437 : AstNodeFactory* ast_node_factory) {
1438 : DCHECK(!force_eager_compilation_);
1439 : UnresolvedList new_unresolved_list;
1440 9905992 : if (!IsArrowFunction(function_kind_) &&
1441 3088089 : (!outer_scope_->is_script_scope() ||
1442 1259449 : (preparse_data_builder_ != nullptr &&
1443 629732 : 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 1889608 : Scope::AnalyzePartially(this, ast_node_factory, &new_unresolved_list);
1448 :
1449 : // Migrate function_ to the right Zone.
1450 1889604 : if (function_ != nullptr) {
1451 852953 : function_ = ast_node_factory->CopyVariable(function_);
1452 : }
1453 :
1454 1889599 : 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 2482521 : ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
1465 :
1466 : unresolved_list_ = std::move(new_unresolved_list);
1467 2482613 : }
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 : this->ForEach([](Scope* scope) {
1679 : // Visible leaf scopes must have real positions.
1680 : if (!scope->is_hidden() && scope->inner_scope_ == nullptr) {
1681 : DCHECK_NE(kNoSourcePosition, scope->start_position());
1682 : DCHECK_NE(kNoSourcePosition, scope->end_position());
1683 : }
1684 : return Iteration::kDescend;
1685 : });
1686 : }
1687 :
1688 : void Scope::CheckZones() {
1689 : DCHECK(!needs_migration_);
1690 : this->ForEach([](Scope* scope) {
1691 : if (WasLazilyParsed(scope)) {
1692 : DCHECK_NULL(scope->zone());
1693 : DCHECK_NULL(scope->inner_scope_);
1694 : return Iteration::kContinue;
1695 : }
1696 : return Iteration::kDescend;
1697 : });
1698 : }
1699 : #endif // DEBUG
1700 :
1701 725917 : Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
1702 : // Declare a new non-local.
1703 : DCHECK(IsDynamicVariableMode(mode));
1704 : bool was_added;
1705 : Variable* var =
1706 725917 : variables_.Declare(zone(), this, name, mode, NORMAL_VARIABLE,
1707 725917 : kCreatedInitialized, kNotAssigned, &was_added);
1708 : // Allocate it by giving it a dynamic lookup.
1709 : var->AllocateTo(VariableLocation::LOOKUP, -1);
1710 725917 : return var;
1711 : }
1712 :
1713 : // static
1714 : template <Scope::ScopeLookupMode mode>
1715 43662394 : Variable* Scope::Lookup(VariableProxy* proxy, Scope* scope,
1716 : Scope* outer_scope_end, Scope* entry_point,
1717 : bool force_context_allocation) {
1718 : if (mode == kDeserializedScope) {
1719 2092698 : Variable* var = entry_point->variables_.Lookup(proxy->raw_name());
1720 2092698 : if (var != nullptr) return var;
1721 : }
1722 :
1723 488877 : while (true) {
1724 : DCHECK_IMPLIES(mode == kParsedScope, !scope->is_debug_evaluate_scope_);
1725 : // Short-cut: whenever we find a debug-evaluate scope, just look everything
1726 : // up dynamically. Debug-evaluate doesn't properly create scope info for the
1727 : // lookups it does. It may not have a valid 'this' declaration, and anything
1728 : // accessed through debug-evaluate might invalidly resolve to
1729 : // stack-allocated variables.
1730 : // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for
1731 : // the scopes in which it's evaluating.
1732 2223574 : if (mode == kDeserializedScope &&
1733 2223574 : V8_UNLIKELY(scope->is_debug_evaluate_scope_)) {
1734 10716 : return entry_point->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
1735 : }
1736 :
1737 : // Try to find the variable in this scope.
1738 : Variable* var = mode == kParsedScope ? scope->LookupLocal(proxy->raw_name())
1739 : : scope->LookupInScopeInfo(
1740 2212858 : proxy->raw_name(), entry_point);
1741 :
1742 : // We found a variable and we are done. (Even if there is an 'eval' in this
1743 : // scope which introduces the same variable again, the resulting variable
1744 : // remains the same.)
1745 60982629 : if (var != nullptr) {
1746 39136297 : if (mode == kParsedScope && force_context_allocation &&
1747 : !var->is_dynamic()) {
1748 : var->ForceContextAllocation();
1749 : }
1750 : return var;
1751 : }
1752 :
1753 28629879 : if (scope->outer_scope_ == outer_scope_end) break;
1754 :
1755 : DCHECK(!scope->is_script_scope());
1756 19885271 : if (V8_UNLIKELY(scope->is_with_scope())) {
1757 46207 : return LookupWith(proxy, scope, outer_scope_end, entry_point,
1758 46207 : force_context_allocation);
1759 : }
1760 35431366 : if (V8_UNLIKELY(scope->is_declaration_scope() &&
1761 : scope->AsDeclarationScope()->calls_sloppy_eval())) {
1762 386230 : return LookupSloppyEval(proxy, scope, outer_scope_end, entry_point,
1763 386230 : force_context_allocation);
1764 : }
1765 :
1766 19452834 : force_context_allocation |= scope->is_function_scope();
1767 : scope = scope->outer_scope_;
1768 : // TODO(verwaest): Separate through AnalyzePartially.
1769 18963957 : if (mode == kParsedScope && !scope->scope_info_.is_null()) {
1770 1773278 : return Lookup<kDeserializedScope>(proxy, scope, outer_scope_end, scope);
1771 : }
1772 : }
1773 :
1774 : // We may just be trying to find all free variables. In that case, don't
1775 : // declare them in the outer scope.
1776 : // TODO(marja): Separate Lookup for preparsed scopes better.
1777 7774864 : if (mode == kParsedScope && !scope->is_script_scope()) {
1778 : return nullptr;
1779 : }
1780 1972933 : if (V8_UNLIKELY(proxy->IsPrivateName())) return nullptr;
1781 :
1782 : // No binding has been found. Declare a variable on the global object.
1783 : return scope->AsDeclarationScope()->DeclareDynamicGlobal(
1784 : proxy->raw_name(), NORMAL_VARIABLE,
1785 1972801 : mode == kDeserializedScope ? entry_point : scope);
1786 : }
1787 :
1788 : template Variable* Scope::Lookup<Scope::kParsedScope>(
1789 : VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
1790 : Scope* entry_point, bool force_context_allocation);
1791 : template Variable* Scope::Lookup<Scope::kDeserializedScope>(
1792 : VariableProxy* proxy, Scope* scope, Scope* outer_scope_end,
1793 : Scope* entry_point, bool force_context_allocation);
1794 :
1795 46207 : Variable* Scope::LookupWith(VariableProxy* proxy, Scope* scope,
1796 : Scope* outer_scope_end, Scope* entry_point,
1797 : bool force_context_allocation) {
1798 : DCHECK(scope->is_with_scope());
1799 :
1800 : Variable* var =
1801 46207 : scope->outer_scope_->scope_info_.is_null()
1802 44576 : ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
1803 : nullptr, force_context_allocation)
1804 : : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
1805 90783 : outer_scope_end, entry_point);
1806 :
1807 46207 : if (var == nullptr) return var;
1808 :
1809 : // The current scope is a with scope, so the variable binding can not be
1810 : // statically resolved. However, note that it was necessary to do a lookup
1811 : // in the outer scope anyway, because if a binding exists in an outer
1812 : // scope, the associated variable has to be marked as potentially being
1813 : // accessed from inside of an inner with scope (the property may not be in
1814 : // the 'with' object).
1815 41054 : if (!var->is_dynamic() && var->IsUnallocated()) {
1816 : DCHECK(!scope->already_resolved_);
1817 : var->set_is_used();
1818 : var->ForceContextAllocation();
1819 11849 : if (proxy->is_assigned()) var->set_maybe_assigned();
1820 : }
1821 28960 : if (entry_point != nullptr) entry_point->variables_.Remove(var);
1822 28960 : Scope* target = entry_point == nullptr ? scope : entry_point;
1823 28960 : return target->NonLocal(proxy->raw_name(), VariableMode::kDynamic);
1824 : }
1825 :
1826 386230 : Variable* Scope::LookupSloppyEval(VariableProxy* proxy, Scope* scope,
1827 : Scope* outer_scope_end, Scope* entry_point,
1828 : bool force_context_allocation) {
1829 : DCHECK(scope->is_declaration_scope() &&
1830 : scope->AsDeclarationScope()->calls_sloppy_eval());
1831 :
1832 : // If we're compiling eval, it's possible that the outer scope is the first
1833 : // ScopeInfo-backed scope.
1834 386230 : Scope* entry = entry_point == nullptr ? scope->outer_scope_ : entry_point;
1835 : Variable* var =
1836 386230 : scope->outer_scope_->scope_info_.is_null()
1837 68440 : ? Lookup<kParsedScope>(proxy, scope->outer_scope_, outer_scope_end,
1838 : nullptr, force_context_allocation)
1839 : : Lookup<kDeserializedScope>(proxy, scope->outer_scope_,
1840 454670 : outer_scope_end, entry);
1841 386230 : if (var == nullptr) return var;
1842 :
1843 : // A variable binding may have been found in an outer scope, but the current
1844 : // scope makes a sloppy 'eval' call, so the found variable may not be the
1845 : // correct one (the 'eval' may introduce a binding with the same name). In
1846 : // that case, change the lookup result to reflect this situation. Only
1847 : // scopes that can host var bindings (declaration scopes) need be considered
1848 : // here (this excludes block and catch scopes), and variable lookups at
1849 : // script scope are always dynamic.
1850 379882 : if (var->IsGlobalObjectProperty()) {
1851 373497 : Scope* target = entry_point == nullptr ? scope : entry_point;
1852 373497 : return target->NonLocal(proxy->raw_name(), VariableMode::kDynamicGlobal);
1853 : }
1854 :
1855 6385 : if (var->is_dynamic()) return var;
1856 :
1857 : Variable* invalidated = var;
1858 4434 : if (entry_point != nullptr) entry_point->variables_.Remove(invalidated);
1859 :
1860 4434 : Scope* target = entry_point == nullptr ? scope : entry_point;
1861 4434 : var = target->NonLocal(proxy->raw_name(), VariableMode::kDynamicLocal);
1862 : var->set_local_if_not_shadowed(invalidated);
1863 :
1864 4434 : return var;
1865 : }
1866 :
1867 18761712 : bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
1868 : DCHECK(info->script_scope()->is_script_scope());
1869 : DCHECK(!proxy->is_resolved());
1870 18761712 : Variable* var = Lookup<kParsedScope>(proxy, this, nullptr);
1871 18762058 : if (var == nullptr) {
1872 : DCHECK(proxy->IsPrivateName());
1873 128 : info->pending_error_handler()->ReportMessageAt(
1874 : proxy->position(), proxy->position() + 1,
1875 : MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
1876 128 : kSyntaxError);
1877 128 : return false;
1878 : }
1879 : ResolveTo(info, proxy, var);
1880 18761654 : return true;
1881 : }
1882 :
1883 : namespace {
1884 :
1885 : void SetNeedsHoleCheck(Variable* var, VariableProxy* proxy) {
1886 : proxy->set_needs_hole_check();
1887 : var->ForceHoleInitialization();
1888 : }
1889 :
1890 18802996 : void UpdateNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
1891 18806775 : if (var->mode() == VariableMode::kDynamicLocal) {
1892 : // Dynamically introduced variables never need a hole check (since they're
1893 : // VariableMode::kVar bindings, either from var or function declarations),
1894 : // but the variable they shadow might need a hole check, which we want to do
1895 : // if we decide that no shadowing variable was dynamically introoduced.
1896 : DCHECK_EQ(kCreatedInitialized, var->initialization_flag());
1897 3779 : return UpdateNeedsHoleCheck(var->local_if_not_shadowed(), proxy, scope);
1898 : }
1899 :
1900 18802996 : if (var->initialization_flag() == kCreatedInitialized) return;
1901 :
1902 : // It's impossible to eliminate module import hole checks here, because it's
1903 : // unknown at compilation time whether the binding referred to in the
1904 : // exporting module itself requires hole checks.
1905 1554552 : if (var->location() == VariableLocation::MODULE && !var->IsExport()) {
1906 : return SetNeedsHoleCheck(var, proxy);
1907 : }
1908 :
1909 : // Check if the binding really needs an initialization check. The check
1910 : // can be skipped in the following situation: we have a VariableMode::kLet or
1911 : // VariableMode::kConst binding, both the Variable and the VariableProxy have
1912 : // the same declaration scope (i.e. they are both in global code, in the same
1913 : // function or in the same eval code), the VariableProxy is in the source
1914 : // physically located after the initializer of the variable, and that the
1915 : // initializer cannot be skipped due to a nonlinear scope.
1916 : //
1917 : // The condition on the closure scopes is a conservative check for
1918 : // nested functions that access a binding and are called before the
1919 : // binding is initialized:
1920 : // function() { f(); let x = 1; function f() { x = 2; } }
1921 : //
1922 : // The check cannot be skipped on non-linear scopes, namely switch
1923 : // scopes, to ensure tests are done in cases like the following:
1924 : // switch (1) { case 0: let x = 2; case 1: f(x); }
1925 : // The scope of the variable needs to be checked, in case the use is
1926 : // in a sub-block which may be linear.
1927 1553241 : if (var->scope()->GetClosureScope() != scope->GetClosureScope()) {
1928 : return SetNeedsHoleCheck(var, proxy);
1929 : }
1930 :
1931 : // We should always have valid source positions.
1932 : DCHECK_NE(var->initializer_position(), kNoSourcePosition);
1933 : DCHECK_NE(proxy->position(), kNoSourcePosition);
1934 :
1935 952257 : if (var->scope()->is_nonlinear() ||
1936 : var->initializer_position() >= proxy->position()) {
1937 : return SetNeedsHoleCheck(var, proxy);
1938 : }
1939 : }
1940 :
1941 : } // anonymous namespace
1942 :
1943 0 : void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
1944 : #ifdef DEBUG
1945 : if (info->is_native()) {
1946 : // To avoid polluting the global object in native scripts
1947 : // - Variables must not be allocated to the global scope.
1948 : DCHECK_NOT_NULL(outer_scope());
1949 : // - Variables must be bound locally or unallocated.
1950 : if (var->IsGlobalObjectProperty()) {
1951 : // The following variable name may be minified. If so, disable
1952 : // minification in js2c.py for better output.
1953 : Handle<String> name = proxy->raw_name()->string();
1954 : FATAL("Unbound variable: '%s' in native script.",
1955 : name->ToCString().get());
1956 : }
1957 : VariableLocation location = var->location();
1958 : DCHECK(location == VariableLocation::LOCAL ||
1959 : location == VariableLocation::CONTEXT ||
1960 : location == VariableLocation::PARAMETER ||
1961 : location == VariableLocation::UNALLOCATED);
1962 : }
1963 : #endif
1964 :
1965 : DCHECK_NOT_NULL(var);
1966 18803061 : UpdateNeedsHoleCheck(var, proxy, this);
1967 18802996 : proxy->BindTo(var);
1968 0 : }
1969 :
1970 6579854 : bool Scope::ResolvePreparsedVariable(VariableProxy* proxy, Scope* scope,
1971 : Scope* end) {
1972 : // Resolve the variable in all parsed scopes to force context allocation.
1973 15279594 : for (; scope != end; scope = scope->outer_scope_) {
1974 : Variable* var = scope->LookupLocal(proxy->raw_name());
1975 6596303 : if (var != nullptr) {
1976 : var->set_is_used();
1977 2246433 : if (!var->is_dynamic()) {
1978 : var->ForceContextAllocation();
1979 2244737 : if (proxy->is_assigned()) var->set_maybe_assigned();
1980 : }
1981 : return true;
1982 : }
1983 : }
1984 :
1985 4333400 : if (!proxy->IsPrivateName()) return true;
1986 :
1987 : // If we're resolving a private name, throw an exception of we didn't manage
1988 : // to resolve. In case of eval, also look in all outer scope-info backed
1989 : // scopes except for the script scope. Don't throw an exception if a reference
1990 : // was found.
1991 : Scope* start = scope;
1992 46 : for (; !scope->is_script_scope(); scope = scope->outer_scope_) {
1993 0 : if (scope->LookupInScopeInfo(proxy->raw_name(), start) != nullptr) {
1994 : return true;
1995 : }
1996 : }
1997 :
1998 : return false;
1999 : }
2000 :
2001 5653037 : bool Scope::ResolveVariablesRecursively(ParseInfo* info) {
2002 : DCHECK(info->script_scope()->is_script_scope());
2003 : // Lazy parsed declaration scopes are already partially analyzed. If there are
2004 : // unresolved references remaining, they just need to be resolved in outer
2005 : // scopes.
2006 5653037 : if (WasLazilyParsed(this)) {
2007 : DCHECK_EQ(variables_.occupancy(), 0);
2008 2452222 : Scope* end = info->scope();
2009 : // Resolve in all parsed scopes except for the script scope.
2010 2452217 : if (!end->is_script_scope()) end = end->outer_scope();
2011 :
2012 9031884 : for (VariableProxy* proxy : unresolved_list_) {
2013 6579686 : if (!ResolvePreparsedVariable(proxy, outer_scope(), end)) {
2014 46 : info->pending_error_handler()->ReportMessageAt(
2015 : proxy->position(), proxy->position() + 1,
2016 : MessageTemplate::kInvalidPrivateFieldResolution, proxy->raw_name(),
2017 46 : kSyntaxError);
2018 : DCHECK(proxy->IsPrivateName());
2019 : return false;
2020 : }
2021 : }
2022 : } else {
2023 : // Resolve unresolved variables for this scope.
2024 21962454 : for (VariableProxy* proxy : unresolved_list_) {
2025 18761759 : if (!ResolveVariable(info, proxy)) return false;
2026 : }
2027 :
2028 : // Resolve unresolved variables for inner scopes.
2029 7048878 : for (Scope* scope = inner_scope_; scope != nullptr;
2030 : scope = scope->sibling_) {
2031 3848348 : if (!scope->ResolveVariablesRecursively(info)) return false;
2032 : }
2033 : }
2034 : return true;
2035 : }
2036 :
2037 19019047 : bool Scope::MustAllocate(Variable* var) {
2038 : DCHECK(var->location() != VariableLocation::MODULE);
2039 : // Give var a read/write use if there is a chance it might be accessed
2040 : // via an eval() call. This is only possible if the variable has a
2041 : // visible name.
2042 57016770 : if (!var->raw_name()->IsEmpty() &&
2043 35154003 : (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
2044 : var->set_is_used();
2045 4141236 : if (inner_scope_calls_eval_) var->set_maybe_assigned();
2046 : }
2047 : DCHECK(!var->has_forced_context_allocation() || var->is_used());
2048 : // Global variables do not need to be allocated.
2049 36248094 : return !var->IsGlobalObjectProperty() && var->is_used();
2050 : }
2051 :
2052 :
2053 11213482 : bool Scope::MustAllocateInContext(Variable* var) {
2054 : // If var is accessed from an inner scope, or if there is a possibility
2055 : // that it might be accessed from the current or an inner scope (through
2056 : // an eval() call or a runtime with lookup), it must be allocated in the
2057 : // context.
2058 : //
2059 : // Temporary variables are always stack-allocated. Catch-bound variables are
2060 : // always context-allocated.
2061 11213482 : if (var->mode() == VariableMode::kTemporary) return false;
2062 9967310 : if (is_catch_scope()) return true;
2063 9870648 : if ((is_script_scope() || is_eval_scope()) &&
2064 : IsLexicalVariableMode(var->mode())) {
2065 : return true;
2066 : }
2067 9219019 : return var->has_forced_context_allocation() || inner_scope_calls_eval_;
2068 : }
2069 :
2070 :
2071 0 : void Scope::AllocateStackSlot(Variable* var) {
2072 6760507 : if (is_block_scope()) {
2073 386802 : outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
2074 : } else {
2075 6373705 : var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
2076 : }
2077 0 : }
2078 :
2079 :
2080 : void Scope::AllocateHeapSlot(Variable* var) {
2081 2324446 : var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
2082 : }
2083 :
2084 : void DeclarationScope::AllocateParameterLocals() {
2085 : DCHECK(is_function_scope());
2086 :
2087 : bool has_mapped_arguments = false;
2088 1595297 : if (arguments_ != nullptr) {
2089 : DCHECK(!is_arrow_scope());
2090 1074703 : if (MustAllocate(arguments_) && !has_arguments_parameter_) {
2091 : // 'arguments' is used and does not refer to a function
2092 : // parameter of the same name. If the arguments object
2093 : // aliases formal parameters, we conservatively allocate
2094 : // them specially in the loop below.
2095 : has_mapped_arguments =
2096 115921 : GetArgumentsType() == CreateArgumentsType::kMappedArguments;
2097 : } else {
2098 : // 'arguments' is unused. Tell the code generator that it does not need to
2099 : // allocate the arguments object by nulling out arguments_.
2100 958776 : arguments_ = nullptr;
2101 : }
2102 : }
2103 :
2104 : // The same parameter may occur multiple times in the parameters_ list.
2105 : // If it does, and if it is not copied into the context object, it must
2106 : // receive the highest parameter index for that parameter; thus iteration
2107 : // order is relevant!
2108 4072152 : for (int i = num_parameters() - 1; i >= 0; --i) {
2109 2476861 : Variable* var = params_[i];
2110 : DCHECK_NOT_NULL(var);
2111 : DCHECK(!has_rest_ || var != rest_parameter());
2112 : DCHECK_EQ(this, var->scope());
2113 2476861 : if (has_mapped_arguments) {
2114 : var->set_is_used();
2115 : var->set_maybe_assigned();
2116 : var->ForceContextAllocation();
2117 : }
2118 : AllocateParameter(var, i);
2119 : }
2120 : }
2121 :
2122 : void DeclarationScope::AllocateParameter(Variable* var, int index) {
2123 3602177 : if (!MustAllocate(var)) return;
2124 5363381 : if (has_forced_context_allocation_for_parameters() ||
2125 2681691 : MustAllocateInContext(var)) {
2126 : DCHECK(var->IsUnallocated() || var->IsContextSlot());
2127 163191 : if (var->IsUnallocated()) AllocateHeapSlot(var);
2128 : } else {
2129 : DCHECK(var->IsUnallocated() || var->IsParameter());
2130 2518499 : if (var->IsUnallocated()) {
2131 : var->AllocateTo(VariableLocation::PARAMETER, index);
2132 : }
2133 : }
2134 : }
2135 :
2136 : void DeclarationScope::AllocateReceiver() {
2137 2702876 : if (!has_this_declaration()) return;
2138 : DCHECK_NOT_NULL(receiver());
2139 : DCHECK_EQ(receiver()->scope(), this);
2140 : AllocateParameter(receiver(), -1);
2141 : }
2142 :
2143 15441791 : void Scope::AllocateNonParameterLocal(Variable* var) {
2144 : DCHECK_EQ(var->scope(), this);
2145 15441791 : if (var->IsUnallocated() && MustAllocate(var)) {
2146 8529739 : if (MustAllocateInContext(var)) {
2147 : AllocateHeapSlot(var);
2148 : DCHECK_IMPLIES(is_catch_scope(),
2149 : var->index() == Context::THROWN_OBJECT_INDEX);
2150 : } else {
2151 : AllocateStackSlot(var);
2152 : }
2153 : }
2154 15441818 : }
2155 :
2156 : void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
2157 37240029 : for (Variable* local : locals_) {
2158 15419527 : AllocateNonParameterLocal(local);
2159 : }
2160 :
2161 3200481 : if (is_declaration_scope()) {
2162 : AsDeclarationScope()->AllocateLocals();
2163 : }
2164 : }
2165 :
2166 : void DeclarationScope::AllocateLocals() {
2167 : // For now, function_ must be allocated at the very end. If it gets
2168 : // allocated in the context, it must be the last slot in the context,
2169 : // because of the current ScopeInfo implementation (see
2170 : // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
2171 2702883 : if (function_ != nullptr && MustAllocate(function_)) {
2172 22274 : AllocateNonParameterLocal(function_);
2173 : } else {
2174 2680610 : function_ = nullptr;
2175 : }
2176 :
2177 : DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
2178 : !rest_parameter()->IsUnallocated());
2179 :
2180 2702899 : if (new_target_ != nullptr && !MustAllocate(new_target_)) {
2181 997220 : new_target_ = nullptr;
2182 : }
2183 :
2184 : NullifyRareVariableIf(RareVariable::kThisFunction,
2185 169460 : [=](Variable* var) { return !MustAllocate(var); });
2186 : }
2187 :
2188 9130 : void ModuleScope::AllocateModuleVariables() {
2189 10336 : for (const auto& it : module()->regular_imports()) {
2190 1206 : Variable* var = LookupLocal(it.first);
2191 1206 : var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
2192 : DCHECK(!var->IsExport());
2193 : }
2194 :
2195 27890 : for (const auto& it : module()->regular_exports()) {
2196 18760 : Variable* var = LookupLocal(it.first);
2197 18760 : var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
2198 : DCHECK(var->IsExport());
2199 : }
2200 9130 : }
2201 :
2202 1804521 : void Scope::AllocateVariablesRecursively() {
2203 5652662 : this->ForEach([](Scope* scope) -> Iteration {
2204 : DCHECK(!scope->already_resolved_);
2205 5652662 : if (WasLazilyParsed(scope)) return Iteration::kContinue;
2206 : DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, scope->num_heap_slots_);
2207 :
2208 : // Allocate variables for this scope.
2209 : // Parameters must be allocated first, if any.
2210 3200481 : if (scope->is_declaration_scope()) {
2211 2702882 : if (scope->is_function_scope()) {
2212 : scope->AsDeclarationScope()->AllocateParameterLocals();
2213 : }
2214 : scope->AsDeclarationScope()->AllocateReceiver();
2215 : }
2216 : scope->AllocateNonParameterLocalsAndDeclaredGlobals();
2217 :
2218 : // Force allocation of a context for this scope if necessary. For a 'with'
2219 : // scope and for a function scope that makes an 'eval' call we need a
2220 : // context, even if no local variables were statically allocated in the
2221 : // scope. Likewise for modules and function scopes representing asm.js
2222 : // modules. Also force a context, if the scope is stricter than the outer
2223 : // scope.
2224 : bool must_have_context =
2225 6316790 : scope->is_with_scope() || scope->is_module_scope() ||
2226 3149682 : scope->IsAsmModule() || scope->ForceContextForLanguageMode() ||
2227 1591029 : (scope->is_function_scope() &&
2228 6265098 : scope->AsDeclarationScope()->calls_sloppy_eval()) ||
2229 359413 : (scope->is_block_scope() && scope->is_declaration_scope() &&
2230 : scope->AsDeclarationScope()->calls_sloppy_eval());
2231 :
2232 : // If we didn't allocate any locals in the local context, then we only
2233 : // need the minimal number of slots if we must have a context.
2234 3200488 : if (scope->num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
2235 : !must_have_context) {
2236 2755981 : scope->num_heap_slots_ = 0;
2237 : }
2238 :
2239 : // Allocation done.
2240 : DCHECK(scope->num_heap_slots_ == 0 ||
2241 : scope->num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
2242 : return Iteration::kDescend;
2243 : });
2244 1804528 : }
2245 :
2246 2397073 : void Scope::AllocateScopeInfosRecursively(Isolate* isolate,
2247 : MaybeHandle<ScopeInfo> outer_scope) {
2248 : DCHECK(scope_info_.is_null());
2249 2397073 : MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
2250 :
2251 2397073 : if (NeedsScopeInfo()) {
2252 1255594 : scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
2253 : // The ScopeInfo chain should mirror the context chain, so we only link to
2254 : // the next outer scope that needs a context.
2255 1255595 : if (NeedsContext()) next_outer_scope = scope_info_;
2256 : }
2257 :
2258 : // Allocate ScopeInfos for inner scopes.
2259 5347320 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
2260 5579547 : if (!scope->is_function_scope() ||
2261 : scope->AsDeclarationScope()->ShouldEagerCompile()) {
2262 829356 : scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
2263 : }
2264 : }
2265 2397076 : }
2266 :
2267 : // static
2268 1567720 : void DeclarationScope::AllocateScopeInfos(ParseInfo* info, Isolate* isolate) {
2269 : DeclarationScope* scope = info->literal()->scope();
2270 1567720 : if (!scope->scope_info_.is_null()) return; // Allocated by outer function.
2271 :
2272 1567720 : MaybeHandle<ScopeInfo> outer_scope;
2273 1567720 : if (scope->outer_scope_ != nullptr) {
2274 1414075 : outer_scope = scope->outer_scope_->scope_info_;
2275 : }
2276 :
2277 1567720 : scope->AllocateScopeInfosRecursively(isolate, outer_scope);
2278 :
2279 : // The debugger expects all shared function infos to contain a scope info.
2280 : // Since the top-most scope will end up in a shared function info, make sure
2281 : // it has one, even if it doesn't need a scope info.
2282 : // TODO(jochen|yangguo): Remove this requirement.
2283 1567723 : if (scope->scope_info_.is_null()) {
2284 : scope->scope_info_ =
2285 946094 : ScopeInfo::Create(isolate, scope->zone(), scope, outer_scope);
2286 : }
2287 :
2288 : // Ensuring that the outer script scope has a scope info avoids having
2289 : // special case for native contexts vs other contexts.
2290 3135449 : if (info->script_scope() && info->script_scope()->scope_info_.is_null()) {
2291 : info->script_scope()->scope_info_ =
2292 1058388 : handle(ScopeInfo::Empty(isolate), isolate);
2293 : }
2294 : }
2295 :
2296 90 : int Scope::ContextLocalCount() const {
2297 90 : if (num_heap_slots() == 0) return 0;
2298 : Variable* function =
2299 55 : is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
2300 : bool is_function_var_in_context =
2301 55 : function != nullptr && function->IsContextSlot();
2302 55 : return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
2303 55 : (is_function_var_in_context ? 1 : 0);
2304 : }
2305 :
2306 : } // namespace internal
2307 120216 : } // namespace v8
|