Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(301)

Side by Side Diff: src/scopes.cc

Issue 1168513004: [es6] Super call in arrows and eval (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Push this_function earlier Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/scopes.h ('k') | src/typing.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/accessors.h" 7 #include "src/accessors.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/messages.h" 9 #include "src/messages.h"
10 #include "src/parser.h" 10 #include "src/parser.h"
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 scope_type_ = scope_type; 153 scope_type_ = scope_type;
154 function_kind_ = function_kind; 154 function_kind_ = function_kind;
155 block_scope_is_class_scope_ = false; 155 block_scope_is_class_scope_ = false;
156 scope_name_ = ast_value_factory_->empty_string(); 156 scope_name_ = ast_value_factory_->empty_string();
157 dynamics_ = nullptr; 157 dynamics_ = nullptr;
158 receiver_ = nullptr; 158 receiver_ = nullptr;
159 new_target_ = nullptr; 159 new_target_ = nullptr;
160 function_ = nullptr; 160 function_ = nullptr;
161 arguments_ = nullptr; 161 arguments_ = nullptr;
162 home_object_ = nullptr; 162 home_object_ = nullptr;
163 this_function_ = nullptr;
163 illegal_redecl_ = nullptr; 164 illegal_redecl_ = nullptr;
164 scope_inside_with_ = false; 165 scope_inside_with_ = false;
165 scope_contains_with_ = false; 166 scope_contains_with_ = false;
166 scope_calls_eval_ = false; 167 scope_calls_eval_ = false;
167 scope_uses_arguments_ = false; 168 scope_uses_arguments_ = false;
168 scope_uses_super_property_ = false; 169 scope_uses_super_property_ = false;
169 asm_module_ = false; 170 asm_module_ = false;
170 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; 171 asm_function_ = outer_scope != NULL && outer_scope->asm_module_;
171 // Inherit the language mode from the parent scope. 172 // Inherit the language mode from the parent scope.
172 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; 173 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 302
302 // Add this scope as a new inner scope of the outer scope. 303 // Add this scope as a new inner scope of the outer scope.
303 if (outer_scope_ != NULL) { 304 if (outer_scope_ != NULL) {
304 outer_scope_->inner_scopes_.Add(this, zone()); 305 outer_scope_->inner_scopes_.Add(this, zone());
305 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope(); 306 scope_inside_with_ = outer_scope_->scope_inside_with_ || is_with_scope();
306 } else { 307 } else {
307 scope_inside_with_ = is_with_scope(); 308 scope_inside_with_ = is_with_scope();
308 } 309 }
309 310
310 // Declare convenience variables and the receiver. 311 // Declare convenience variables and the receiver.
311 if (is_declaration_scope()) { 312 if (is_declaration_scope() && has_this_declaration()) {
312 DCHECK(!subclass_constructor || is_function_scope()); 313 Variable* var = variables_.Declare(
313 if (has_this_declaration()) { 314 this, ast_value_factory_->this_string(),
314 Variable* var = variables_.Declare( 315 subclass_constructor ? CONST : VAR, Variable::THIS,
315 this, ast_value_factory_->this_string(), 316 subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
316 subclass_constructor ? CONST : VAR, Variable::THIS, 317 receiver_ = var;
317 subclass_constructor ? kNeedsInitialization : kCreatedInitialized); 318 }
318 receiver_ = var; 319
320 if (is_function_scope()) {
321 if (!is_arrow_scope()) {
322 // Declare 'arguments' variable which exists in all non arrow functions.
323 // Note that it might never be accessed, in which case it won't be
324 // allocated during variable allocation.
325 variables_.Declare(this, ast_value_factory_->arguments_string(), VAR,
326 Variable::ARGUMENTS, kCreatedInitialized);
319 } 327 }
320 328
321 if (subclass_constructor) { 329 if (subclass_constructor) {
322 new_target_ = 330 DCHECK(!is_arrow_scope());
323 variables_.Declare(this, ast_value_factory_->new_target_string(), 331 variables_.Declare(this, ast_value_factory_->new_target_string(), CONST,
324 CONST, Variable::NEW_TARGET, kCreatedInitialized); 332 Variable::NORMAL, kCreatedInitialized);
325 new_target_->AllocateTo(Variable::PARAMETER, -2);
326 new_target_->set_is_used();
327 } 333 }
328 }
329 334
330 if (is_function_scope() && !is_arrow_scope()) { 335 if (IsConciseMethod(function_kind_) || IsConstructor(function_kind_) ||
331 // Declare 'arguments' variable which exists in all non arrow functions. 336 IsAccessorFunction(function_kind_)) {
332 // Note that it might never be accessed, in which case it won't be 337 DCHECK(!is_arrow_scope());
333 // allocated during variable allocation. 338 // Declare '.home_object' variable which exists in all methods.
334 variables_.Declare(this, 339 // Note that it might never be accessed, in which case it won't be
335 ast_value_factory_->arguments_string(), 340 // allocated during variable allocation.
336 VAR, 341 variables_.Declare(this, ast_value_factory_->home_object_string(), CONST,
337 Variable::ARGUMENTS, 342 Variable::NORMAL, kCreatedInitialized);
338 kCreatedInitialized); 343 }
339 }
340 344
341 if (is_function_scope() && 345 if (IsSubclassConstructor(function_kind_)) {
342 (IsConciseMethod(function_kind_) || IsConstructor(function_kind_) || 346 DCHECK(!is_arrow_scope());
343 IsAccessorFunction(function_kind_))) { 347 variables_.Declare(this, ast_value_factory_->this_function_string(),
344 DCHECK(!is_arrow_scope()); 348 CONST, Variable::NORMAL, kCreatedInitialized);
345 // Declare '.home_object' variable which exists in all methods. 349 }
346 // Note that it might never be accessed, in which case it won't be
347 // allocated during variable allocation.
348 variables_.Declare(this, ast_value_factory_->home_object_string(), VAR,
349 Variable::NORMAL, kCreatedInitialized);
350 } 350 }
351 } 351 }
352 352
353 353
354 Scope* Scope::FinalizeBlockScope() { 354 Scope* Scope::FinalizeBlockScope() {
355 DCHECK(is_block_scope()); 355 DCHECK(is_block_scope());
356 DCHECK(internals_.is_empty()); 356 DCHECK(internals_.is_empty());
357 DCHECK(temps_.is_empty()); 357 DCHECK(temps_.is_empty());
358 DCHECK(params_.is_empty()); 358 DCHECK(params_.is_empty());
359 359
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 inner->asm_function_ = true; 1304 inner->asm_function_ = true;
1305 } 1305 }
1306 } 1306 }
1307 } 1307 }
1308 1308
1309 1309
1310 bool Scope::MustAllocate(Variable* var) { 1310 bool Scope::MustAllocate(Variable* var) {
1311 // Give var a read/write use if there is a chance it might be accessed 1311 // Give var a read/write use if there is a chance it might be accessed
1312 // via an eval() call. This is only possible if the variable has a 1312 // via an eval() call. This is only possible if the variable has a
1313 // visible name. 1313 // visible name.
1314 if ((var->is_this() || var->is_new_target() || !var->raw_name()->IsEmpty()) && 1314 if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
1315 (var->has_forced_context_allocation() || scope_calls_eval_ || 1315 (var->has_forced_context_allocation() || scope_calls_eval_ ||
1316 inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() || 1316 inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() ||
1317 is_block_scope() || is_module_scope() || is_script_scope())) { 1317 is_block_scope() || is_module_scope() || is_script_scope())) {
1318 var->set_is_used(); 1318 var->set_is_used();
1319 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); 1319 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned();
1320 } 1320 }
1321 // Global variables do not need to be allocated. 1321 // Global variables do not need to be allocated.
1322 return !var->IsGlobalObjectProperty() && var->is_used(); 1322 return !var->IsGlobalObjectProperty() && var->is_used();
1323 } 1323 }
1324 1324
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 // In strict mode 'arguments' does not alias formal parameters. 1396 // In strict mode 'arguments' does not alias formal parameters.
1397 // Therefore in strict mode we allocate parameters as if 'arguments' 1397 // Therefore in strict mode we allocate parameters as if 'arguments'
1398 // were not used. 1398 // were not used.
1399 uses_sloppy_arguments = is_sloppy(language_mode()); 1399 uses_sloppy_arguments = is_sloppy(language_mode());
1400 } 1400 }
1401 1401
1402 if (rest_parameter_ && !MustAllocate(rest_parameter_)) { 1402 if (rest_parameter_ && !MustAllocate(rest_parameter_)) {
1403 rest_parameter_ = NULL; 1403 rest_parameter_ = NULL;
1404 } 1404 }
1405 1405
1406 Variable* home_object_var =
1407 LookupLocal(ast_value_factory_->home_object_string());
1408 if (home_object_var != nullptr && uses_super_property() &&
1409 MustAllocate(home_object_var)) {
1410 // TODO(arv): super() uses a SuperReference so it generates a VariableProxy
1411 // for the .home_object which makes it look like we need to allocate the
1412 // home_object_var.
1413 // Consider splitting the AST node into 2 different nodes since the
1414 // semantics is just so different.
1415 home_object_ = home_object_var;
1416 }
1417
1418 // The same parameter may occur multiple times in the parameters_ list. 1406 // The same parameter may occur multiple times in the parameters_ list.
1419 // If it does, and if it is not copied into the context object, it must 1407 // If it does, and if it is not copied into the context object, it must
1420 // receive the highest parameter index for that parameter; thus iteration 1408 // receive the highest parameter index for that parameter; thus iteration
1421 // order is relevant! 1409 // order is relevant!
1422 for (int i = params_.length() - 1; i >= 0; --i) { 1410 for (int i = params_.length() - 1; i >= 0; --i) {
1423 Variable* var = params_[i]; 1411 Variable* var = params_[i];
1424 if (var == rest_parameter_) continue; 1412 if (var == rest_parameter_) continue;
1425 1413
1426 DCHECK(var->scope() == this); 1414 DCHECK(var->scope() == this);
1427 if (uses_sloppy_arguments || has_forced_context_allocation()) { 1415 if (uses_sloppy_arguments || has_forced_context_allocation()) {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1496 vars.Sort(VarAndOrder::Compare); 1484 vars.Sort(VarAndOrder::Compare);
1497 int var_count = vars.length(); 1485 int var_count = vars.length();
1498 for (int i = 0; i < var_count; i++) { 1486 for (int i = 0; i < var_count; i++) {
1499 AllocateNonParameterLocal(isolate, vars[i].var()); 1487 AllocateNonParameterLocal(isolate, vars[i].var());
1500 } 1488 }
1501 1489
1502 // For now, function_ must be allocated at the very end. If it gets 1490 // For now, function_ must be allocated at the very end. If it gets
1503 // allocated in the context, it must be the last slot in the context, 1491 // allocated in the context, it must be the last slot in the context,
1504 // because of the current ScopeInfo implementation (see 1492 // because of the current ScopeInfo implementation (see
1505 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). 1493 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
1506 if (function_ != NULL) { 1494 if (function_ != nullptr) {
1507 AllocateNonParameterLocal(isolate, function_->proxy()->var()); 1495 AllocateNonParameterLocal(isolate, function_->proxy()->var());
1508 } 1496 }
1509 1497
1510 if (rest_parameter_) { 1498 if (rest_parameter_ != nullptr) {
1511 AllocateNonParameterLocal(isolate, rest_parameter_); 1499 AllocateNonParameterLocal(isolate, rest_parameter_);
1512 } 1500 }
1501
1502 Variable* home_object_var =
1503 LookupLocal(ast_value_factory_->home_object_string());
1504 if (home_object_var != nullptr && MustAllocate(home_object_var)) {
1505 home_object_ = home_object_var;
1506 }
1507
1508 Variable* new_target_var =
1509 LookupLocal(ast_value_factory_->new_target_string());
1510 if (new_target_var != nullptr && MustAllocate(new_target_var)) {
1511 new_target_ = new_target_var;
1512 }
1513
1514 Variable* this_function_var =
1515 LookupLocal(ast_value_factory_->this_function_string());
1516 if (this_function_var != nullptr && MustAllocate(this_function_var)) {
1517 this_function_ = this_function_var;
1518 }
1513 } 1519 }
1514 1520
1515 1521
1516 void Scope::AllocateVariablesRecursively(Isolate* isolate) { 1522 void Scope::AllocateVariablesRecursively(Isolate* isolate) {
1517 if (!already_resolved()) { 1523 if (!already_resolved()) {
1518 num_stack_slots_ = 0; 1524 num_stack_slots_ = 0;
1519 } 1525 }
1520 // Allocate variables for inner scopes. 1526 // Allocate variables for inner scopes.
1521 for (int i = 0; i < inner_scopes_.length(); i++) { 1527 for (int i = 0; i < inner_scopes_.length(); i++) {
1522 inner_scopes_[i]->AllocateVariablesRecursively(isolate); 1528 inner_scopes_[i]->AllocateVariablesRecursively(isolate);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1573 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); 1579 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0);
1574 } 1580 }
1575 1581
1576 1582
1577 int Scope::ContextLocalCount() const { 1583 int Scope::ContextLocalCount() const {
1578 if (num_heap_slots() == 0) return 0; 1584 if (num_heap_slots() == 0) return 0;
1579 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - 1585 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS -
1580 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); 1586 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0);
1581 } 1587 }
1582 } } // namespace v8::internal 1588 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | src/typing.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698