| 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 |