| OLD | NEW |
| 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/ast/scopes.h" | 5 #include "src/ast/scopes.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/ast/scopeinfo.h" | 8 #include "src/ast/scopeinfo.h" |
| 9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
| 10 #include "src/messages.h" | 10 #include "src/messages.h" |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 function_kind_ = function_kind; | 164 function_kind_ = function_kind; |
| 165 scope_name_ = ast_value_factory_->empty_string(); | 165 scope_name_ = ast_value_factory_->empty_string(); |
| 166 dynamics_ = nullptr; | 166 dynamics_ = nullptr; |
| 167 receiver_ = nullptr; | 167 receiver_ = nullptr; |
| 168 new_target_ = nullptr; | 168 new_target_ = nullptr; |
| 169 function_ = nullptr; | 169 function_ = nullptr; |
| 170 arguments_ = nullptr; | 170 arguments_ = nullptr; |
| 171 this_function_ = nullptr; | 171 this_function_ = nullptr; |
| 172 illegal_redecl_ = nullptr; | 172 illegal_redecl_ = nullptr; |
| 173 scope_inside_with_ = false; | 173 scope_inside_with_ = false; |
| 174 scope_contains_with_ = false; | |
| 175 scope_calls_eval_ = false; | 174 scope_calls_eval_ = false; |
| 176 scope_uses_arguments_ = false; | 175 scope_uses_arguments_ = false; |
| 177 scope_uses_super_property_ = false; | 176 scope_uses_super_property_ = false; |
| 178 asm_module_ = false; | 177 asm_module_ = false; |
| 179 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; | 178 asm_function_ = outer_scope != NULL && outer_scope->asm_module_; |
| 180 // Inherit the language mode from the parent scope. | 179 // Inherit the language mode from the parent scope. |
| 181 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; | 180 language_mode_ = outer_scope != NULL ? outer_scope->language_mode_ : SLOPPY; |
| 182 outer_scope_calls_sloppy_eval_ = false; | 181 outer_scope_calls_sloppy_eval_ = false; |
| 183 inner_scope_calls_eval_ = false; | 182 inner_scope_calls_eval_ = false; |
| 184 scope_nonlinear_ = false; | 183 scope_nonlinear_ = false; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 Scope(zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info), | 244 Scope(zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info), |
| 246 script_scope->ast_value_factory_); | 245 script_scope->ast_value_factory_); |
| 247 } else { | 246 } else { |
| 248 DCHECK(context->IsCatchContext()); | 247 DCHECK(context->IsCatchContext()); |
| 249 String* name = context->catch_name(); | 248 String* name = context->catch_name(); |
| 250 current_scope = new (zone) Scope( | 249 current_scope = new (zone) Scope( |
| 251 zone, current_scope, | 250 zone, current_scope, |
| 252 script_scope->ast_value_factory_->GetString(Handle<String>(name)), | 251 script_scope->ast_value_factory_->GetString(Handle<String>(name)), |
| 253 script_scope->ast_value_factory_); | 252 script_scope->ast_value_factory_); |
| 254 } | 253 } |
| 255 if (contains_with) current_scope->RecordWithStatement(); | |
| 256 if (innermost_scope == NULL) innermost_scope = current_scope; | 254 if (innermost_scope == NULL) innermost_scope = current_scope; |
| 257 | 255 |
| 258 // Forget about a with when we move to a context for a different function. | 256 // Forget about a with when we move to a context for a different function. |
| 259 if (context->previous()->closure() != context->closure()) { | 257 if (context->previous()->closure() != context->closure()) { |
| 260 contains_with = false; | 258 contains_with = false; |
| 261 } | 259 } |
| 262 context = context->previous(); | 260 context = context->previous(); |
| 263 } | 261 } |
| 264 | 262 |
| 265 script_scope->AddInnerScope(current_scope); | 263 script_scope->AddInnerScope(current_scope); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 } | 383 } |
| 386 | 384 |
| 387 | 385 |
| 388 void Scope::PropagateUsageFlagsToScope(Scope* other) { | 386 void Scope::PropagateUsageFlagsToScope(Scope* other) { |
| 389 DCHECK_NOT_NULL(other); | 387 DCHECK_NOT_NULL(other); |
| 390 DCHECK(!already_resolved()); | 388 DCHECK(!already_resolved()); |
| 391 DCHECK(!other->already_resolved()); | 389 DCHECK(!other->already_resolved()); |
| 392 if (uses_arguments()) other->RecordArgumentsUsage(); | 390 if (uses_arguments()) other->RecordArgumentsUsage(); |
| 393 if (uses_super_property()) other->RecordSuperPropertyUsage(); | 391 if (uses_super_property()) other->RecordSuperPropertyUsage(); |
| 394 if (calls_eval()) other->RecordEvalCall(); | 392 if (calls_eval()) other->RecordEvalCall(); |
| 395 if (scope_contains_with_) other->RecordWithStatement(); | |
| 396 } | 393 } |
| 397 | 394 |
| 398 | 395 |
| 399 Variable* Scope::LookupLocal(const AstRawString* name) { | 396 Variable* Scope::LookupLocal(const AstRawString* name) { |
| 400 Variable* result = variables_.Lookup(name); | 397 Variable* result = variables_.Lookup(name); |
| 401 if (result != NULL || scope_info_.is_null()) { | 398 if (result != NULL || scope_info_.is_null()) { |
| 402 return result; | 399 return result; |
| 403 } | 400 } |
| 404 Handle<String> name_handle = name->string(); | 401 Handle<String> name_handle = name->string(); |
| 405 // The Scope is backed up by ScopeInfo. This means it cannot operate in a | 402 // The Scope is backed up by ScopeInfo. This means it cannot operate in a |
| (...skipping 569 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 975 } | 972 } |
| 976 | 973 |
| 977 // Scope info. | 974 // Scope info. |
| 978 if (HasTrivialOuterContext()) { | 975 if (HasTrivialOuterContext()) { |
| 979 Indent(n1, "// scope has trivial outer context\n"); | 976 Indent(n1, "// scope has trivial outer context\n"); |
| 980 } | 977 } |
| 981 if (is_strict(language_mode())) { | 978 if (is_strict(language_mode())) { |
| 982 Indent(n1, "// strict mode scope\n"); | 979 Indent(n1, "// strict mode scope\n"); |
| 983 } | 980 } |
| 984 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); | 981 if (scope_inside_with_) Indent(n1, "// scope inside 'with'\n"); |
| 985 if (scope_contains_with_) Indent(n1, "// scope contains 'with'\n"); | |
| 986 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); | 982 if (scope_calls_eval_) Indent(n1, "// scope calls 'eval'\n"); |
| 987 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n"); | 983 if (scope_uses_arguments_) Indent(n1, "// scope uses 'arguments'\n"); |
| 988 if (scope_uses_super_property_) | 984 if (scope_uses_super_property_) |
| 989 Indent(n1, "// scope uses 'super' property\n"); | 985 Indent(n1, "// scope uses 'super' property\n"); |
| 990 if (outer_scope_calls_sloppy_eval_) { | 986 if (outer_scope_calls_sloppy_eval_) { |
| 991 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); | 987 Indent(n1, "// outer scope calls 'eval' in sloppy context\n"); |
| 992 } | 988 } |
| 993 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); | 989 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); |
| 994 if (num_stack_slots_ > 0) { | 990 if (num_stack_slots_ > 0) { |
| 995 Indent(n1, "// "); | 991 Indent(n1, "// "); |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1247 } | 1243 } |
| 1248 } | 1244 } |
| 1249 | 1245 |
| 1250 | 1246 |
| 1251 bool Scope::MustAllocate(Variable* var) { | 1247 bool Scope::MustAllocate(Variable* var) { |
| 1252 // Give var a read/write use if there is a chance it might be accessed | 1248 // Give var a read/write use if there is a chance it might be accessed |
| 1253 // via an eval() call. This is only possible if the variable has a | 1249 // via an eval() call. This is only possible if the variable has a |
| 1254 // visible name. | 1250 // visible name. |
| 1255 if ((var->is_this() || !var->raw_name()->IsEmpty()) && | 1251 if ((var->is_this() || !var->raw_name()->IsEmpty()) && |
| 1256 (var->has_forced_context_allocation() || scope_calls_eval_ || | 1252 (var->has_forced_context_allocation() || scope_calls_eval_ || |
| 1257 inner_scope_calls_eval_ || scope_contains_with_ || is_catch_scope() || | 1253 inner_scope_calls_eval_ || is_catch_scope() || is_block_scope() || |
| 1258 is_block_scope() || is_module_scope() || is_script_scope())) { | 1254 is_module_scope() || is_script_scope())) { |
| 1259 var->set_is_used(); | 1255 var->set_is_used(); |
| 1260 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); | 1256 if (scope_calls_eval_ || inner_scope_calls_eval_) var->set_maybe_assigned(); |
| 1261 } | 1257 } |
| 1262 // Global variables do not need to be allocated. | 1258 // Global variables do not need to be allocated. |
| 1263 return !var->IsGlobalObjectProperty() && var->is_used(); | 1259 return !var->IsGlobalObjectProperty() && var->is_used(); |
| 1264 } | 1260 } |
| 1265 | 1261 |
| 1266 | 1262 |
| 1267 bool Scope::MustAllocateInContext(Variable* var) { | 1263 bool Scope::MustAllocateInContext(Variable* var) { |
| 1268 // If var is accessed from an inner scope, or if there is a possibility | 1264 // If var is accessed from an inner scope, or if there is a possibility |
| 1269 // that it might be accessed from the current or an inner scope (through | 1265 // that it might be accessed from the current or an inner scope (through |
| 1270 // an eval() call or a runtime with lookup), it must be allocated in the | 1266 // an eval() call or a runtime with lookup), it must be allocated in the |
| 1271 // context. | 1267 // context. |
| 1272 // | 1268 // |
| 1273 // Exceptions: If the scope as a whole has forced context allocation, all | 1269 // Exceptions: If the scope as a whole has forced context allocation, all |
| 1274 // variables will have context allocation, even temporaries. Otherwise | 1270 // variables will have context allocation, even temporaries. Otherwise |
| 1275 // temporary variables are always stack-allocated. Catch-bound variables are | 1271 // temporary variables are always stack-allocated. Catch-bound variables are |
| 1276 // always context-allocated. | 1272 // always context-allocated. |
| 1277 if (has_forced_context_allocation()) return true; | 1273 if (has_forced_context_allocation()) return true; |
| 1278 if (var->mode() == TEMPORARY) return false; | 1274 if (var->mode() == TEMPORARY) return false; |
| 1279 if (is_catch_scope() || is_module_scope()) return true; | 1275 if (is_catch_scope() || is_module_scope()) return true; |
| 1280 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; | 1276 if (is_script_scope() && IsLexicalVariableMode(var->mode())) return true; |
| 1281 return var->has_forced_context_allocation() || | 1277 return var->has_forced_context_allocation() || scope_calls_eval_ || |
| 1282 scope_calls_eval_ || | 1278 inner_scope_calls_eval_; |
| 1283 inner_scope_calls_eval_ || | |
| 1284 scope_contains_with_; | |
| 1285 } | 1279 } |
| 1286 | 1280 |
| 1287 | 1281 |
| 1288 bool Scope::HasArgumentsParameter(Isolate* isolate) { | 1282 bool Scope::HasArgumentsParameter(Isolate* isolate) { |
| 1289 for (int i = 0; i < params_.length(); i++) { | 1283 for (int i = 0; i < params_.length(); i++) { |
| 1290 if (params_[i]->name().is_identical_to( | 1284 if (params_[i]->name().is_identical_to( |
| 1291 isolate->factory()->arguments_string())) { | 1285 isolate->factory()->arguments_string())) { |
| 1292 return true; | 1286 return true; |
| 1293 } | 1287 } |
| 1294 } | 1288 } |
| (...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1530 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1524 function_ != NULL && function_->proxy()->var()->IsContextSlot(); |
| 1531 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1525 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1532 (is_function_var_in_context ? 1 : 0); | 1526 (is_function_var_in_context ? 1 : 0); |
| 1533 } | 1527 } |
| 1534 | 1528 |
| 1535 | 1529 |
| 1536 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1530 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1537 | 1531 |
| 1538 } // namespace internal | 1532 } // namespace internal |
| 1539 } // namespace v8 | 1533 } // namespace v8 |
| OLD | NEW |