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/bootstrapper.h"
12 : #include "src/counters.h"
13 : #include "src/messages.h"
14 : #include "src/objects-inl.h"
15 : #include "src/objects/module-info.h"
16 : #include "src/objects/scope-info.h"
17 : #include "src/parsing/parse-info.h"
18 : #include "src/parsing/preparsed-scope-data.h"
19 :
20 : namespace v8 {
21 : namespace internal {
22 :
23 : namespace {
24 : void* kDummyPreParserVariable = reinterpret_cast<void*>(0x1);
25 : void* kDummyPreParserLexicalVariable = reinterpret_cast<void*>(0x2);
26 :
27 5035 : bool IsLexical(Variable* variable) {
28 5092 : if (variable == kDummyPreParserLexicalVariable) return true;
29 5078 : if (variable == kDummyPreParserVariable) return false;
30 : return IsLexicalVariableMode(variable->mode());
31 : }
32 :
33 : } // namespace
34 :
35 : // ----------------------------------------------------------------------------
36 : // Implementation of LocalsMap
37 : //
38 : // Note: We are storing the handle locations as key values in the hash map.
39 : // When inserting a new variable via Declare(), we rely on the fact that
40 : // the handle location remains alive for the duration of that variable
41 : // use. Because a Variable holding a handle with the same location exists
42 : // this is ensured.
43 :
44 0 : VariableMap::VariableMap(Zone* zone)
45 0 : : ZoneHashMap(8, ZoneAllocationPolicy(zone)) {}
46 :
47 59272772 : Variable* VariableMap::Declare(Zone* zone, Scope* scope,
48 59272772 : const AstRawString* name, VariableMode mode,
49 : VariableKind kind,
50 : InitializationFlag initialization_flag,
51 : MaybeAssignedFlag maybe_assigned_flag,
52 : bool* added) {
53 : // AstRawStrings are unambiguous, i.e., the same string is always represented
54 : // by the same AstRawString*.
55 : // FIXME(marja): fix the type of Lookup.
56 : Entry* p =
57 : ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
58 118545561 : ZoneAllocationPolicy(zone));
59 59272789 : if (added) *added = p->value == nullptr;
60 59272789 : if (p->value == nullptr) {
61 : // The variable has not been declared yet -> insert it.
62 : DCHECK_EQ(name, p->key);
63 : p->value = new (zone) Variable(scope, name, mode, kind, initialization_flag,
64 59258147 : maybe_assigned_flag);
65 : }
66 59272731 : return reinterpret_cast<Variable*>(p->value);
67 : }
68 :
69 1409420 : Variable* VariableMap::DeclareName(Zone* zone, const AstRawString* name,
70 : VariableMode mode) {
71 : Entry* p =
72 : ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
73 2818840 : ZoneAllocationPolicy(zone));
74 1409420 : if (p->value == nullptr) {
75 : // The variable has not been declared yet -> insert it.
76 : DCHECK_EQ(name, p->key);
77 : p->value =
78 1379070 : mode == VAR ? kDummyPreParserVariable : kDummyPreParserLexicalVariable;
79 : }
80 1409420 : return reinterpret_cast<Variable*>(p->value);
81 : }
82 :
83 29 : void VariableMap::Remove(Variable* var) {
84 29 : const AstRawString* name = var->raw_name();
85 29 : ZoneHashMap::Remove(const_cast<AstRawString*>(name), name->hash());
86 0 : }
87 :
88 873841 : void VariableMap::Add(Zone* zone, Variable* var) {
89 873841 : const AstRawString* name = var->raw_name();
90 : Entry* p =
91 : ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
92 1747690 : ZoneAllocationPolicy(zone));
93 : DCHECK_NULL(p->value);
94 : DCHECK_EQ(name, p->key);
95 873849 : p->value = var;
96 873849 : }
97 :
98 161898190 : Variable* VariableMap::Lookup(const AstRawString* name) {
99 161898190 : Entry* p = ZoneHashMap::Lookup(const_cast<AstRawString*>(name), name->hash());
100 161898200 : if (p != NULL) {
101 : DCHECK(reinterpret_cast<const AstRawString*>(p->key) == name);
102 : DCHECK(p->value != NULL);
103 105094389 : return reinterpret_cast<Variable*>(p->value);
104 : }
105 : return NULL;
106 : }
107 :
108 0 : void SloppyBlockFunctionMap::Delegate::set_statement(Statement* statement) {
109 7902 : if (statement_ != nullptr) {
110 : statement_->set_statement(statement);
111 : }
112 0 : }
113 :
114 0 : SloppyBlockFunctionMap::SloppyBlockFunctionMap(Zone* zone)
115 10807 : : ZoneHashMap(8, ZoneAllocationPolicy(zone)), count_(0) {}
116 :
117 24054 : void SloppyBlockFunctionMap::Declare(Zone* zone, const AstRawString* name,
118 : Scope* scope,
119 : SloppyBlockFunctionStatement* statement) {
120 12027 : auto* delegate = new (zone) Delegate(scope, statement, count_++);
121 : // AstRawStrings are unambiguous, i.e., the same string is always represented
122 : // by the same AstRawString*.
123 : Entry* p =
124 : ZoneHashMap::LookupOrInsert(const_cast<AstRawString*>(name), name->hash(),
125 24054 : ZoneAllocationPolicy(zone));
126 12027 : delegate->set_next(static_cast<SloppyBlockFunctionMap::Delegate*>(p->value));
127 12027 : p->value = delegate;
128 12027 : }
129 :
130 : // ----------------------------------------------------------------------------
131 : // Implementation of Scope
132 :
133 5590110 : Scope::Scope(Zone* zone)
134 : : zone_(zone),
135 : outer_scope_(nullptr),
136 : variables_(zone),
137 11180211 : scope_type_(SCRIPT_SCOPE) {
138 : SetDefaults();
139 5590101 : }
140 :
141 20992343 : Scope::Scope(Zone* zone, Scope* outer_scope, ScopeType scope_type)
142 : : zone_(zone),
143 : outer_scope_(outer_scope),
144 : variables_(zone),
145 41984670 : scope_type_(scope_type) {
146 : DCHECK_NE(SCRIPT_SCOPE, scope_type);
147 : SetDefaults();
148 : set_language_mode(outer_scope->language_mode());
149 : force_context_allocation_ =
150 33182976 : !is_function_scope() && outer_scope->has_forced_context_allocation();
151 20992327 : outer_scope_->AddInnerScope(this);
152 20992327 : }
153 :
154 138202857 : Scope::Snapshot::Snapshot(Scope* scope)
155 : : outer_scope_(scope),
156 : top_inner_scope_(scope->inner_scope_),
157 : top_unresolved_(scope->unresolved_),
158 138202857 : top_local_(scope->GetClosureScope()->locals_.end()),
159 138202857 : top_decl_(scope->GetClosureScope()->decls_.end()),
160 414608571 : outer_scope_calls_eval_(scope->scope_calls_eval_) {
161 : // Reset in order to record eval calls during this Snapshot's lifetime.
162 138202857 : outer_scope_->scope_calls_eval_ = false;
163 138202857 : }
164 :
165 138202718 : Scope::Snapshot::~Snapshot() {
166 : // Restore previous calls_eval bit if needed.
167 138202718 : if (outer_scope_calls_eval_) {
168 453247 : outer_scope_->scope_calls_eval_ = true;
169 : }
170 138202718 : }
171 :
172 5590111 : DeclarationScope::DeclarationScope(Zone* zone,
173 5590125 : AstValueFactory* ast_value_factory)
174 5590111 : : Scope(zone), function_kind_(kNormalFunction), params_(4, zone) {
175 : DCHECK_EQ(scope_type_, SCRIPT_SCOPE);
176 : SetDefaults();
177 :
178 : // Make sure that if we don't find the global 'this', it won't be declared as
179 : // a regular dynamic global by predeclaring it with the right variable kind.
180 5590125 : DeclareDynamicGlobal(ast_value_factory->this_string(), THIS_VARIABLE);
181 5590113 : }
182 :
183 10325866 : DeclarationScope::DeclarationScope(Zone* zone, Scope* outer_scope,
184 : ScopeType scope_type,
185 : FunctionKind function_kind)
186 : : Scope(zone, outer_scope, scope_type),
187 : function_kind_(function_kind),
188 10325866 : params_(4, zone) {
189 : DCHECK_NE(scope_type, SCRIPT_SCOPE);
190 : SetDefaults();
191 20651736 : asm_function_ = outer_scope_->IsAsmModule();
192 10325868 : }
193 :
194 28202 : ModuleScope::ModuleScope(DeclarationScope* script_scope,
195 56404 : AstValueFactory* ast_value_factory)
196 : : DeclarationScope(ast_value_factory->zone(), script_scope, MODULE_SCOPE,
197 28202 : kModule) {
198 : Zone* zone = ast_value_factory->zone();
199 28202 : module_descriptor_ = new (zone) ModuleDescriptor(zone);
200 : set_language_mode(STRICT);
201 28202 : DeclareThis(ast_value_factory);
202 28202 : }
203 :
204 5406 : ModuleScope::ModuleScope(Handle<ScopeInfo> scope_info,
205 11056 : AstValueFactory* avfactory)
206 5406 : : DeclarationScope(avfactory->zone(), MODULE_SCOPE, scope_info) {
207 : Zone* zone = avfactory->zone();
208 : Isolate* isolate = scope_info->GetIsolate();
209 5406 : Handle<ModuleInfo> module_info(scope_info->ModuleDescriptorInfo(), isolate);
210 :
211 : set_language_mode(STRICT);
212 5406 : module_descriptor_ = new (zone) ModuleDescriptor(zone);
213 :
214 : // Deserialize special exports.
215 : Handle<FixedArray> special_exports(module_info->special_exports(), isolate);
216 5406 : for (int i = 0, n = special_exports->length(); i < n; ++i) {
217 : Handle<ModuleInfoEntry> serialized_entry(
218 : ModuleInfoEntry::cast(special_exports->get(i)), isolate);
219 : module_descriptor_->AddSpecialExport(
220 : ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
221 0 : serialized_entry),
222 0 : avfactory->zone());
223 : }
224 :
225 : // Deserialize regular exports.
226 : module_descriptor_->DeserializeRegularExports(isolate, avfactory,
227 5406 : module_info);
228 :
229 : // Deserialize namespace imports.
230 : Handle<FixedArray> namespace_imports(module_info->namespace_imports(),
231 : isolate);
232 5650 : for (int i = 0, n = namespace_imports->length(); i < n; ++i) {
233 : Handle<ModuleInfoEntry> serialized_entry(
234 : ModuleInfoEntry::cast(namespace_imports->get(i)), isolate);
235 : module_descriptor_->AddNamespaceImport(
236 : ModuleDescriptor::Entry::Deserialize(isolate, avfactory,
237 244 : serialized_entry),
238 244 : avfactory->zone());
239 : }
240 :
241 : // Deserialize regular imports.
242 : Handle<FixedArray> regular_imports(module_info->regular_imports(), isolate);
243 8028 : for (int i = 0, n = regular_imports->length(); i < n; ++i) {
244 : Handle<ModuleInfoEntry> serialized_entry(
245 : ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
246 : module_descriptor_->AddRegularImport(ModuleDescriptor::Entry::Deserialize(
247 2622 : isolate, avfactory, serialized_entry));
248 : }
249 5406 : }
250 :
251 3494379 : Scope::Scope(Zone* zone, ScopeType scope_type, Handle<ScopeInfo> scope_info)
252 : : zone_(zone),
253 : outer_scope_(nullptr),
254 : variables_(zone),
255 : scope_info_(scope_info),
256 6988757 : scope_type_(scope_type) {
257 : DCHECK(!scope_info.is_null());
258 : SetDefaults();
259 : #ifdef DEBUG
260 : already_resolved_ = true;
261 : #endif
262 3494378 : if (scope_info->CallsEval()) RecordEvalCall();
263 3494378 : set_language_mode(scope_info->language_mode());
264 3494378 : num_heap_slots_ = scope_info->ContextLength();
265 : DCHECK_LE(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
266 : // We don't really need to use the preparsed scope data; this is just to
267 : // shorten the recursion in SetMustUsePreParsedScopeData.
268 3494378 : must_use_preparsed_scope_data_ = true;
269 3494378 : }
270 :
271 3342985 : DeclarationScope::DeclarationScope(Zone* zone, ScopeType scope_type,
272 : Handle<ScopeInfo> scope_info)
273 : : Scope(zone, scope_type, scope_info),
274 3342984 : function_kind_(scope_info->function_kind()),
275 6685969 : params_(0, zone) {
276 : DCHECK_NE(scope_type, SCRIPT_SCOPE);
277 : SetDefaults();
278 3342984 : }
279 :
280 4694 : Scope::Scope(Zone* zone, const AstRawString* catch_variable_name,
281 : MaybeAssignedFlag maybe_assigned, Handle<ScopeInfo> scope_info)
282 : : zone_(zone),
283 : outer_scope_(nullptr),
284 : variables_(zone),
285 : scope_info_(scope_info),
286 9388 : scope_type_(CATCH_SCOPE) {
287 : SetDefaults();
288 : #ifdef DEBUG
289 : already_resolved_ = true;
290 : #endif
291 : // Cache the catch variable, even though it's also available via the
292 : // scope_info, as the parser expects that a catch scope always has the catch
293 : // variable as first and only variable.
294 : Variable* variable = Declare(zone, catch_variable_name, VAR, NORMAL_VARIABLE,
295 4694 : kCreatedInitialized, maybe_assigned);
296 : AllocateHeapSlot(variable);
297 4694 : }
298 :
299 0 : void DeclarationScope::SetDefaults() {
300 19258977 : is_declaration_scope_ = true;
301 19258977 : has_simple_parameters_ = true;
302 19258977 : asm_module_ = false;
303 19258977 : asm_function_ = false;
304 19258977 : force_eager_compilation_ = false;
305 19258977 : has_arguments_parameter_ = false;
306 19258977 : scope_uses_super_property_ = false;
307 19258977 : has_rest_ = false;
308 19258977 : sloppy_block_function_map_ = nullptr;
309 19258977 : receiver_ = nullptr;
310 19258977 : new_target_ = nullptr;
311 19258977 : function_ = nullptr;
312 19258977 : arguments_ = nullptr;
313 0 : rare_data_ = nullptr;
314 19258977 : should_eager_compile_ = false;
315 19258977 : was_lazily_parsed_ = false;
316 19258977 : is_skipped_function_ = false;
317 : #ifdef DEBUG
318 : DeclarationScope* outer_declaration_scope =
319 : outer_scope_ ? outer_scope_->GetDeclarationScope() : nullptr;
320 : is_being_lazily_parsed_ =
321 : outer_declaration_scope ? outer_declaration_scope->is_being_lazily_parsed_
322 : : false;
323 : #endif
324 0 : }
325 :
326 0 : void Scope::SetDefaults() {
327 : #ifdef DEBUG
328 : scope_name_ = nullptr;
329 : already_resolved_ = false;
330 : needs_migration_ = false;
331 : #endif
332 30081500 : inner_scope_ = nullptr;
333 30081500 : sibling_ = nullptr;
334 30081500 : unresolved_ = nullptr;
335 :
336 30081500 : start_position_ = kNoSourcePosition;
337 30081500 : end_position_ = kNoSourcePosition;
338 :
339 30081500 : num_stack_slots_ = 0;
340 30081500 : num_heap_slots_ = Context::MIN_CONTEXT_SLOTS;
341 :
342 : set_language_mode(SLOPPY);
343 :
344 30081500 : scope_calls_eval_ = false;
345 30081500 : scope_nonlinear_ = false;
346 30081500 : is_hidden_ = false;
347 30081500 : is_debug_evaluate_scope_ = false;
348 :
349 30081500 : inner_scope_calls_eval_ = false;
350 30081500 : force_context_allocation_ = false;
351 :
352 30081500 : is_declaration_scope_ = false;
353 :
354 30081500 : must_use_preparsed_scope_data_ = false;
355 0 : }
356 :
357 543562 : bool Scope::HasSimpleParameters() {
358 : DeclarationScope* scope = GetClosureScope();
359 755607 : return !scope->is_function_scope() || scope->has_simple_parameters();
360 : }
361 :
362 5458771 : bool DeclarationScope::ShouldEagerCompile() const {
363 11303438 : return force_eager_compilation_ || should_eager_compile_;
364 : }
365 :
366 1096877 : void DeclarationScope::set_should_eager_compile() {
367 3973454 : should_eager_compile_ = !was_lazily_parsed_;
368 1096877 : }
369 :
370 11102 : void DeclarationScope::set_asm_module() {
371 23467 : asm_module_ = true;
372 : // Mark any existing inner function scopes as asm function scopes.
373 23467 : for (Scope* inner = inner_scope_; inner != nullptr; inner = inner->sibling_) {
374 0 : if (inner->is_function_scope()) {
375 : inner->AsDeclarationScope()->set_asm_function();
376 : }
377 : }
378 11102 : }
379 :
380 13256618 : bool Scope::IsAsmModule() const {
381 36756634 : return is_function_scope() && AsDeclarationScope()->asm_module();
382 : }
383 :
384 30 : bool Scope::IsAsmFunction() const {
385 60 : return is_function_scope() && AsDeclarationScope()->asm_function();
386 : }
387 :
388 3241202 : Scope* Scope::DeserializeScopeChain(Zone* zone, ScopeInfo* scope_info,
389 : DeclarationScope* script_scope,
390 : AstValueFactory* ast_value_factory,
391 : DeserializationMode deserialization_mode) {
392 : // Reconstruct the outer scope chain from a closure's context chain.
393 : Scope* current_scope = nullptr;
394 : Scope* innermost_scope = nullptr;
395 : Scope* outer_scope = nullptr;
396 9981477 : while (scope_info) {
397 4021321 : if (scope_info->scope_type() == WITH_SCOPE) {
398 : // For scope analysis, debug-evaluate is equivalent to a with scope.
399 76836 : outer_scope = new (zone) Scope(zone, WITH_SCOPE, handle(scope_info));
400 :
401 : // TODO(yangguo): Remove once debug-evaluate properly keeps track of the
402 : // function scope in which we are evaluating.
403 38418 : if (scope_info->IsDebugEvaluateScope()) {
404 : outer_scope->set_is_debug_evaluate_scope();
405 : }
406 3982903 : } else if (scope_info->scope_type() == SCRIPT_SCOPE) {
407 : // If we reach a script scope, it's the outermost scope. Install the
408 : // scope info of this script context onto the existing script scope to
409 : // avoid nesting script scopes.
410 522248 : if (deserialization_mode == DeserializationMode::kIncludingVariables) {
411 : script_scope->SetScriptScopeInfo(handle(scope_info));
412 : }
413 : DCHECK(!scope_info->HasOuterScopeInfo());
414 : break;
415 3460655 : } else if (scope_info->scope_type() == FUNCTION_SCOPE) {
416 : outer_scope =
417 6629790 : new (zone) DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info));
418 3314894 : if (scope_info->IsAsmFunction())
419 : outer_scope->AsDeclarationScope()->set_asm_function();
420 3314894 : if (scope_info->IsAsmModule())
421 : outer_scope->AsDeclarationScope()->set_asm_module();
422 145760 : } else if (scope_info->scope_type() == EVAL_SCOPE) {
423 : outer_scope =
424 19816 : new (zone) DeclarationScope(zone, EVAL_SCOPE, handle(scope_info));
425 135852 : } else if (scope_info->scope_type() == BLOCK_SCOPE) {
426 125752 : if (scope_info->is_declaration_scope()) {
427 : outer_scope =
428 25552 : new (zone) DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info));
429 : } else {
430 225952 : outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info));
431 : }
432 10100 : } else if (scope_info->scope_type() == MODULE_SCOPE) {
433 : outer_scope =
434 10812 : new (zone) ModuleScope(handle(scope_info), ast_value_factory);
435 : } else {
436 : DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE);
437 : DCHECK_EQ(scope_info->LocalCount(), 1);
438 : DCHECK_EQ(scope_info->ContextLocalCount(), 1);
439 : DCHECK_EQ(scope_info->ContextLocalMode(0), VAR);
440 : DCHECK_EQ(scope_info->ContextLocalInitFlag(0), kCreatedInitialized);
441 4694 : String* name = scope_info->ContextLocalName(0);
442 : MaybeAssignedFlag maybe_assigned =
443 4694 : scope_info->ContextLocalMaybeAssignedFlag(0);
444 : outer_scope =
445 : new (zone) Scope(zone, ast_value_factory->GetString(handle(name)),
446 14082 : maybe_assigned, handle(scope_info));
447 : }
448 3499072 : if (deserialization_mode == DeserializationMode::kScopesOnly) {
449 1857617 : outer_scope->scope_info_ = Handle<ScopeInfo>::null();
450 : }
451 3499072 : if (current_scope != nullptr) {
452 : outer_scope->AddInnerScope(current_scope);
453 : }
454 : current_scope = outer_scope;
455 3499072 : if (innermost_scope == nullptr) innermost_scope = current_scope;
456 3499072 : scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo()
457 3499073 : : nullptr;
458 : }
459 :
460 3241202 : if (innermost_scope == nullptr) return script_scope;
461 3005380 : script_scope->AddInnerScope(current_scope);
462 3005380 : return innermost_scope;
463 : }
464 :
465 152779109 : DeclarationScope* Scope::AsDeclarationScope() {
466 : DCHECK(is_declaration_scope());
467 152779109 : return static_cast<DeclarationScope*>(this);
468 : }
469 :
470 0 : const DeclarationScope* Scope::AsDeclarationScope() const {
471 : DCHECK(is_declaration_scope());
472 0 : return static_cast<const DeclarationScope*>(this);
473 : }
474 :
475 25354 : ModuleScope* Scope::AsModuleScope() {
476 : DCHECK(is_module_scope());
477 25354 : return static_cast<ModuleScope*>(this);
478 : }
479 :
480 0 : const ModuleScope* Scope::AsModuleScope() const {
481 : DCHECK(is_module_scope());
482 0 : return static_cast<const ModuleScope*>(this);
483 : }
484 :
485 4325730 : int Scope::num_parameters() const {
486 8651460 : return is_declaration_scope() ? AsDeclarationScope()->num_parameters() : 0;
487 : }
488 :
489 12027 : void DeclarationScope::DeclareSloppyBlockFunction(
490 : const AstRawString* name, Scope* scope,
491 : SloppyBlockFunctionStatement* statement) {
492 12027 : if (sloppy_block_function_map_ == nullptr) {
493 : sloppy_block_function_map_ =
494 : new (zone()->New(sizeof(SloppyBlockFunctionMap)))
495 21614 : SloppyBlockFunctionMap(zone());
496 : }
497 12027 : sloppy_block_function_map_->Declare(zone(), name, scope, statement);
498 12027 : }
499 :
500 5556521 : void DeclarationScope::HoistSloppyBlockFunctions(AstNodeFactory* factory) {
501 : DCHECK(is_sloppy(language_mode()));
502 : DCHECK(is_function_scope() || is_eval_scope() || is_script_scope() ||
503 : (is_block_scope() && outer_scope()->is_function_scope()));
504 : DCHECK(HasSimpleParameters() || is_block_scope() || is_being_lazily_parsed_);
505 : DCHECK_EQ(factory == nullptr, is_being_lazily_parsed_);
506 :
507 : SloppyBlockFunctionMap* map = sloppy_block_function_map();
508 11058303 : if (map == nullptr) return;
509 :
510 10683 : const bool has_simple_parameters = HasSimpleParameters();
511 :
512 : // The declarations need to be added in the order they were seen,
513 : // so accumulate declared names sorted by index.
514 : ZoneMap<int, const AstRawString*> names_to_declare(zone());
515 :
516 : // For each variable which is used as a function declaration in a sloppy
517 : // block,
518 32910 : for (ZoneHashMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
519 11544 : const AstRawString* name = static_cast<AstRawString*>(p->key);
520 :
521 : // If the variable wouldn't conflict with a lexical declaration
522 : // or parameter,
523 :
524 : // Check if there's a conflict with a parameter.
525 : // This depends on the fact that functions always have a scope solely to
526 : // hold complex parameters, and the names local to that scope are
527 : // precisely the names of the parameters. IsDeclaredParameter(name) does
528 : // not hold for names declared by complex parameters, nor are those
529 : // bindings necessarily declared lexically, so we have to check for them
530 : // explicitly. On the other hand, if there are not complex parameters,
531 : // it is sufficient to just check IsDeclaredParameter.
532 11544 : if (!has_simple_parameters) {
533 186 : if (outer_scope_->LookupLocal(name) != nullptr) {
534 : continue;
535 : }
536 : } else {
537 11358 : if (IsDeclaredParameter(name)) {
538 : continue;
539 : }
540 : }
541 :
542 : bool declaration_queued = false;
543 :
544 : // Write in assignments to var for each block-scoped function declaration
545 11326 : auto delegates = static_cast<SloppyBlockFunctionMap::Delegate*>(p->value);
546 :
547 : DeclarationScope* decl_scope = this;
548 24563 : while (decl_scope->is_eval_scope()) {
549 26474 : decl_scope = decl_scope->outer_scope()->GetDeclarationScope();
550 : }
551 : Scope* outer_scope = decl_scope->outer_scope();
552 :
553 40299 : for (SloppyBlockFunctionMap::Delegate* delegate = delegates;
554 : delegate != nullptr; delegate = delegate->next()) {
555 : // Check if there's a conflict with a lexical declaration
556 25214 : Scope* query_scope = delegate->scope()->outer_scope();
557 : Variable* var = nullptr;
558 : bool should_hoist = true;
559 :
560 : // Note that we perform this loop for each delegate named 'name',
561 : // which may duplicate work if those delegates share scopes.
562 : // It is not sufficient to just do a Lookup on query_scope: for
563 : // example, that does not prevent hoisting of the function in
564 : // `{ let e; try {} catch (e) { function e(){} } }`
565 13452 : do {
566 15483 : var = query_scope->LookupLocal(name);
567 18960 : if (var != nullptr && IsLexical(var)) {
568 : should_hoist = false;
569 : break;
570 : }
571 : query_scope = query_scope->outer_scope();
572 : } while (query_scope != outer_scope);
573 :
574 11762 : if (!should_hoist) continue;
575 :
576 9731 : if (!declaration_queued) {
577 : declaration_queued = true;
578 9309 : names_to_declare.insert({delegate->index(), name});
579 : }
580 :
581 9731 : if (factory) {
582 : DCHECK(!is_being_lazily_parsed_);
583 : Expression* assignment = factory->NewAssignment(
584 7902 : Token::ASSIGN, NewUnresolved(factory, name),
585 15804 : delegate->scope()->NewUnresolved(factory, name), kNoSourcePosition);
586 : Statement* statement =
587 : factory->NewExpressionStatement(assignment, kNoSourcePosition);
588 : delegate->set_statement(statement);
589 : }
590 : }
591 : }
592 :
593 10683 : if (names_to_declare.empty()) return;
594 :
595 26217 : for (const auto& index_and_name : names_to_declare) {
596 9309 : const AstRawString* name = index_and_name.second;
597 9309 : if (factory) {
598 : DCHECK(!is_being_lazily_parsed_);
599 : VariableProxy* proxy = factory->NewVariableProxy(name, NORMAL_VARIABLE);
600 : auto declaration =
601 : factory->NewVariableDeclaration(proxy, this, kNoSourcePosition);
602 : // Based on the preceding checks, it doesn't matter what we pass as
603 : // allow_harmony_restrictive_generators and
604 : // sloppy_mode_block_scope_function_redefinition.
605 7620 : bool ok = true;
606 : DeclareVariable(declaration, VAR,
607 : Variable::DefaultInitializationFlag(VAR), false, nullptr,
608 7620 : &ok);
609 : DCHECK(ok);
610 : } else {
611 : DCHECK(is_being_lazily_parsed_);
612 1689 : Variable* var = DeclareVariableName(name, VAR);
613 3236 : if (var != kDummyPreParserVariable &&
614 1547 : var != kDummyPreParserLexicalVariable) {
615 : DCHECK(FLAG_experimental_preparser_scope_analysis);
616 : var->set_maybe_assigned();
617 : }
618 : }
619 : }
620 : }
621 :
622 12763656 : void DeclarationScope::Analyze(ParseInfo* info, Isolate* isolate,
623 : AnalyzeMode mode) {
624 : RuntimeCallTimerScope runtimeTimer(isolate,
625 2876573 : &RuntimeCallStats::CompileScopeAnalysis);
626 : DCHECK(info->literal() != NULL);
627 2876576 : DeclarationScope* scope = info->literal()->scope();
628 : DCHECK(scope->scope_info_.is_null());
629 :
630 : Handle<ScopeInfo> outer_scope_info;
631 2876576 : if (info->maybe_outer_scope_info().ToHandle(&outer_scope_info)) {
632 4418008 : if (scope->outer_scope()) {
633 : DeclarationScope* script_scope = new (info->zone())
634 1541431 : DeclarationScope(info->zone(), info->ast_value_factory());
635 : info->set_script_scope(script_scope);
636 : scope->ReplaceOuterScope(Scope::DeserializeScopeChain(
637 : info->zone(), *outer_scope_info, script_scope,
638 : info->ast_value_factory(),
639 1541431 : Scope::DeserializationMode::kIncludingVariables));
640 : } else {
641 : DCHECK_EQ(outer_scope_info->scope_type(), SCRIPT_SCOPE);
642 : scope->SetScriptScopeInfo(outer_scope_info);
643 : }
644 : }
645 :
646 4114378 : if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) {
647 : AstNodeFactory factory(info->ast_value_factory());
648 1051060 : scope->HoistSloppyBlockFunctions(&factory);
649 : }
650 :
651 : // We are compiling one of four cases:
652 : // 1) top-level code,
653 : // 2) a function/eval/module on the top-level
654 : // 3) a function/eval in a scope that was already resolved.
655 : // 4) an asm.js function
656 : DCHECK(scope->scope_type() == SCRIPT_SCOPE ||
657 : scope->outer_scope()->scope_type() == SCRIPT_SCOPE ||
658 : scope->outer_scope()->already_resolved_ ||
659 : (info->asm_function_scope() && scope->is_function_scope()));
660 :
661 : // The outer scope is never lazy.
662 : scope->set_should_eager_compile();
663 :
664 2876577 : if (scope->must_use_preparsed_scope_data_) {
665 : DCHECK(FLAG_experimental_preparser_scope_analysis);
666 : DCHECK_NOT_NULL(info->preparsed_scope_data());
667 : DCHECK_EQ(scope->scope_type_, ScopeType::FUNCTION_SCOPE);
668 14 : info->preparsed_scope_data()->RestoreData(scope);
669 : }
670 :
671 2876577 : scope->AllocateVariables(info, isolate, mode);
672 :
673 : // Ensuring that the outer script scope has a scope info avoids having
674 : // special case for native contexts vs other contexts.
675 2876585 : if (info->script_scope()->scope_info_.is_null()) {
676 4551822 : info->script_scope()->scope_info_ = handle(ScopeInfo::Empty(isolate));
677 : }
678 :
679 : #ifdef DEBUG
680 : if (info->script_is_native() ? FLAG_print_builtin_scopes
681 : : FLAG_print_scopes) {
682 : PrintF("Global scope:\n");
683 : scope->Print();
684 : }
685 : scope->CheckScopePositions();
686 : scope->CheckZones();
687 : #endif
688 2876585 : }
689 :
690 16159932 : void DeclarationScope::DeclareThis(AstValueFactory* ast_value_factory) {
691 : DCHECK(!already_resolved_);
692 : DCHECK(is_declaration_scope());
693 : DCHECK(has_this_declaration());
694 :
695 8079966 : bool derived_constructor = IsDerivedConstructor(function_kind_);
696 : Variable* var =
697 : Declare(zone(), ast_value_factory->this_string(),
698 : derived_constructor ? CONST : VAR, THIS_VARIABLE,
699 16159932 : derived_constructor ? kNeedsInitialization : kCreatedInitialized);
700 8079966 : receiver_ = var;
701 8079966 : }
702 :
703 13779997 : void DeclarationScope::DeclareArguments(AstValueFactory* ast_value_factory) {
704 : DCHECK(is_function_scope());
705 : DCHECK(!is_arrow_scope());
706 :
707 13779997 : arguments_ = LookupLocal(ast_value_factory->arguments_string());
708 6890810 : if (arguments_ == nullptr) {
709 : // Declare 'arguments' variable which exists in all non arrow functions.
710 : // Note that it might never be accessed, in which case it won't be
711 : // allocated during variable allocation.
712 6889195 : arguments_ = Declare(zone(), ast_value_factory->arguments_string(), VAR);
713 1615 : } else if (IsLexical(arguments_)) {
714 : // Check if there's lexically declared variable named arguments to avoid
715 : // redeclaration. See ES#sec-functiondeclarationinstantiation, step 20.
716 615 : arguments_ = nullptr;
717 : }
718 6890805 : }
719 :
720 8051767 : void DeclarationScope::DeclareDefaultFunctionVariables(
721 9407861 : AstValueFactory* ast_value_factory) {
722 : DCHECK(is_function_scope());
723 : DCHECK(!is_arrow_scope());
724 :
725 8051767 : DeclareThis(ast_value_factory);
726 8729813 : new_target_ = Declare(zone(), ast_value_factory->new_target_string(), CONST);
727 :
728 31098655 : if (IsConciseMethod(function_kind_) || IsClassConstructor(function_kind_) ||
729 : IsAccessorFunction(function_kind_)) {
730 : EnsureRareData()->this_function =
731 678048 : Declare(zone(), ast_value_factory->this_function_string(), CONST);
732 : }
733 8051766 : }
734 :
735 940123 : Variable* DeclarationScope::DeclareFunctionVar(const AstRawString* name) {
736 : DCHECK(is_function_scope());
737 : DCHECK_NULL(function_);
738 : DCHECK_NULL(variables_.Lookup(name));
739 1813937 : VariableKind kind = is_sloppy(language_mode()) ? SLOPPY_FUNCTION_NAME_VARIABLE
740 940123 : : NORMAL_VARIABLE;
741 : function_ =
742 940134 : new (zone()) Variable(this, name, CONST, kind, kCreatedInitialized);
743 940130 : if (calls_sloppy_eval()) {
744 66316 : NonLocal(name, DYNAMIC);
745 : } else {
746 873814 : variables_.Add(zone(), function_);
747 : }
748 940136 : return function_;
749 : }
750 :
751 110847 : Variable* DeclarationScope::DeclareGeneratorObjectVar(
752 110847 : const AstRawString* name) {
753 : DCHECK(is_function_scope() || is_module_scope());
754 : DCHECK_NULL(generator_object_var());
755 :
756 : Variable* result = EnsureRareData()->generator_object =
757 110847 : NewTemporary(name, kNotAssigned);
758 : result->set_is_used();
759 110847 : return result;
760 : }
761 :
762 32344 : Variable* DeclarationScope::DeclarePromiseVar(const AstRawString* name) {
763 : DCHECK(is_function_scope());
764 : DCHECK_NULL(promise_var());
765 64688 : Variable* result = EnsureRareData()->promise = NewTemporary(name);
766 : result->set_is_used();
767 32344 : return result;
768 : }
769 :
770 11386 : Variable* DeclarationScope::DeclareAsyncGeneratorAwaitVar(
771 11386 : const AstRawString* name) {
772 : DCHECK(is_function_scope());
773 : DCHECK_NULL(async_generator_await_var());
774 22772 : Variable* result = EnsureRareData()->promise = NewTemporary(name);
775 : DCHECK_NULL(promise_var()); // promise is alias for generator await var
776 : result->set_is_used();
777 11386 : return result;
778 : }
779 :
780 111119 : bool Scope::HasBeenRemoved() const {
781 111119 : if (sibling() == this) {
782 : DCHECK_NULL(inner_scope_);
783 : DCHECK(is_block_scope());
784 : return true;
785 : }
786 0 : return false;
787 : }
788 :
789 73529 : Scope* Scope::GetUnremovedScope() {
790 37590 : Scope* scope = this;
791 295767 : while (scope != nullptr && scope->HasBeenRemoved()) {
792 : scope = scope->outer_scope();
793 : }
794 : DCHECK_NOT_NULL(scope);
795 73529 : return scope;
796 : }
797 :
798 34734055 : Scope* Scope::FinalizeBlockScope() {
799 : DCHECK(is_block_scope());
800 : DCHECK(!HasBeenRemoved());
801 :
802 27778350 : if (variables_.occupancy() > 0 ||
803 69537 : (is_declaration_scope() && calls_sloppy_eval())) {
804 : return this;
805 : }
806 :
807 : // Remove this scope from outer scope.
808 : outer_scope()->RemoveInnerScope(this);
809 :
810 : // Reparent inner scopes.
811 8946210 : if (inner_scope_ != nullptr) {
812 : Scope* scope = inner_scope_;
813 674968 : scope->outer_scope_ = outer_scope();
814 1570376 : while (scope->sibling_ != nullptr) {
815 : scope = scope->sibling_;
816 220440 : scope->outer_scope_ = outer_scope();
817 : }
818 674968 : scope->sibling_ = outer_scope()->inner_scope_;
819 674968 : outer_scope()->inner_scope_ = inner_scope_;
820 674968 : inner_scope_ = nullptr;
821 : }
822 :
823 : // Move unresolved variables
824 8946210 : if (unresolved_ != nullptr) {
825 6768837 : if (outer_scope()->unresolved_ != nullptr) {
826 50317270 : VariableProxy* unresolved = unresolved_;
827 50317270 : while (unresolved->next_unresolved() != nullptr) {
828 : unresolved = unresolved->next_unresolved();
829 : }
830 : unresolved->set_next_unresolved(outer_scope()->unresolved_);
831 : }
832 6768837 : outer_scope()->unresolved_ = unresolved_;
833 6768837 : unresolved_ = nullptr;
834 : }
835 :
836 9235965 : if (scope_calls_eval_) outer_scope()->scope_calls_eval_ = true;
837 9246185 : if (inner_scope_calls_eval_) outer_scope()->inner_scope_calls_eval_ = true;
838 :
839 : // This block does not need a context.
840 8946210 : num_heap_slots_ = 0;
841 :
842 : // Mark scope as removed by making it its own sibling.
843 8946210 : sibling_ = this;
844 : DCHECK(HasBeenRemoved());
845 :
846 8946210 : return nullptr;
847 : }
848 :
849 0 : void DeclarationScope::AddLocal(Variable* var) {
850 : DCHECK(!already_resolved_);
851 : // Temporaries are only placed in ClosureScopes.
852 : DCHECK_EQ(GetClosureScope(), this);
853 : locals_.Add(var);
854 0 : }
855 :
856 48966242 : Variable* Scope::Declare(Zone* zone, const AstRawString* name,
857 : VariableMode mode, VariableKind kind,
858 : InitializationFlag initialization_flag,
859 : MaybeAssignedFlag maybe_assigned_flag) {
860 : bool added;
861 : Variable* var =
862 : variables_.Declare(zone, this, name, mode, kind, initialization_flag,
863 48966242 : maybe_assigned_flag, &added);
864 48966228 : if (added) locals_.Add(var);
865 48966228 : return var;
866 : }
867 :
868 685823 : void Scope::Snapshot::Reparent(DeclarationScope* new_parent) const {
869 : DCHECK_EQ(new_parent, outer_scope_->inner_scope_);
870 : DCHECK_EQ(new_parent->outer_scope_, outer_scope_);
871 : DCHECK_EQ(new_parent, new_parent->GetClosureScope());
872 : DCHECK_NULL(new_parent->inner_scope_);
873 : DCHECK_NULL(new_parent->unresolved_);
874 : DCHECK(new_parent->locals_.is_empty());
875 686235 : Scope* inner_scope = new_parent->sibling_;
876 685823 : if (inner_scope != top_inner_scope_) {
877 2983 : for (; inner_scope->sibling() != top_inner_scope_;
878 : inner_scope = inner_scope->sibling()) {
879 412 : inner_scope->outer_scope_ = new_parent;
880 412 : if (inner_scope->inner_scope_calls_eval_) {
881 0 : new_parent->inner_scope_calls_eval_ = true;
882 : }
883 : DCHECK_NE(inner_scope, new_parent);
884 : }
885 2571 : inner_scope->outer_scope_ = new_parent;
886 2571 : if (inner_scope->inner_scope_calls_eval_) {
887 162 : new_parent->inner_scope_calls_eval_ = true;
888 : }
889 2571 : new_parent->inner_scope_ = new_parent->sibling_;
890 2571 : inner_scope->sibling_ = nullptr;
891 : // Reset the sibling rather than the inner_scope_ since we
892 : // want to keep new_parent there.
893 2571 : new_parent->sibling_ = top_inner_scope_;
894 : }
895 :
896 685823 : if (outer_scope_->unresolved_ != top_unresolved_) {
897 627851 : VariableProxy* last = outer_scope_->unresolved_;
898 627851 : while (last->next_unresolved() != top_unresolved_) {
899 : last = last->next_unresolved();
900 : }
901 : last->set_next_unresolved(nullptr);
902 283605 : new_parent->unresolved_ = outer_scope_->unresolved_;
903 283605 : outer_scope_->unresolved_ = top_unresolved_;
904 : }
905 :
906 : // TODO(verwaest): This currently only moves do-expression declared variables
907 : // in default arguments that weren't already previously declared with the same
908 : // name in the closure-scope. See
909 : // test/mjsunit/harmony/default-parameter-do-expression.js.
910 685823 : DeclarationScope* outer_closure = outer_scope_->GetClosureScope();
911 :
912 : new_parent->locals_.MoveTail(outer_closure->locals(), top_local_);
913 1374694 : for (Variable* local : new_parent->locals_) {
914 : DCHECK(local->mode() == TEMPORARY || local->mode() == VAR);
915 : DCHECK_EQ(local->scope(), local->scope()->GetClosureScope());
916 : DCHECK_NE(local->scope(), new_parent);
917 : local->set_scope(new_parent);
918 1524 : if (local->mode() == VAR) {
919 : outer_closure->variables_.Remove(local);
920 29 : new_parent->variables_.Add(new_parent->zone(), local);
921 : }
922 : }
923 : outer_closure->locals_.Rewind(top_local_);
924 : outer_closure->decls_.Rewind(top_decl_);
925 :
926 : // Move eval calls since Snapshot's creation into new_parent.
927 685823 : if (outer_scope_->scope_calls_eval_) {
928 512 : new_parent->scope_calls_eval_ = true;
929 512 : new_parent->inner_scope_calls_eval_ = true;
930 : }
931 : // Reset the outer_scope's eval state. It will be restored to its
932 : // original value as necessary in the destructor of this class.
933 685823 : outer_scope_->scope_calls_eval_ = false;
934 685823 : }
935 :
936 1541479 : void Scope::ReplaceOuterScope(Scope* outer) {
937 : DCHECK_NOT_NULL(outer);
938 : DCHECK_NOT_NULL(outer_scope_);
939 : DCHECK(!already_resolved_);
940 1541479 : outer_scope_->RemoveInnerScope(this);
941 : outer->AddInnerScope(this);
942 : outer_scope_ = outer;
943 1541479 : }
944 :
945 5043164 : Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
946 : Handle<String> name_handle = name->string();
947 : // The Scope is backed up by ScopeInfo. This means it cannot operate in a
948 : // heap-independent mode, and all strings must be internalized immediately. So
949 : // it's ok to get the Handle<String> here.
950 : // If we have a serialized scope info, we might find the variable there.
951 : // There should be no local slot with the given name.
952 : DCHECK_LT(scope_info_->StackSlotIndex(*name_handle), 0);
953 :
954 : bool found = false;
955 :
956 : VariableLocation location;
957 : int index;
958 : VariableMode mode;
959 : InitializationFlag init_flag;
960 : MaybeAssignedFlag maybe_assigned_flag;
961 :
962 : {
963 : location = VariableLocation::CONTEXT;
964 : index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
965 2521334 : &init_flag, &maybe_assigned_flag);
966 2521334 : found = index >= 0;
967 : }
968 :
969 3736474 : if (!found && scope_type() == MODULE_SCOPE) {
970 : location = VariableLocation::MODULE;
971 : index = scope_info_->ModuleIndex(name_handle, &mode, &init_flag,
972 5331 : &maybe_assigned_flag);
973 5331 : found = index != 0;
974 : }
975 :
976 2521334 : if (!found) {
977 1214644 : index = scope_info_->FunctionContextSlotIndex(*name_handle);
978 1214644 : if (index < 0) return nullptr; // Nowhere found.
979 1425 : Variable* var = AsDeclarationScope()->DeclareFunctionVar(name);
980 : DCHECK_EQ(CONST, var->mode());
981 : var->AllocateTo(VariableLocation::CONTEXT, index);
982 1425 : return variables_.Lookup(name);
983 : }
984 :
985 : VariableKind kind = NORMAL_VARIABLE;
986 2612884 : if (location == VariableLocation::CONTEXT &&
987 1306194 : index == scope_info_->ReceiverContextSlotIndex()) {
988 : kind = THIS_VARIABLE;
989 : }
990 : // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
991 : // ARGUMENTS bindings as their corresponding VariableKind.
992 :
993 : Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag,
994 2613380 : maybe_assigned_flag);
995 : var->AllocateTo(location, index);
996 1306690 : return var;
997 : }
998 :
999 32216 : Variable* Scope::Lookup(const AstRawString* name) {
1000 33742 : for (Scope* scope = this;
1001 : scope != NULL;
1002 : scope = scope->outer_scope()) {
1003 33742 : Variable* var = scope->LookupLocal(name);
1004 33742 : if (var != NULL) return var;
1005 : }
1006 : return NULL;
1007 : }
1008 :
1009 9006180 : Variable* DeclarationScope::DeclareParameter(
1010 : const AstRawString* name, VariableMode mode, bool is_optional, bool is_rest,
1011 9006181 : bool* is_duplicate, AstValueFactory* ast_value_factory, int position) {
1012 : DCHECK(!already_resolved_);
1013 : DCHECK(is_function_scope() || is_module_scope());
1014 : DCHECK(!has_rest_);
1015 : DCHECK(!is_optional || !is_rest);
1016 : DCHECK(!is_being_lazily_parsed_);
1017 : DCHECK(!was_lazily_parsed_);
1018 : Variable* var;
1019 9006180 : if (mode == TEMPORARY) {
1020 18012361 : var = NewTemporary(name);
1021 : } else {
1022 : DCHECK_EQ(mode, VAR);
1023 17767584 : var = Declare(zone(), name, mode);
1024 : // TODO(wingo): Avoid O(n^2) check.
1025 8883793 : *is_duplicate = IsDeclaredParameter(name);
1026 : }
1027 9006181 : has_rest_ = is_rest;
1028 : var->set_initializer_position(position);
1029 : params_.Add(var, zone());
1030 9006181 : if (name == ast_value_factory->arguments_string()) {
1031 1253 : has_arguments_parameter_ = true;
1032 : }
1033 9006181 : return var;
1034 : }
1035 :
1036 651128 : Variable* DeclarationScope::DeclareParameterName(
1037 : const AstRawString* name, bool is_rest,
1038 651128 : AstValueFactory* ast_value_factory) {
1039 : DCHECK(!already_resolved_);
1040 : DCHECK(is_function_scope() || is_module_scope());
1041 : DCHECK(!has_rest_ || is_rest);
1042 : DCHECK(is_being_lazily_parsed_);
1043 651128 : has_rest_ = is_rest;
1044 651128 : if (name == ast_value_factory->arguments_string()) {
1045 7 : has_arguments_parameter_ = true;
1046 : }
1047 651128 : if (FLAG_experimental_preparser_scope_analysis) {
1048 4978 : Variable* var = Declare(zone(), name, VAR);
1049 : params_.Add(var, zone());
1050 : return var;
1051 : }
1052 646150 : DeclareVariableName(name, VAR);
1053 646150 : return nullptr;
1054 : }
1055 :
1056 750946 : Variable* Scope::DeclareLocal(const AstRawString* name, VariableMode mode,
1057 : InitializationFlag init_flag, VariableKind kind,
1058 16373841 : MaybeAssignedFlag maybe_assigned_flag) {
1059 : DCHECK(!already_resolved_);
1060 : // This function handles VAR, LET, and CONST modes. DYNAMIC variables are
1061 : // introduced during variable allocation, and TEMPORARY variables are
1062 : // allocated via NewTemporary().
1063 : DCHECK(IsDeclaredVariableMode(mode));
1064 : DCHECK_IMPLIES(GetDeclarationScope()->is_being_lazily_parsed(),
1065 : mode == VAR || mode == LET || mode == CONST);
1066 : DCHECK(!GetDeclarationScope()->was_lazily_parsed());
1067 32747682 : return Declare(zone(), name, mode, kind, init_flag, maybe_assigned_flag);
1068 : }
1069 :
1070 18418634 : Variable* Scope::DeclareVariable(
1071 16427514 : Declaration* declaration, VariableMode mode, InitializationFlag init,
1072 : bool allow_harmony_restrictive_generators,
1073 16756424 : bool* sloppy_mode_block_scope_function_redefinition, bool* ok) {
1074 : DCHECK(IsDeclaredVariableMode(mode));
1075 : DCHECK(!already_resolved_);
1076 : DCHECK(!GetDeclarationScope()->is_being_lazily_parsed());
1077 : DCHECK(!GetDeclarationScope()->was_lazily_parsed());
1078 :
1079 35014538 : if (mode == VAR && !is_declaration_scope()) {
1080 : return GetDeclarationScope()->DeclareVariable(
1081 : declaration, mode, init, allow_harmony_restrictive_generators,
1082 3982240 : sloppy_mode_block_scope_function_redefinition, ok);
1083 : }
1084 : DCHECK(!is_catch_scope());
1085 : DCHECK(!is_with_scope());
1086 : DCHECK(is_declaration_scope() ||
1087 : (IsLexicalVariableMode(mode) && is_block_scope()));
1088 :
1089 : VariableProxy* proxy = declaration->proxy();
1090 : DCHECK(proxy->raw_name() != NULL);
1091 478 : const AstRawString* name = proxy->raw_name();
1092 : bool is_function_declaration = declaration->IsFunctionDeclaration();
1093 :
1094 : // Pessimistically assume that top-level variables will be assigned.
1095 : //
1096 : // Top-level variables in a script can be accessed by other scripts or even
1097 : // become global properties. While this does not apply to top-level variables
1098 : // in a module (assuming they are not exported), we must still mark these as
1099 : // assigned because they might be accessed by a lazily parsed top-level
1100 : // function, which, for efficiency, we preparse without variable tracking.
1101 16427514 : if (is_script_scope() || is_module_scope()) {
1102 2427299 : if (mode != CONST) proxy->set_is_assigned();
1103 : }
1104 :
1105 436349 : Variable* var = nullptr;
1106 17566000 : if (is_eval_scope() && is_sloppy(language_mode()) && mode == VAR) {
1107 : // In a var binding in a sloppy direct eval, pollute the enclosing scope
1108 : // with this new binding by doing the following:
1109 : // The proxy is bound to a lookup variable to force a dynamic declaration
1110 : // using the DeclareEvalVar or DeclareEvalFunction runtime functions.
1111 : var = new (zone())
1112 328910 : Variable(this, name, mode, NORMAL_VARIABLE, init, kMaybeAssigned);
1113 : var->AllocateTo(VariableLocation::LOOKUP, -1);
1114 : } else {
1115 : // Declare the variable in the declaration scope.
1116 16098604 : var = LookupLocal(name);
1117 16098605 : if (var == NULL) {
1118 : // Declare the name.
1119 : VariableKind kind = NORMAL_VARIABLE;
1120 15594997 : if (is_function_declaration) {
1121 : kind = FUNCTION_VARIABLE;
1122 : }
1123 : var = DeclareLocal(name, mode, init, kind, kNotAssigned);
1124 939957 : } else if (IsLexicalVariableMode(mode) ||
1125 : IsLexicalVariableMode(var->mode())) {
1126 : // Allow duplicate function decls for web compat, see bug 4693.
1127 : bool duplicate_allowed = false;
1128 81612 : if (is_sloppy(language_mode()) && is_function_declaration &&
1129 : var->is_function()) {
1130 : DCHECK(IsLexicalVariableMode(mode) &&
1131 : IsLexicalVariableMode(var->mode()));
1132 : // If the duplication is allowed, then the var will show up
1133 : // in the SloppyBlockFunctionMap and the new FunctionKind
1134 : // will be a permitted duplicate.
1135 : FunctionKind function_kind =
1136 1436 : declaration->AsFunctionDeclaration()->fun()->kind();
1137 : SloppyBlockFunctionMap* map =
1138 718 : GetDeclarationScope()->sloppy_block_function_map();
1139 478 : duplicate_allowed = map != nullptr &&
1140 : map->Lookup(const_cast<AstRawString*>(name),
1141 2152 : name->hash()) != nullptr &&
1142 1004 : !IsAsyncFunction(function_kind) &&
1143 : !(allow_harmony_restrictive_generators &&
1144 240 : IsGeneratorFunction(function_kind));
1145 : }
1146 80515 : if (duplicate_allowed) {
1147 238 : *sloppy_mode_block_scope_function_redefinition = true;
1148 : } else {
1149 : // The name was declared in this scope before; check for conflicting
1150 : // re-declarations. We have a conflict if either of the declarations
1151 : // is not a var (in script scope, we also have to ignore legacy const
1152 : // for compatibility). There is similar code in runtime.cc in the
1153 : // Declare functions. The function CheckConflictingVarDeclarations
1154 : // checks for var and let bindings from different scopes whereas this
1155 : // is a check for conflicting declarations within the same scope. This
1156 : // check also covers the special case
1157 : //
1158 : // function () { let x; { var x; } }
1159 : //
1160 : // because the var declaration is hoisted to the function scope where
1161 : // 'x' is already bound.
1162 : DCHECK(IsDeclaredVariableMode(var->mode()));
1163 : // In harmony we treat re-declarations as early errors. See
1164 : // ES5 16 for a definition of early errors.
1165 80277 : *ok = false;
1166 80277 : return nullptr;
1167 : }
1168 423093 : } else if (mode == VAR) {
1169 : var->set_maybe_assigned();
1170 : }
1171 : }
1172 : DCHECK_NOT_NULL(var);
1173 :
1174 : // We add a declaration node for every declaration. The compiler
1175 : // will only generate code if necessary. In particular, declarations
1176 : // for inner local variables that do not represent functions won't
1177 : // result in any generated code.
1178 : //
1179 : // This will lead to multiple declaration nodes for the
1180 : // same variable if it is declared several times. This is not a
1181 : // semantic issue, but it may be a performance issue since it may
1182 : // lead to repeated DeclareEvalVar or DeclareEvalFunction calls.
1183 : decls_.Add(declaration);
1184 16347236 : proxy->BindTo(var);
1185 16347237 : return var;
1186 : }
1187 :
1188 1836741 : Variable* Scope::DeclareVariableName(const AstRawString* name,
1189 1409420 : VariableMode mode) {
1190 : DCHECK(IsDeclaredVariableMode(mode));
1191 : DCHECK(!already_resolved_);
1192 : DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
1193 :
1194 3612353 : if (mode == VAR && !is_declaration_scope()) {
1195 796282 : return GetDeclarationScope()->DeclareVariableName(name, mode);
1196 : }
1197 : DCHECK(!is_with_scope());
1198 : DCHECK(!is_eval_scope());
1199 : // Unlike DeclareVariable, DeclareVariableName allows declaring variables in
1200 : // catch scopes: Parser::RewriteCatchPattern bypasses DeclareVariable by
1201 : // calling DeclareLocal directly, and it doesn't make sense to add a similar
1202 : // bypass mechanism for PreParser.
1203 : DCHECK(is_declaration_scope() || (IsLexicalVariableMode(mode) &&
1204 : (is_block_scope() || is_catch_scope())));
1205 : DCHECK(scope_info_.is_null());
1206 :
1207 : // Declare the variable in the declaration scope.
1208 1438600 : if (FLAG_experimental_preparser_scope_analysis) {
1209 29180 : Variable* var = LookupLocal(name);
1210 : DCHECK_NE(var, kDummyPreParserLexicalVariable);
1211 : DCHECK_NE(var, kDummyPreParserVariable);
1212 29180 : if (var == nullptr) {
1213 : var = DeclareLocal(name, mode);
1214 1282 : } else if (mode == VAR) {
1215 : DCHECK_EQ(var->mode(), VAR);
1216 : var->set_maybe_assigned();
1217 : }
1218 : var->set_is_used();
1219 29180 : return var;
1220 : } else {
1221 2818840 : return variables_.DeclareName(zone(), name, mode);
1222 : }
1223 : }
1224 :
1225 106191558 : VariableProxy* Scope::NewUnresolved(AstNodeFactory* factory,
1226 : const AstRawString* name,
1227 : int start_position, VariableKind kind) {
1228 : // Note that we must not share the unresolved variables with
1229 : // the same name because they may be removed selectively via
1230 : // RemoveUnresolved().
1231 : DCHECK(!already_resolved_);
1232 : DCHECK_EQ(factory->zone(), zone());
1233 : VariableProxy* proxy = factory->NewVariableProxy(name, kind, start_position);
1234 106191517 : proxy->set_next_unresolved(unresolved_);
1235 106191517 : unresolved_ = proxy;
1236 106191517 : return proxy;
1237 : }
1238 :
1239 1457 : void Scope::AddUnresolved(VariableProxy* proxy) {
1240 : DCHECK(!already_resolved_);
1241 : DCHECK(!proxy->is_resolved());
1242 1457 : proxy->set_next_unresolved(unresolved_);
1243 1457 : unresolved_ = proxy;
1244 1457 : }
1245 :
1246 8101489 : Variable* DeclarationScope::DeclareDynamicGlobal(const AstRawString* name,
1247 : VariableKind kind) {
1248 : DCHECK(is_script_scope());
1249 8101489 : return variables_.Declare(zone(), this, name, DYNAMIC_GLOBAL, kind);
1250 : // TODO(neis): Mark variable as maybe-assigned?
1251 : }
1252 :
1253 :
1254 25961694 : bool Scope::RemoveUnresolved(VariableProxy* var) {
1255 15175552 : if (unresolved_ == var) {
1256 10786142 : unresolved_ = var->next_unresolved();
1257 : var->set_next_unresolved(nullptr);
1258 10786142 : return true;
1259 : }
1260 8120917 : VariableProxy* current = unresolved_;
1261 8122402 : while (current != nullptr) {
1262 4387925 : VariableProxy* next = current->next_unresolved();
1263 8120917 : if (var == next) {
1264 : current->set_next_unresolved(next->next_unresolved());
1265 : var->set_next_unresolved(nullptr);
1266 4387925 : return true;
1267 : }
1268 : current = next;
1269 : }
1270 : return false;
1271 : }
1272 :
1273 3725422 : Variable* Scope::NewTemporary(const AstRawString* name) {
1274 3891540 : return NewTemporary(name, kMaybeAssigned);
1275 : }
1276 :
1277 4002381 : Variable* Scope::NewTemporary(const AstRawString* name,
1278 4002381 : MaybeAssignedFlag maybe_assigned) {
1279 : DeclarationScope* scope = GetClosureScope();
1280 : Variable* var = new (zone())
1281 4002387 : Variable(scope, name, TEMPORARY, NORMAL_VARIABLE, kCreatedInitialized);
1282 : scope->AddLocal(var);
1283 4002388 : if (maybe_assigned == kMaybeAssigned) var->set_maybe_assigned();
1284 4002388 : return var;
1285 : }
1286 :
1287 11036823 : Declaration* Scope::CheckConflictingVarDeclarations() {
1288 65547649 : for (Declaration* decl : decls_) {
1289 15541858 : VariableMode mode = decl->proxy()->var()->mode();
1290 16591480 : if (IsLexicalVariableMode(mode) && !is_block_scope()) continue;
1291 :
1292 : // Iterate through all scopes until and including the declaration scope.
1293 : Scope* previous = NULL;
1294 : Scope* current = decl->scope();
1295 : // Lexical vs lexical conflicts within the same scope have already been
1296 : // captured in Parser::Declare. The only conflicts we still need to check
1297 : // are lexical vs VAR, or any declarations within a declaration block scope
1298 : // vs lexical declarations in its surrounding (function) scope.
1299 14527527 : if (IsLexicalVariableMode(mode)) current = current->outer_scope_;
1300 18128658 : do {
1301 : // There is a conflict if there exists a non-VAR binding.
1302 14192219 : Variable* other_var =
1303 18166654 : current->variables_.Lookup(decl->proxy()->raw_name());
1304 32358873 : if (other_var != NULL && IsLexicalVariableMode(other_var->mode())) {
1305 : return decl;
1306 : }
1307 : previous = current;
1308 18128658 : current = current->outer_scope_;
1309 : } while (!previous->is_declaration_scope());
1310 : }
1311 : return NULL;
1312 : }
1313 :
1314 1619 : Declaration* Scope::CheckLexDeclarationsConflictingWith(
1315 : const ZoneList<const AstRawString*>& names) {
1316 : DCHECK(is_block_scope());
1317 5412 : for (int i = 0; i < names.length(); ++i) {
1318 4325 : Variable* var = LookupLocal(names.at(i));
1319 1619 : if (var != nullptr) {
1320 : // Conflict; find and return its declaration.
1321 : DCHECK(IsLexicalVariableMode(var->mode()));
1322 532 : const AstRawString* name = names.at(i);
1323 2156 : for (Declaration* decl : decls_) {
1324 812 : if (decl->proxy()->raw_name() == name) return decl;
1325 : }
1326 : DCHECK(false);
1327 : }
1328 : }
1329 : return nullptr;
1330 : }
1331 :
1332 2876570 : void DeclarationScope::AllocateVariables(ParseInfo* info, Isolate* isolate,
1333 : AnalyzeMode mode) {
1334 : // Module variables must be allocated before variable resolution
1335 : // to ensure that AccessNeedsHoleCheck() can detect import variables.
1336 4336389 : if (is_module_scope()) AsModuleScope()->AllocateModuleVariables();
1337 :
1338 2876570 : ResolveVariablesRecursively(info);
1339 2876580 : AllocateVariablesRecursively();
1340 :
1341 : MaybeHandle<ScopeInfo> outer_scope;
1342 2876581 : if (outer_scope_ != nullptr) outer_scope = outer_scope_->scope_info_;
1343 :
1344 2876581 : AllocateScopeInfosRecursively(isolate, outer_scope);
1345 2876581 : if (mode == AnalyzeMode::kDebugger) {
1346 194942 : AllocateDebuggerScopeInfos(isolate, outer_scope);
1347 : }
1348 : // The debugger expects all shared function infos to contain a scope info.
1349 : // Since the top-most scope will end up in a shared function info, make sure
1350 : // it has one, even if it doesn't need a scope info.
1351 : // TODO(jochen|yangguo): Remove this requirement.
1352 2876581 : if (scope_info_.is_null()) {
1353 2919638 : scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
1354 : }
1355 2876582 : }
1356 :
1357 8492807 : bool Scope::AllowsLazyParsingWithoutUnresolvedVariables(
1358 : const Scope* outer) const {
1359 : // If none of the outer scopes need to decide whether to context allocate
1360 : // specific variables, we can preparse inner functions without unresolved
1361 : // variables. Otherwise we need to find unresolved variables to force context
1362 : // allocation of the matching declarations. We can stop at the outer scope for
1363 : // the parse, since context allocation of those variables is already
1364 : // guaranteed to be correct.
1365 8545520 : for (const Scope* s = this; s != outer; s = s->outer_scope_) {
1366 : // Eval forces context allocation on all outer scopes, so we don't need to
1367 : // look at those scopes. Sloppy eval makes top-level non-lexical variables
1368 : // dynamic, whereas strict-mode requires context allocation.
1369 6738932 : if (s->is_eval_scope()) return is_sloppy(s->language_mode());
1370 : // Catch scopes force context allocation of all variables.
1371 5212132 : if (s->is_catch_scope()) continue;
1372 : // With scopes do not introduce variables that need allocation.
1373 5211626 : if (s->is_with_scope()) continue;
1374 : // If everything is guaranteed to be context allocated we can ignore the
1375 : // scope.
1376 5211170 : if (s->has_forced_context_allocation()) continue;
1377 : // Only block scopes and function scopes should disallow preparsing.
1378 : DCHECK(s->is_block_scope() || s->is_function_scope());
1379 : return false;
1380 : }
1381 : return true;
1382 : }
1383 :
1384 7235378 : bool DeclarationScope::AllowsLazyCompilation() const {
1385 7235378 : return !force_eager_compilation_;
1386 : }
1387 :
1388 6901825 : int Scope::ContextChainLength(Scope* scope) const {
1389 : int n = 0;
1390 9064220 : for (const Scope* s = this; s != scope; s = s->outer_scope_) {
1391 : DCHECK(s != NULL); // scope must be in the scope chain
1392 2162395 : if (s->NeedsContext()) n++;
1393 : }
1394 6901825 : return n;
1395 : }
1396 :
1397 463047 : int Scope::ContextChainLengthUntilOutermostSloppyEval() const {
1398 : int result = 0;
1399 : int length = 0;
1400 :
1401 1909897 : for (const Scope* s = this; s != nullptr; s = s->outer_scope()) {
1402 1446850 : if (!s->NeedsContext()) continue;
1403 1046258 : length++;
1404 1046258 : if (s->calls_sloppy_eval()) result = length;
1405 : }
1406 :
1407 463047 : return result;
1408 : }
1409 :
1410 2424070 : int Scope::MaxNestedContextChainLength() {
1411 2424070 : int max_context_chain_length = 0;
1412 6360240 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1413 3936170 : if (scope->is_function_scope()) continue;
1414 346610 : max_context_chain_length = std::max(scope->MaxNestedContextChainLength(),
1415 693220 : max_context_chain_length);
1416 : }
1417 2424070 : if (NeedsContext()) {
1418 379809 : max_context_chain_length += 1;
1419 : }
1420 2424070 : return max_context_chain_length;
1421 : }
1422 :
1423 20942412 : DeclarationScope* Scope::GetDeclarationScope() {
1424 14016479 : Scope* scope = this;
1425 62457070 : while (!scope->is_declaration_scope()) {
1426 : scope = scope->outer_scope();
1427 : }
1428 20942412 : return scope->AsDeclarationScope();
1429 : }
1430 :
1431 0 : const DeclarationScope* Scope::GetClosureScope() const {
1432 0 : const Scope* scope = this;
1433 0 : while (!scope->is_declaration_scope() || scope->is_block_scope()) {
1434 : scope = scope->outer_scope();
1435 : }
1436 0 : return scope->AsDeclarationScope();
1437 : }
1438 :
1439 1315214 : DeclarationScope* Scope::GetClosureScope() {
1440 436714521 : Scope* scope = this;
1441 720982429 : while (!scope->is_declaration_scope() || scope->is_block_scope()) {
1442 : scope = scope->outer_scope();
1443 : }
1444 1315214 : return scope->AsDeclarationScope();
1445 : }
1446 :
1447 4267312 : bool Scope::NeedsScopeInfo() const {
1448 : DCHECK(!already_resolved_);
1449 : DCHECK(GetClosureScope()->ShouldEagerCompile());
1450 : // The debugger expects all functions to have scope infos.
1451 : // TODO(jochen|yangguo): Remove this requirement.
1452 4267312 : if (is_function_scope()) return true;
1453 0 : return NeedsContext();
1454 : }
1455 :
1456 0 : ModuleScope* Scope::GetModuleScope() {
1457 0 : Scope* scope = this;
1458 : DCHECK(!scope->is_script_scope());
1459 0 : while (!scope->is_module_scope()) {
1460 : scope = scope->outer_scope();
1461 : DCHECK_NOT_NULL(scope);
1462 : }
1463 0 : return scope->AsModuleScope();
1464 : }
1465 :
1466 60795 : DeclarationScope* Scope::GetReceiverScope() {
1467 18231 : Scope* scope = this;
1468 218847 : while (!scope->is_script_scope() &&
1469 57047 : (!scope->is_function_scope() ||
1470 : scope->AsDeclarationScope()->is_arrow_scope())) {
1471 : scope = scope->outer_scope();
1472 : }
1473 60795 : return scope->AsDeclarationScope();
1474 : }
1475 :
1476 7826979 : Scope* Scope::GetOuterScopeWithContext() {
1477 10002742 : Scope* scope = outer_scope_;
1478 27085543 : while (scope && !scope->NeedsContext()) {
1479 : scope = scope->outer_scope();
1480 : }
1481 7826979 : return scope;
1482 : }
1483 :
1484 195620 : Handle<StringSet> DeclarationScope::CollectNonLocals(
1485 : ParseInfo* info, Handle<StringSet> non_locals) {
1486 195620 : VariableProxy* free_variables = FetchFreeVariables(this, info);
1487 2812582 : for (VariableProxy* proxy = free_variables; proxy != nullptr;
1488 : proxy = proxy->next_unresolved()) {
1489 2616962 : non_locals = StringSet::Add(non_locals, proxy->name());
1490 : }
1491 195620 : return non_locals;
1492 : }
1493 :
1494 1384502 : void DeclarationScope::ResetAfterPreparsing(AstValueFactory* ast_value_factory,
1495 : bool aborted) {
1496 : DCHECK(is_function_scope());
1497 :
1498 : // Reset all non-trivial members.
1499 1384502 : if (!aborted || !IsArrowFunction(function_kind_)) {
1500 : // Do not remove parameters when lazy parsing an Arrow Function has failed,
1501 : // as the formal parameters are not re-parsed.
1502 : params_.Clear();
1503 : }
1504 : decls_.Clear();
1505 : locals_.Clear();
1506 1384450 : inner_scope_ = nullptr;
1507 1384450 : unresolved_ = nullptr;
1508 1384450 : sloppy_block_function_map_ = nullptr;
1509 :
1510 1384450 : if (aborted) {
1511 : // Prepare scope for use in the outer zone.
1512 52 : zone_ = ast_value_factory->zone();
1513 52 : variables_.Reset(ZoneAllocationPolicy(zone_));
1514 104 : if (!IsArrowFunction(function_kind_)) {
1515 44 : DeclareDefaultFunctionVariables(ast_value_factory);
1516 : }
1517 : } else {
1518 : // Make sure this scope isn't used for allocation anymore.
1519 1384398 : zone_ = nullptr;
1520 : variables_.Invalidate();
1521 : }
1522 :
1523 : #ifdef DEBUG
1524 : needs_migration_ = false;
1525 : is_being_lazily_parsed_ = false;
1526 : #endif
1527 :
1528 1384450 : was_lazily_parsed_ = !aborted;
1529 1384450 : }
1530 :
1531 1355757 : void DeclarationScope::AnalyzePartially(
1532 3890462 : AstNodeFactory* ast_node_factory,
1533 14815 : PreParsedScopeData* preparsed_scope_data) {
1534 : DCHECK(!force_eager_compilation_);
1535 : VariableProxy* unresolved = nullptr;
1536 :
1537 1355757 : if (!outer_scope_->is_script_scope()) {
1538 : // Try to resolve unresolved variables for this Scope and migrate those
1539 : // which cannot be resolved inside. It doesn't make sense to try to resolve
1540 : // them in the outer Scopes here, because they are incomplete.
1541 3134965 : for (VariableProxy* proxy = FetchFreeVariables(this); proxy != nullptr;
1542 : proxy = proxy->next_unresolved()) {
1543 : DCHECK(!proxy->is_resolved());
1544 : VariableProxy* copy = ast_node_factory->CopyVariableProxy(proxy);
1545 : copy->set_next_unresolved(unresolved);
1546 : unresolved = copy;
1547 : }
1548 :
1549 : // Clear arguments_ if unused. This is used as a signal for optimization.
1550 1730330 : if (arguments_ != nullptr &&
1551 541421 : !(MustAllocate(arguments_) && !has_arguments_parameter_)) {
1552 518206 : arguments_ = nullptr;
1553 : }
1554 :
1555 615075 : if (FLAG_experimental_preparser_scope_analysis &&
1556 : preparsed_scope_data->Producing()) {
1557 : // Store the information needed for allocating the locals of this scope
1558 : // and its inner scopes.
1559 14801 : preparsed_scope_data->SaveData(this);
1560 : }
1561 : }
1562 : #ifdef DEBUG
1563 : if (FLAG_print_scopes) {
1564 : PrintF("Inner function scope:\n");
1565 : Print();
1566 : }
1567 : #endif
1568 :
1569 1355757 : ResetAfterPreparsing(ast_node_factory->ast_value_factory(), false);
1570 :
1571 1355757 : unresolved_ = unresolved;
1572 1355757 : }
1573 :
1574 : #ifdef DEBUG
1575 : namespace {
1576 :
1577 : const char* Header(ScopeType scope_type, FunctionKind function_kind,
1578 : bool is_declaration_scope) {
1579 : switch (scope_type) {
1580 : case EVAL_SCOPE: return "eval";
1581 : // TODO(adamk): Should we print concise method scopes specially?
1582 : case FUNCTION_SCOPE:
1583 : if (IsGeneratorFunction(function_kind)) return "function*";
1584 : if (IsAsyncFunction(function_kind)) return "async function";
1585 : if (IsArrowFunction(function_kind)) return "arrow";
1586 : return "function";
1587 : case MODULE_SCOPE: return "module";
1588 : case SCRIPT_SCOPE: return "global";
1589 : case CATCH_SCOPE: return "catch";
1590 : case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block";
1591 : case WITH_SCOPE: return "with";
1592 : }
1593 : UNREACHABLE();
1594 : return NULL;
1595 : }
1596 :
1597 : void Indent(int n, const char* str) { PrintF("%*s%s", n, "", str); }
1598 :
1599 : void PrintName(const AstRawString* name) {
1600 : PrintF("%.*s", name->length(), name->raw_data());
1601 : }
1602 :
1603 : void PrintLocation(Variable* var) {
1604 : switch (var->location()) {
1605 : case VariableLocation::UNALLOCATED:
1606 : break;
1607 : case VariableLocation::PARAMETER:
1608 : PrintF("parameter[%d]", var->index());
1609 : break;
1610 : case VariableLocation::LOCAL:
1611 : PrintF("local[%d]", var->index());
1612 : break;
1613 : case VariableLocation::CONTEXT:
1614 : PrintF("context[%d]", var->index());
1615 : break;
1616 : case VariableLocation::LOOKUP:
1617 : PrintF("lookup");
1618 : break;
1619 : case VariableLocation::MODULE:
1620 : PrintF("module");
1621 : break;
1622 : }
1623 : }
1624 :
1625 : void PrintVar(int indent, Variable* var) {
1626 : Indent(indent, VariableMode2String(var->mode()));
1627 : PrintF(" ");
1628 : if (var->raw_name()->IsEmpty())
1629 : PrintF(".%p", reinterpret_cast<void*>(var));
1630 : else
1631 : PrintName(var->raw_name());
1632 : PrintF("; // (%p) ", reinterpret_cast<void*>(var));
1633 : PrintLocation(var);
1634 : bool comma = !var->IsUnallocated();
1635 : if (var->has_forced_context_allocation()) {
1636 : if (comma) PrintF(", ");
1637 : PrintF("forced context allocation");
1638 : comma = true;
1639 : }
1640 : if (var->maybe_assigned() == kNotAssigned) {
1641 : if (comma) PrintF(", ");
1642 : PrintF("never assigned");
1643 : }
1644 : PrintF("\n");
1645 : }
1646 :
1647 : void PrintMap(int indent, const char* label, VariableMap* map, bool locals,
1648 : Variable* function_var) {
1649 : bool printed_label = false;
1650 : for (VariableMap::Entry* p = map->Start(); p != nullptr; p = map->Next(p)) {
1651 : Variable* var = reinterpret_cast<Variable*>(p->value);
1652 : if (var == function_var) continue;
1653 : if (var == kDummyPreParserVariable ||
1654 : var == kDummyPreParserLexicalVariable) {
1655 : continue;
1656 : }
1657 : bool local = !IsDynamicVariableMode(var->mode());
1658 : if ((locals ? local : !local) &&
1659 : (var->is_used() || !var->IsUnallocated())) {
1660 : if (!printed_label) {
1661 : Indent(indent, label);
1662 : printed_label = true;
1663 : }
1664 : PrintVar(indent, var);
1665 : }
1666 : }
1667 : }
1668 :
1669 : } // anonymous namespace
1670 :
1671 : void DeclarationScope::PrintParameters() {
1672 : PrintF(" (");
1673 : for (int i = 0; i < params_.length(); i++) {
1674 : if (i > 0) PrintF(", ");
1675 : const AstRawString* name = params_[i]->raw_name();
1676 : if (name->IsEmpty())
1677 : PrintF(".%p", reinterpret_cast<void*>(params_[i]));
1678 : else
1679 : PrintName(name);
1680 : }
1681 : PrintF(")");
1682 : }
1683 :
1684 : void Scope::Print(int n) {
1685 : int n0 = (n > 0 ? n : 0);
1686 : int n1 = n0 + 2; // indentation
1687 :
1688 : // Print header.
1689 : FunctionKind function_kind = is_function_scope()
1690 : ? AsDeclarationScope()->function_kind()
1691 : : kNormalFunction;
1692 : Indent(n0, Header(scope_type_, function_kind, is_declaration_scope()));
1693 : if (scope_name_ != nullptr && !scope_name_->IsEmpty()) {
1694 : PrintF(" ");
1695 : PrintName(scope_name_);
1696 : }
1697 :
1698 : // Print parameters, if any.
1699 : Variable* function = nullptr;
1700 : if (is_function_scope()) {
1701 : AsDeclarationScope()->PrintParameters();
1702 : function = AsDeclarationScope()->function_var();
1703 : }
1704 :
1705 : PrintF(" { // (%p) (%d, %d)\n", reinterpret_cast<void*>(this),
1706 : start_position(), end_position());
1707 : if (is_hidden()) {
1708 : Indent(n1, "// is hidden\n");
1709 : }
1710 :
1711 : // Function name, if any (named function literals, only).
1712 : if (function != nullptr) {
1713 : Indent(n1, "// (local) function name: ");
1714 : PrintName(function->raw_name());
1715 : PrintF("\n");
1716 : }
1717 :
1718 : // Scope info.
1719 : if (is_strict(language_mode())) {
1720 : Indent(n1, "// strict mode scope\n");
1721 : }
1722 : if (IsAsmModule()) Indent(n1, "// scope is an asm module\n");
1723 : if (IsAsmFunction()) Indent(n1, "// scope is an asm function\n");
1724 : if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n");
1725 : if (is_declaration_scope() && AsDeclarationScope()->uses_super_property()) {
1726 : Indent(n1, "// scope uses 'super' property\n");
1727 : }
1728 : if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n");
1729 : if (is_declaration_scope()) {
1730 : DeclarationScope* scope = AsDeclarationScope();
1731 : if (scope->was_lazily_parsed()) Indent(n1, "// lazily parsed\n");
1732 : if (scope->ShouldEagerCompile()) Indent(n1, "// will be compiled\n");
1733 : }
1734 : if (has_forced_context_allocation()) {
1735 : Indent(n1, "// forces context allocation\n");
1736 : }
1737 : if (num_stack_slots_ > 0) {
1738 : Indent(n1, "// ");
1739 : PrintF("%d stack slots\n", num_stack_slots_);
1740 : }
1741 : if (num_heap_slots_ > 0) {
1742 : Indent(n1, "// ");
1743 : PrintF("%d heap slots\n", num_heap_slots_);
1744 : }
1745 :
1746 : // Print locals.
1747 : if (function != nullptr) {
1748 : Indent(n1, "// function var:\n");
1749 : PrintVar(n1, function);
1750 : }
1751 :
1752 : // Print temporaries.
1753 : {
1754 : bool printed_header = false;
1755 : for (Variable* local : locals_) {
1756 : if (local->mode() != TEMPORARY) continue;
1757 : if (!printed_header) {
1758 : printed_header = true;
1759 : Indent(n1, "// temporary vars:\n");
1760 : }
1761 : PrintVar(n1, local);
1762 : }
1763 : }
1764 :
1765 : if (variables_.occupancy() > 0) {
1766 : PrintMap(n1, "// local vars:\n", &variables_, true, function);
1767 : PrintMap(n1, "// dynamic vars:\n", &variables_, false, function);
1768 : }
1769 :
1770 : // Print inner scopes (disable by providing negative n).
1771 : if (n >= 0) {
1772 : for (Scope* scope = inner_scope_; scope != nullptr;
1773 : scope = scope->sibling_) {
1774 : PrintF("\n");
1775 : scope->Print(n1);
1776 : }
1777 : }
1778 :
1779 : Indent(n0, "}\n");
1780 : }
1781 :
1782 : void Scope::CheckScopePositions() {
1783 : // Visible leaf scopes must have real positions.
1784 : if (!is_hidden() && inner_scope_ == nullptr) {
1785 : CHECK_NE(kNoSourcePosition, start_position());
1786 : CHECK_NE(kNoSourcePosition, end_position());
1787 : }
1788 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1789 : scope->CheckScopePositions();
1790 : }
1791 : }
1792 :
1793 : void Scope::CheckZones() {
1794 : DCHECK(!needs_migration_);
1795 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1796 : if (scope->is_declaration_scope() &&
1797 : scope->AsDeclarationScope()->was_lazily_parsed()) {
1798 : DCHECK_NULL(scope->zone());
1799 : DCHECK_NULL(scope->inner_scope_);
1800 : continue;
1801 : }
1802 : CHECK_EQ(scope->zone(), zone());
1803 : scope->CheckZones();
1804 : }
1805 : }
1806 : #endif // DEBUG
1807 :
1808 1796790 : Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
1809 : // Declare a new non-local.
1810 : DCHECK(IsDynamicVariableMode(mode));
1811 1796790 : Variable* var = variables_.Declare(zone(), nullptr, name, mode);
1812 : // Allocate it by giving it a dynamic lookup.
1813 : var->AllocateTo(VariableLocation::LOOKUP, -1);
1814 898395 : return var;
1815 : }
1816 :
1817 138662785 : Variable* Scope::LookupRecursive(VariableProxy* proxy, Scope* outer_scope_end) {
1818 : DCHECK_NE(outer_scope_end, this);
1819 : // Short-cut: whenever we find a debug-evaluate scope, just look everything up
1820 : // dynamically. Debug-evaluate doesn't properly create scope info for the
1821 : // lookups it does. It may not have a valid 'this' declaration, and anything
1822 : // accessed through debug-evaluate might invalidly resolve to stack-allocated
1823 : // variables.
1824 : // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the
1825 : // scopes in which it's evaluating.
1826 110844551 : if (is_debug_evaluate_scope_) return NonLocal(proxy->raw_name(), DYNAMIC);
1827 :
1828 : // Try to find the variable in this scope.
1829 110815633 : Variable* var = LookupLocal(proxy->raw_name());
1830 :
1831 : // We found a variable and we are done. (Even if there is an 'eval' in this
1832 : // scope which introduces the same variable again, the resulting variable
1833 : // remains the same.)
1834 110815655 : if (var != nullptr) return var;
1835 :
1836 28041063 : if (outer_scope_ == outer_scope_end) {
1837 : // We may just be trying to find all free variables. In that case, don't
1838 : // declare them in the outer scope.
1839 7622904 : if (!is_script_scope()) return nullptr;
1840 : // No binding has been found. Declare a variable on the global object.
1841 : return AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(),
1842 2471237 : NORMAL_VARIABLE);
1843 : }
1844 :
1845 : DCHECK(!is_script_scope());
1846 :
1847 20418159 : var = outer_scope_->LookupRecursive(proxy, outer_scope_end);
1848 :
1849 : // The variable could not be resolved statically.
1850 20418163 : if (var == nullptr) return var;
1851 :
1852 : // TODO(marja): Separate LookupRecursive for preparsed scopes better.
1853 20274522 : if (var == kDummyPreParserVariable || var == kDummyPreParserLexicalVariable) {
1854 : DCHECK(GetDeclarationScope()->is_being_lazily_parsed());
1855 : DCHECK(FLAG_lazy_inner_functions);
1856 : return var;
1857 : }
1858 :
1859 37151566 : if (is_function_scope() && !var->is_dynamic()) {
1860 : var->ForceContextAllocation();
1861 : }
1862 : // "this" can't be shadowed by "eval"-introduced bindings or by "with"
1863 : // scopes.
1864 : // TODO(wingo): There are other variables in this category; add them.
1865 20202462 : if (var->is_this()) return var;
1866 :
1867 19929814 : if (is_with_scope()) {
1868 : // The current scope is a with scope, so the variable binding can not be
1869 : // statically resolved. However, note that it was necessary to do a lookup
1870 : // in the outer scope anyway, because if a binding exists in an outer
1871 : // scope, the associated variable has to be marked as potentially being
1872 : // accessed from inside of an inner with scope (the property may not be in
1873 : // the 'with' object).
1874 24434 : if (!var->is_dynamic() && var->IsUnallocated()) {
1875 : DCHECK(!already_resolved_);
1876 : var->set_is_used();
1877 : var->ForceContextAllocation();
1878 7327 : if (proxy->is_assigned()) var->set_maybe_assigned();
1879 : }
1880 16833 : return NonLocal(proxy->raw_name(), DYNAMIC);
1881 : }
1882 :
1883 20856833 : if (calls_sloppy_eval() && is_declaration_scope()) {
1884 : // A variable binding may have been found in an outer scope, but the current
1885 : // scope makes a sloppy 'eval' call, so the found variable may not be the
1886 : // correct one (the 'eval' may introduce a binding with the same name). In
1887 : // that case, change the lookup result to reflect this situation. Only
1888 : // scopes that can host var bindings (declaration scopes) need be considered
1889 : // here (this excludes block and catch scopes), and variable lookups at
1890 : // script scope are always dynamic.
1891 939790 : if (var->IsGlobalObjectProperty()) {
1892 735941 : return NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL);
1893 : }
1894 :
1895 203849 : if (var->is_dynamic()) return var;
1896 :
1897 : Variable* invalidated = var;
1898 64846 : var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL);
1899 : var->set_local_if_not_shadowed(invalidated);
1900 : }
1901 :
1902 19038037 : return var;
1903 : }
1904 :
1905 65603090 : void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) {
1906 : DCHECK(info->script_scope()->is_script_scope());
1907 : DCHECK(!proxy->is_resolved());
1908 65603090 : Variable* var = LookupRecursive(proxy, nullptr);
1909 65603104 : ResolveTo(info, proxy, var);
1910 65603094 : }
1911 :
1912 : namespace {
1913 :
1914 80177453 : bool AccessNeedsHoleCheck(Variable* var, VariableProxy* proxy, Scope* scope) {
1915 76972928 : if (var->mode() == DYNAMIC_LOCAL) {
1916 : // Dynamically introduced variables never need a hole check (since they're
1917 : // VAR bindings, either from var or function declarations), but the variable
1918 : // they shadow might need a hole check, which we want to do if we decide
1919 : // that no shadowing variable was dynamically introoduced.
1920 : DCHECK(!var->binding_needs_init());
1921 65435 : return AccessNeedsHoleCheck(var->local_if_not_shadowed(), proxy, scope);
1922 : }
1923 :
1924 76907493 : if (!var->binding_needs_init()) {
1925 : return false;
1926 : }
1927 :
1928 : // It's impossible to eliminate module import hole checks here, because it's
1929 : // unknown at compilation time whether the binding referred to in the
1930 : // exporting module itself requires hole checks.
1931 1861078 : if (var->location() == VariableLocation::MODULE && !var->IsExport()) {
1932 : return true;
1933 : }
1934 :
1935 : // Check if the binding really needs an initialization check. The check
1936 : // can be skipped in the following situation: we have a LET or CONST
1937 : // binding, both the Variable and the VariableProxy have the same
1938 : // declaration scope (i.e. they are both in global code, in the
1939 : // same function or in the same eval code), the VariableProxy is in
1940 : // the source physically located after the initializer of the variable,
1941 : // and that the initializer cannot be skipped due to a nonlinear scope.
1942 : //
1943 : // The condition on the declaration scopes is a conservative check for
1944 : // nested functions that access a binding and are called before the
1945 : // binding is initialized:
1946 : // function() { f(); let x = 1; function f() { x = 2; } }
1947 : //
1948 : // The check cannot be skipped on non-linear scopes, namely switch
1949 : // scopes, to ensure tests are done in cases like the following:
1950 : // switch (1) { case 0: let x = 2; case 1: f(x); }
1951 : // The scope of the variable needs to be checked, in case the use is
1952 : // in a sub-block which may be linear.
1953 1858419 : if (var->scope()->GetDeclarationScope() != scope->GetDeclarationScope()) {
1954 : return true;
1955 : }
1956 :
1957 1405412 : if (var->is_this()) {
1958 : DCHECK(IsDerivedConstructor(scope->GetDeclarationScope()->function_kind()));
1959 : // TODO(littledan): implement 'this' hole check elimination.
1960 : return true;
1961 : }
1962 :
1963 : // We should always have valid source positions.
1964 : DCHECK(var->initializer_position() != kNoSourcePosition);
1965 : DCHECK(proxy->position() != kNoSourcePosition);
1966 :
1967 2692333 : return var->scope()->is_nonlinear() ||
1968 2692333 : var->initializer_position() >= proxy->position();
1969 : }
1970 :
1971 : } // anonymous namespace
1972 :
1973 76907493 : void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) {
1974 : #ifdef DEBUG
1975 : if (info->script_is_native()) {
1976 : // To avoid polluting the global object in native scripts
1977 : // - Variables must not be allocated to the global scope.
1978 : CHECK_NOT_NULL(outer_scope());
1979 : // - Variables must be bound locally or unallocated.
1980 : if (var->IsGlobalObjectProperty()) {
1981 : // The following variable name may be minified. If so, disable
1982 : // minification in js2c.py for better output.
1983 : Handle<String> name = proxy->raw_name()->string();
1984 : V8_Fatal(__FILE__, __LINE__, "Unbound variable: '%s' in native script.",
1985 : name->ToCString().get());
1986 : }
1987 : VariableLocation location = var->location();
1988 : CHECK(location == VariableLocation::LOCAL ||
1989 : location == VariableLocation::CONTEXT ||
1990 : location == VariableLocation::PARAMETER ||
1991 : location == VariableLocation::UNALLOCATED);
1992 : }
1993 : #endif
1994 :
1995 : DCHECK_NOT_NULL(var);
1996 76907493 : if (AccessNeedsHoleCheck(var, proxy, this)) proxy->set_needs_hole_check();
1997 76907492 : proxy->BindTo(var);
1998 76907490 : }
1999 :
2000 12842037 : void Scope::ResolveVariablesRecursively(ParseInfo* info) {
2001 : DCHECK(info->script_scope()->is_script_scope());
2002 : // Lazy parsed declaration scopes are already partially analyzed. If there are
2003 : // unresolved references remaining, they just need to be resolved in outer
2004 : // scopes.
2005 19741802 : if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
2006 : DCHECK(variables_.occupancy() == 0);
2007 5919528 : for (VariableProxy* proxy = unresolved_; proxy != nullptr;
2008 : proxy = proxy->next_unresolved()) {
2009 2491455 : Variable* var = outer_scope()->LookupRecursive(proxy, nullptr);
2010 2491455 : if (!var->is_dynamic()) {
2011 : var->set_is_used();
2012 : var->ForceContextAllocation();
2013 2136980 : if (proxy->is_assigned()) var->set_maybe_assigned();
2014 : }
2015 : }
2016 : } else {
2017 : // Resolve unresolved variables for this scope.
2018 74662583 : for (VariableProxy* proxy = unresolved_; proxy != nullptr;
2019 : proxy = proxy->next_unresolved()) {
2020 65603091 : ResolveVariable(info, proxy);
2021 : }
2022 :
2023 : // Resolve unresolved variables for inner scopes.
2024 16533507 : for (Scope* scope = inner_scope_; scope != nullptr;
2025 : scope = scope->sibling_) {
2026 7474009 : scope->ResolveVariablesRecursively(info);
2027 : }
2028 : }
2029 10350591 : }
2030 :
2031 1411012 : VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope,
2032 : ParseInfo* info,
2033 1060025 : VariableProxy* stack) {
2034 : // Module variables must be allocated before variable resolution
2035 : // to ensure that AccessNeedsHoleCheck() can detect import variables.
2036 2114901 : if (info != nullptr && is_module_scope()) {
2037 468 : AsModuleScope()->AllocateModuleVariables();
2038 : }
2039 : // Lazy parsed declaration scopes are already partially analyzed. If there are
2040 : // unresolved references remaining, they just need to be resolved in outer
2041 : // scopes.
2042 : Scope* lookup =
2043 1229511 : is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()
2044 : ? outer_scope()
2045 1767148 : : this;
2046 25184837 : for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr;
2047 : proxy = next) {
2048 : next = proxy->next_unresolved();
2049 : DCHECK(!proxy->is_resolved());
2050 : Variable* var =
2051 22317517 : lookup->LookupRecursive(proxy, max_outer_scope->outer_scope());
2052 22317517 : if (var == nullptr) {
2053 : proxy->set_next_unresolved(stack);
2054 : stack = proxy;
2055 28573773 : } else if (var != kDummyPreParserVariable &&
2056 11407923 : var != kDummyPreParserLexicalVariable) {
2057 11349687 : if (info != nullptr) {
2058 : // In this case we need to leave scopes in a way that they can be
2059 : // allocated. If we resolved variables from lazy parsed scopes, we need
2060 : // to context allocate the var.
2061 11304391 : ResolveTo(info, proxy, var);
2062 11304391 : if (!var->is_dynamic() && lookup != this) var->ForceContextAllocation();
2063 : } else {
2064 : var->set_is_used();
2065 45296 : if (proxy->is_assigned()) {
2066 : var->set_maybe_assigned();
2067 : }
2068 : }
2069 : }
2070 : }
2071 :
2072 : // Clear unresolved_ as it's in an inconsistent state.
2073 1411012 : unresolved_ = nullptr;
2074 :
2075 2026144 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
2076 615132 : stack = scope->FetchFreeVariables(max_outer_scope, info, stack);
2077 : }
2078 :
2079 1411012 : return stack;
2080 : }
2081 :
2082 230474141 : bool Scope::MustAllocate(Variable* var) {
2083 61500814 : if (var == kDummyPreParserLexicalVariable || var == kDummyPreParserVariable) {
2084 : return true;
2085 : }
2086 : DCHECK(var->location() != VariableLocation::MODULE);
2087 : // Give var a read/write use if there is a chance it might be accessed
2088 : // via an eval() call. This is only possible if the variable has a
2089 : // visible name.
2090 175414708 : if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
2091 56823447 : (inner_scope_calls_eval_ || is_catch_scope() || is_script_scope())) {
2092 : var->set_is_used();
2093 5326493 : if (inner_scope_calls_eval_) var->set_maybe_assigned();
2094 : }
2095 : DCHECK(!var->has_forced_context_allocation() || var->is_used());
2096 : // Global variables do not need to be allocated.
2097 121237572 : return !var->IsGlobalObjectProperty() && var->is_used();
2098 : }
2099 :
2100 :
2101 83505067 : bool Scope::MustAllocateInContext(Variable* var) {
2102 : // If var is accessed from an inner scope, or if there is a possibility
2103 : // that it might be accessed from the current or an inner scope (through
2104 : // an eval() call or a runtime with lookup), it must be allocated in the
2105 : // context.
2106 : //
2107 : // Exceptions: If the scope as a whole has forced context allocation, all
2108 : // variables will have context allocation, even temporaries. Otherwise
2109 : // temporary variables are always stack-allocated. Catch-bound variables are
2110 : // always context-allocated.
2111 28824445 : if (has_forced_context_allocation()) return true;
2112 28629805 : if (var->mode() == TEMPORARY) return false;
2113 26050817 : if (is_catch_scope()) return true;
2114 26457910 : if ((is_script_scope() || is_eval_scope()) &&
2115 : IsLexicalVariableMode(var->mode())) {
2116 : return true;
2117 : }
2118 25339197 : return var->has_forced_context_allocation() || inner_scope_calls_eval_;
2119 : }
2120 :
2121 :
2122 13874770 : void Scope::AllocateStackSlot(Variable* var) {
2123 13874770 : if (is_block_scope()) {
2124 447039 : outer_scope()->GetDeclarationScope()->AllocateStackSlot(var);
2125 : } else {
2126 13427731 : var->AllocateTo(VariableLocation::LOCAL, num_stack_slots_++);
2127 : }
2128 13427731 : }
2129 :
2130 :
2131 0 : void Scope::AllocateHeapSlot(Variable* var) {
2132 5022232 : var->AllocateTo(VariableLocation::CONTEXT, num_heap_slots_++);
2133 0 : }
2134 :
2135 6529626 : void DeclarationScope::AllocateParameterLocals() {
2136 : DCHECK(is_function_scope());
2137 :
2138 : bool uses_sloppy_arguments = false;
2139 :
2140 6529626 : if (arguments_ != nullptr) {
2141 : DCHECK(!is_arrow_scope());
2142 : // 'arguments' is used. Unless there is also a parameter called
2143 : // 'arguments', we must be conservative and allocate all parameters to
2144 : // the context assuming they will be captured by the arguments object.
2145 : // If we have a parameter named 'arguments', a (new) value is always
2146 : // assigned to it via the function invocation. Then 'arguments' denotes
2147 : // that specific parameter value and cannot be used to access the
2148 : // parameters, which is why we don't need to allocate an arguments
2149 : // object in that case.
2150 5892758 : if (MustAllocate(arguments_) && !has_arguments_parameter_) {
2151 : // In strict mode 'arguments' does not alias formal parameters.
2152 : // Therefore in strict mode we allocate parameters as if 'arguments'
2153 : // were not used.
2154 : // If the parameter list is not simple, arguments isn't sloppy either.
2155 : uses_sloppy_arguments =
2156 452289 : is_sloppy(language_mode()) && has_simple_parameters();
2157 : } else {
2158 : // 'arguments' is unused. Tell the code generator that it does not need to
2159 : // allocate the arguments object by nulling out arguments_.
2160 5631012 : arguments_ = nullptr;
2161 : }
2162 : }
2163 :
2164 : // The same parameter may occur multiple times in the parameters_ list.
2165 : // If it does, and if it is not copied into the context object, it must
2166 : // receive the highest parameter index for that parameter; thus iteration
2167 : // order is relevant!
2168 14956609 : for (int i = num_parameters() - 1; i >= 0; --i) {
2169 16853950 : Variable* var = params_[i];
2170 : DCHECK(!has_rest_ || var != rest_parameter());
2171 : DCHECK_EQ(this, var->scope());
2172 8426975 : if (uses_sloppy_arguments) {
2173 : var->set_is_used();
2174 : var->set_maybe_assigned();
2175 : var->ForceContextAllocation();
2176 : }
2177 8426975 : AllocateParameter(var, i);
2178 : }
2179 6529634 : }
2180 :
2181 14367995 : void DeclarationScope::AllocateParameter(Variable* var, int index) {
2182 14367995 : if (MustAllocate(var)) {
2183 11221314 : if (MustAllocateInContext(var)) {
2184 : DCHECK(var->IsUnallocated() || var->IsContextSlot());
2185 844695 : if (var->IsUnallocated()) {
2186 : AllocateHeapSlot(var);
2187 : }
2188 : } else {
2189 : DCHECK(var->IsUnallocated() || var->IsParameter());
2190 10376619 : if (var->IsUnallocated()) {
2191 : var->AllocateTo(VariableLocation::PARAMETER, index);
2192 : }
2193 : }
2194 : }
2195 14367996 : }
2196 :
2197 14073158 : void DeclarationScope::AllocateReceiver() {
2198 16264272 : if (!has_this_declaration()) return;
2199 : DCHECK_NOT_NULL(receiver());
2200 : DCHECK_EQ(receiver()->scope(), this);
2201 5941022 : AllocateParameter(receiver(), -1);
2202 : }
2203 :
2204 45517160 : void Scope::AllocateNonParameterLocal(Variable* var) {
2205 : DCHECK(var->scope() == this);
2206 45517160 : if (var->IsUnallocated() && MustAllocate(var)) {
2207 17600683 : if (MustAllocateInContext(var)) {
2208 : AllocateHeapSlot(var);
2209 : } else {
2210 13427733 : AllocateStackSlot(var);
2211 : }
2212 : }
2213 45517163 : }
2214 :
2215 9108971 : void Scope::AllocateNonParameterLocalsAndDeclaredGlobals() {
2216 62833625 : for (Variable* local : locals_) {
2217 44615682 : AllocateNonParameterLocal(local);
2218 : }
2219 :
2220 9108972 : if (is_declaration_scope()) {
2221 8132147 : AsDeclarationScope()->AllocateLocals();
2222 : }
2223 9108974 : }
2224 :
2225 16264293 : void DeclarationScope::AllocateLocals() {
2226 : // For now, function_ must be allocated at the very end. If it gets
2227 : // allocated in the context, it must be the last slot in the context,
2228 : // because of the current ScopeInfo implementation (see
2229 : // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
2230 8132146 : if (function_ != nullptr) {
2231 901483 : AllocateNonParameterLocal(function_);
2232 : }
2233 :
2234 : DCHECK(!has_rest_ || !MustAllocate(rest_parameter()) ||
2235 : !rest_parameter()->IsUnallocated());
2236 :
2237 8132147 : if (new_target_ != nullptr && !MustAllocate(new_target_)) {
2238 5654645 : new_target_ = nullptr;
2239 : }
2240 :
2241 : NullifyRareVariableIf(RareVariable::kThisFunction,
2242 480000 : [=](Variable* var) { return !MustAllocate(var); });
2243 8132147 : }
2244 :
2245 13848 : void ModuleScope::AllocateModuleVariables() {
2246 14551 : for (const auto& it : module()->regular_imports()) {
2247 703 : Variable* var = LookupLocal(it.first);
2248 703 : var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
2249 : DCHECK(!var->IsExport());
2250 : }
2251 :
2252 15214 : for (const auto& it : module()->regular_exports()) {
2253 1366 : Variable* var = LookupLocal(it.first);
2254 1366 : var->AllocateTo(VariableLocation::MODULE, it.second->cell_index);
2255 : DCHECK(var->IsExport());
2256 : }
2257 6924 : }
2258 :
2259 27641158 : void Scope::AllocateVariablesRecursively() {
2260 : DCHECK(!already_resolved_);
2261 : DCHECK_IMPLIES(!FLAG_experimental_preparser_scope_analysis,
2262 : num_stack_slots_ == 0);
2263 :
2264 : // Don't allocate variables of preparsed scopes.
2265 19823264 : if (is_declaration_scope() && AsDeclarationScope()->was_lazily_parsed()) {
2266 10400049 : return;
2267 : }
2268 :
2269 : // Allocate variables for inner scopes.
2270 16617716 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
2271 7508750 : scope->AllocateVariablesRecursively();
2272 : }
2273 :
2274 : DCHECK(!already_resolved_);
2275 : DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, num_heap_slots_);
2276 :
2277 : // Allocate variables for this scope.
2278 : // Parameters must be allocated first, if any.
2279 9108966 : if (is_declaration_scope()) {
2280 8132142 : if (is_function_scope()) {
2281 6529629 : AsDeclarationScope()->AllocateParameterLocals();
2282 : }
2283 8132147 : AsDeclarationScope()->AllocateReceiver();
2284 : }
2285 9108969 : AllocateNonParameterLocalsAndDeclaredGlobals();
2286 :
2287 : // Force allocation of a context for this scope if necessary. For a 'with'
2288 : // scope and for a function scope that makes an 'eval' call we need a context,
2289 : // even if no local variables were statically allocated in the scope.
2290 : // Likewise for modules and function scopes representing asm.js modules.
2291 : bool must_have_context =
2292 18101036 : is_with_scope() || is_module_scope() || IsAsmModule() ||
2293 15627542 : (is_function_scope() && calls_sloppy_eval()) ||
2294 470574 : (is_block_scope() && is_declaration_scope() && calls_sloppy_eval());
2295 :
2296 : // If we didn't allocate any locals in the local context, then we only
2297 : // need the minimal number of slots if we must have a context.
2298 9108975 : if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) {
2299 7837590 : num_heap_slots_ = 0;
2300 : }
2301 :
2302 : // Allocation done.
2303 : DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
2304 : }
2305 :
2306 4267312 : void Scope::AllocateScopeInfosRecursively(Isolate* isolate,
2307 2477468 : MaybeHandle<ScopeInfo> outer_scope) {
2308 : DCHECK(scope_info_.is_null());
2309 4267312 : MaybeHandle<ScopeInfo> next_outer_scope = outer_scope;
2310 :
2311 4267312 : if (NeedsScopeInfo()) {
2312 4954936 : scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
2313 : // The ScopeInfo chain should mirror the context chain, so we only link to
2314 : // the next outer scope that needs a context.
2315 2477461 : if (NeedsContext()) next_outer_scope = scope_info_;
2316 : }
2317 :
2318 : // Allocate ScopeInfos for inner scopes.
2319 10679272 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
2320 12256626 : if (!scope->is_function_scope() ||
2321 : scope->AsDeclarationScope()->ShouldEagerCompile()) {
2322 1390728 : scope->AllocateScopeInfosRecursively(isolate, next_outer_scope);
2323 : }
2324 : }
2325 4267313 : }
2326 :
2327 309972 : void Scope::AllocateDebuggerScopeInfos(Isolate* isolate,
2328 95504 : MaybeHandle<ScopeInfo> outer_scope) {
2329 309972 : if (scope_info_.is_null()) {
2330 191008 : scope_info_ = ScopeInfo::Create(isolate, zone(), this, outer_scope);
2331 : }
2332 309972 : MaybeHandle<ScopeInfo> outer = NeedsContext() ? scope_info_ : outer_scope;
2333 801377 : for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
2334 491405 : if (scope->is_function_scope()) continue;
2335 115030 : scope->AllocateDebuggerScopeInfos(isolate, outer);
2336 : }
2337 309972 : }
2338 :
2339 4878 : int Scope::StackLocalCount() const {
2340 : Variable* function =
2341 2439 : is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
2342 2439 : return num_stack_slots() -
2343 740 : (function != nullptr && function->IsStackLocal() ? 1 : 0);
2344 : }
2345 :
2346 :
2347 39772 : int Scope::ContextLocalCount() const {
2348 31013 : if (num_heap_slots() == 0) return 0;
2349 : Variable* function =
2350 8759 : is_function_scope() ? AsDeclarationScope()->function_var() : nullptr;
2351 : bool is_function_var_in_context =
2352 8759 : function != nullptr && function->IsContextSlot();
2353 8759 : return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
2354 8759 : (is_function_var_in_context ? 1 : 0);
2355 : }
2356 :
2357 : } // namespace internal
2358 : } // namespace v8
|