| Index: src/scopes.cc
|
| diff --git a/src/scopes.cc b/src/scopes.cc
|
| index 21a8805c54aad396364829e66110c72752cfd3c2..2aa3cbde98a7cd1c4efa178e8e892f460d4b5b10 100644
|
| --- a/src/scopes.cc
|
| +++ b/src/scopes.cc
|
| @@ -160,6 +160,7 @@ void Scope::SetDefaults(ScopeType scope_type, Scope* outer_scope,
|
| function_ = nullptr;
|
| arguments_ = nullptr;
|
| home_object_ = nullptr;
|
| + this_function_ = nullptr;
|
| illegal_redecl_ = nullptr;
|
| scope_inside_with_ = false;
|
| scope_contains_with_ = false;
|
| @@ -308,45 +309,44 @@ void Scope::Initialize() {
|
| }
|
|
|
| // Declare convenience variables and the receiver.
|
| - if (is_declaration_scope()) {
|
| - DCHECK(!subclass_constructor || is_function_scope());
|
| - if (has_this_declaration()) {
|
| - Variable* var = variables_.Declare(
|
| - this, ast_value_factory_->this_string(),
|
| - subclass_constructor ? CONST : VAR, Variable::THIS,
|
| - subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
|
| - receiver_ = var;
|
| + if (is_declaration_scope() && has_this_declaration()) {
|
| + Variable* var = variables_.Declare(
|
| + this, ast_value_factory_->this_string(),
|
| + subclass_constructor ? CONST : VAR, Variable::THIS,
|
| + subclass_constructor ? kNeedsInitialization : kCreatedInitialized);
|
| + receiver_ = var;
|
| + }
|
| +
|
| + if (is_function_scope()) {
|
| + if (!is_arrow_scope()) {
|
| + // Declare 'arguments' variable which exists in all non arrow functions.
|
| + // Note that it might never be accessed, in which case it won't be
|
| + // allocated during variable allocation.
|
| + variables_.Declare(this, ast_value_factory_->arguments_string(), VAR,
|
| + Variable::ARGUMENTS, kCreatedInitialized);
|
| }
|
|
|
| if (subclass_constructor) {
|
| - new_target_ =
|
| - variables_.Declare(this, ast_value_factory_->new_target_string(),
|
| - CONST, Variable::NEW_TARGET, kCreatedInitialized);
|
| - new_target_->AllocateTo(Variable::PARAMETER, -2);
|
| - new_target_->set_is_used();
|
| + DCHECK(!is_arrow_scope());
|
| + variables_.Declare(this, ast_value_factory_->new_target_string(), CONST,
|
| + Variable::NORMAL, kCreatedInitialized);
|
| }
|
| - }
|
|
|
| - if (is_function_scope() && !is_arrow_scope()) {
|
| - // Declare 'arguments' variable which exists in all non arrow functions.
|
| - // Note that it might never be accessed, in which case it won't be
|
| - // allocated during variable allocation.
|
| - variables_.Declare(this,
|
| - ast_value_factory_->arguments_string(),
|
| - VAR,
|
| - Variable::ARGUMENTS,
|
| - kCreatedInitialized);
|
| - }
|
| + if (IsConciseMethod(function_kind_) || IsConstructor(function_kind_) ||
|
| + IsAccessorFunction(function_kind_)) {
|
| + DCHECK(!is_arrow_scope());
|
| + // Declare '.home_object' variable which exists in all methods.
|
| + // Note that it might never be accessed, in which case it won't be
|
| + // allocated during variable allocation.
|
| + variables_.Declare(this, ast_value_factory_->home_object_string(), CONST,
|
| + Variable::NORMAL, kCreatedInitialized);
|
| + }
|
|
|
| - if (is_function_scope() &&
|
| - (IsConciseMethod(function_kind_) || IsConstructor(function_kind_) ||
|
| - IsAccessorFunction(function_kind_))) {
|
| - DCHECK(!is_arrow_scope());
|
| - // Declare '.home_object' variable which exists in all methods.
|
| - // Note that it might never be accessed, in which case it won't be
|
| - // allocated during variable allocation.
|
| - variables_.Declare(this, ast_value_factory_->home_object_string(), VAR,
|
| - Variable::NORMAL, kCreatedInitialized);
|
| + if (IsSubclassConstructor(function_kind_)) {
|
| + DCHECK(!is_arrow_scope());
|
| + variables_.Declare(this, ast_value_factory_->this_function_string(),
|
| + CONST, Variable::NORMAL, kCreatedInitialized);
|
| + }
|
| }
|
| }
|
|
|
| @@ -1311,7 +1311,7 @@ bool Scope::MustAllocate(Variable* var) {
|
| // Give var a read/write use if there is a chance it might be accessed
|
| // via an eval() call. This is only possible if the variable has a
|
| // visible name.
|
| - if ((var->is_this() || var->is_new_target() || !var->raw_name()->IsEmpty()) &&
|
| + if ((var->is_this() || !var->raw_name()->IsEmpty()) &&
|
| (var->has_forced_context_allocation() || scope_calls_eval_ ||
|
| inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() ||
|
| is_block_scope() || is_module_scope() || is_script_scope())) {
|
| @@ -1403,18 +1403,6 @@ void Scope::AllocateParameterLocals(Isolate* isolate) {
|
| rest_parameter_ = NULL;
|
| }
|
|
|
| - Variable* home_object_var =
|
| - LookupLocal(ast_value_factory_->home_object_string());
|
| - if (home_object_var != nullptr && uses_super_property() &&
|
| - MustAllocate(home_object_var)) {
|
| - // TODO(arv): super() uses a SuperReference so it generates a VariableProxy
|
| - // for the .home_object which makes it look like we need to allocate the
|
| - // home_object_var.
|
| - // Consider splitting the AST node into 2 different nodes since the
|
| - // semantics is just so different.
|
| - home_object_ = home_object_var;
|
| - }
|
| -
|
| // The same parameter may occur multiple times in the parameters_ list.
|
| // If it does, and if it is not copied into the context object, it must
|
| // receive the highest parameter index for that parameter; thus iteration
|
| @@ -1503,13 +1491,31 @@ void Scope::AllocateNonParameterLocals(Isolate* isolate) {
|
| // allocated in the context, it must be the last slot in the context,
|
| // because of the current ScopeInfo implementation (see
|
| // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor).
|
| - if (function_ != NULL) {
|
| + if (function_ != nullptr) {
|
| AllocateNonParameterLocal(isolate, function_->proxy()->var());
|
| }
|
|
|
| - if (rest_parameter_) {
|
| + if (rest_parameter_ != nullptr) {
|
| AllocateNonParameterLocal(isolate, rest_parameter_);
|
| }
|
| +
|
| + Variable* home_object_var =
|
| + LookupLocal(ast_value_factory_->home_object_string());
|
| + if (home_object_var != nullptr && MustAllocate(home_object_var)) {
|
| + home_object_ = home_object_var;
|
| + }
|
| +
|
| + Variable* new_target_var =
|
| + LookupLocal(ast_value_factory_->new_target_string());
|
| + if (new_target_var != nullptr && MustAllocate(new_target_var)) {
|
| + new_target_ = new_target_var;
|
| + }
|
| +
|
| + Variable* this_function_var =
|
| + LookupLocal(ast_value_factory_->this_function_string());
|
| + if (this_function_var != nullptr && MustAllocate(this_function_var)) {
|
| + this_function_ = this_function_var;
|
| + }
|
| }
|
|
|
|
|
|
|