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