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/scopes.h" | 5 #include "src/scopes.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 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 // Reparent inner scopes. | 379 // Reparent inner scopes. |
380 for (int i = 0; i < inner_scopes_.length(); i++) { | 380 for (int i = 0; i < inner_scopes_.length(); i++) { |
381 outer_scope()->AddInnerScope(inner_scopes_[i]); | 381 outer_scope()->AddInnerScope(inner_scopes_[i]); |
382 } | 382 } |
383 | 383 |
384 // Move unresolved variables | 384 // Move unresolved variables |
385 for (int i = 0; i < unresolved_.length(); i++) { | 385 for (int i = 0; i < unresolved_.length(); i++) { |
386 outer_scope()->unresolved_.Add(unresolved_[i], zone()); | 386 outer_scope()->unresolved_.Add(unresolved_[i], zone()); |
387 } | 387 } |
388 | 388 |
389 // Propagate usage flags to outer scope. | 389 PropagateUsageFlagsToScope(outer_scope_); |
390 // TODO(adamk): Why doesn't this call PropagateScopeInfo()? | |
391 if (uses_arguments()) outer_scope_->RecordArgumentsUsage(); | |
392 if (uses_super_property()) outer_scope_->RecordSuperPropertyUsage(); | |
393 if (scope_calls_eval_) outer_scope_->RecordEvalCall(); | |
394 | 390 |
395 return NULL; | 391 return NULL; |
396 } | 392 } |
397 | 393 |
398 | 394 |
399 void Scope::ReplaceOuterScope(Scope* outer_scope) { | 395 void Scope::ReplaceOuterScope(Scope* outer) { |
| 396 DCHECK_NOT_NULL(outer); |
400 DCHECK_NOT_NULL(outer_scope_); | 397 DCHECK_NOT_NULL(outer_scope_); |
| 398 DCHECK(!already_resolved()); |
| 399 DCHECK(!outer->already_resolved()); |
| 400 DCHECK(!outer_scope_->already_resolved()); |
401 outer_scope_->RemoveInnerScope(this); | 401 outer_scope_->RemoveInnerScope(this); |
402 outer_scope_ = outer_scope; | 402 outer->AddInnerScope(this); |
403 outer_scope_->AddInnerScope(this); | 403 outer_scope_ = outer; |
404 // TODO(adamk): Do we need to propagate usage flags here? | |
405 } | 404 } |
406 | 405 |
407 | 406 |
| 407 void Scope::PropagateUsageFlagsToScope(Scope* other) { |
| 408 DCHECK_NOT_NULL(other); |
| 409 DCHECK(!already_resolved()); |
| 410 DCHECK(!other->already_resolved()); |
| 411 if (uses_arguments()) other->RecordArgumentsUsage(); |
| 412 if (uses_super_property()) other->RecordSuperPropertyUsage(); |
| 413 if (calls_eval()) other->RecordEvalCall(); |
| 414 if (scope_contains_with_) other->RecordWithStatement(); |
| 415 } |
| 416 |
| 417 |
408 Variable* Scope::LookupLocal(const AstRawString* name) { | 418 Variable* Scope::LookupLocal(const AstRawString* name) { |
409 Variable* result = variables_.Lookup(name); | 419 Variable* result = variables_.Lookup(name); |
410 if (result != NULL || scope_info_.is_null()) { | 420 if (result != NULL || scope_info_.is_null()) { |
411 return result; | 421 return result; |
412 } | 422 } |
413 Handle<String> name_handle = name->string(); | 423 Handle<String> name_handle = name->string(); |
414 // The Scope is backed up by ScopeInfo. This means it cannot operate in a | 424 // The Scope is backed up by ScopeInfo. This means it cannot operate in a |
415 // heap-independent mode, and all strings must be internalized immediately. So | 425 // heap-independent mode, and all strings must be internalized immediately. So |
416 // it's ok to get the Handle<String> here. | 426 // it's ok to get the Handle<String> here. |
417 // If we have a serialized scope info, we might find the variable there. | 427 // If we have a serialized scope info, we might find the variable there. |
(...skipping 695 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 DCHECK(!already_resolved()); | 1123 DCHECK(!already_resolved()); |
1114 // The current scope is a with scope, so the variable binding can not be | 1124 // The current scope is a with scope, so the variable binding can not be |
1115 // statically resolved. However, note that it was necessary to do a lookup | 1125 // statically resolved. However, note that it was necessary to do a lookup |
1116 // in the outer scope anyway, because if a binding exists in an outer scope, | 1126 // in the outer scope anyway, because if a binding exists in an outer scope, |
1117 // the associated variable has to be marked as potentially being accessed | 1127 // the associated variable has to be marked as potentially being accessed |
1118 // from inside of an inner with scope (the property may not be in the 'with' | 1128 // from inside of an inner with scope (the property may not be in the 'with' |
1119 // object). | 1129 // object). |
1120 if (var != NULL && proxy->is_assigned()) var->set_maybe_assigned(); | 1130 if (var != NULL && proxy->is_assigned()) var->set_maybe_assigned(); |
1121 *binding_kind = DYNAMIC_LOOKUP; | 1131 *binding_kind = DYNAMIC_LOOKUP; |
1122 return NULL; | 1132 return NULL; |
1123 } else if (calls_sloppy_eval() && name_can_be_shadowed) { | 1133 } else if (calls_sloppy_eval() && !is_script_scope() && |
| 1134 name_can_be_shadowed) { |
1124 // A variable binding may have been found in an outer scope, but the current | 1135 // A variable binding may have been found in an outer scope, but the current |
1125 // scope makes a sloppy 'eval' call, so the found variable may not be | 1136 // scope makes a sloppy 'eval' call, so the found variable may not be |
1126 // the correct one (the 'eval' may introduce a binding with the same name). | 1137 // the correct one (the 'eval' may introduce a binding with the same name). |
1127 // In that case, change the lookup result to reflect this situation. | 1138 // In that case, change the lookup result to reflect this situation. |
1128 if (*binding_kind == BOUND) { | 1139 if (*binding_kind == BOUND) { |
1129 *binding_kind = BOUND_EVAL_SHADOWED; | 1140 *binding_kind = BOUND_EVAL_SHADOWED; |
1130 } else if (*binding_kind == UNBOUND) { | 1141 } else if (*binding_kind == UNBOUND) { |
1131 *binding_kind = UNBOUND_EVAL_SHADOWED; | 1142 *binding_kind = UNBOUND_EVAL_SHADOWED; |
1132 } | 1143 } |
1133 } | 1144 } |
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1650 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1661 function_ != NULL && function_->proxy()->var()->IsContextSlot(); |
1651 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1662 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
1652 (is_function_var_in_context ? 1 : 0); | 1663 (is_function_var_in_context ? 1 : 0); |
1653 } | 1664 } |
1654 | 1665 |
1655 | 1666 |
1656 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1667 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
1657 | 1668 |
1658 } // namespace internal | 1669 } // namespace internal |
1659 } // namespace v8 | 1670 } // namespace v8 |
OLD | NEW |