| 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/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/scopes.h" | 7 #include "src/scopes.h" |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 268 | 268 |
| 269 // Traverse the scope tree up to the first unresolved scope or the global | 269 // Traverse the scope tree up to the first unresolved scope or the global |
| 270 // scope and start scope resolution and variable allocation from that scope. | 270 // scope and start scope resolution and variable allocation from that scope. |
| 271 while (!top->is_global_scope() && | 271 while (!top->is_global_scope() && |
| 272 !top->outer_scope()->already_resolved()) { | 272 !top->outer_scope()->already_resolved()) { |
| 273 top = top->outer_scope(); | 273 top = top->outer_scope(); |
| 274 } | 274 } |
| 275 | 275 |
| 276 // Allocate the variables. | 276 // Allocate the variables. |
| 277 { | 277 { |
| 278 AstNodeFactory<AstNullVisitor> ast_node_factory(info->ast_value_factory()); | 278 AstNodeFactory ast_node_factory(info->ast_value_factory()); |
| 279 if (!top->AllocateVariables(info, &ast_node_factory)) return false; | 279 if (!top->AllocateVariables(info, &ast_node_factory)) return false; |
| 280 } | 280 } |
| 281 | 281 |
| 282 #ifdef DEBUG | 282 #ifdef DEBUG |
| 283 if (info->isolate()->bootstrapper()->IsActive() | 283 if (info->isolate()->bootstrapper()->IsActive() |
| 284 ? FLAG_print_builtin_scopes | 284 ? FLAG_print_builtin_scopes |
| 285 : FLAG_print_scopes) { | 285 : FLAG_print_scopes) { |
| 286 scope->Print(); | 286 scope->Print(); |
| 287 } | 287 } |
| 288 | 288 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 } | 410 } |
| 411 | 411 |
| 412 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, | 412 Variable* var = variables_.Declare(this, name, mode, true, Variable::NORMAL, |
| 413 init_flag, maybe_assigned_flag); | 413 init_flag, maybe_assigned_flag); |
| 414 var->AllocateTo(location, index); | 414 var->AllocateTo(location, index); |
| 415 return var; | 415 return var; |
| 416 } | 416 } |
| 417 | 417 |
| 418 | 418 |
| 419 Variable* Scope::LookupFunctionVar(const AstRawString* name, | 419 Variable* Scope::LookupFunctionVar(const AstRawString* name, |
| 420 AstNodeFactory<AstNullVisitor>* factory) { | 420 AstNodeFactory* factory) { |
| 421 if (function_ != NULL && function_->proxy()->raw_name() == name) { | 421 if (function_ != NULL && function_->proxy()->raw_name() == name) { |
| 422 return function_->proxy()->var(); | 422 return function_->proxy()->var(); |
| 423 } else if (!scope_info_.is_null()) { | 423 } else if (!scope_info_.is_null()) { |
| 424 // If we are backed by a scope info, try to lookup the variable there. | 424 // If we are backed by a scope info, try to lookup the variable there. |
| 425 VariableMode mode; | 425 VariableMode mode; |
| 426 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); | 426 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode); |
| 427 if (index < 0) return NULL; | 427 if (index < 0) return NULL; |
| 428 Variable* var = new(zone()) Variable( | 428 Variable* var = new(zone()) Variable( |
| 429 this, name, mode, true /* is valid LHS */, | 429 this, name, mode, true /* is valid LHS */, |
| 430 Variable::NORMAL, kCreatedInitialized); | 430 Variable::NORMAL, kCreatedInitialized); |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 Variable* var = vars[i].var(); | 629 Variable* var = vars[i].var(); |
| 630 if (var->IsStackLocal()) { | 630 if (var->IsStackLocal()) { |
| 631 stack_locals->Add(var, zone()); | 631 stack_locals->Add(var, zone()); |
| 632 } else if (var->IsContextSlot()) { | 632 } else if (var->IsContextSlot()) { |
| 633 context_locals->Add(var, zone()); | 633 context_locals->Add(var, zone()); |
| 634 } | 634 } |
| 635 } | 635 } |
| 636 } | 636 } |
| 637 | 637 |
| 638 | 638 |
| 639 bool Scope::AllocateVariables(CompilationInfo* info, | 639 bool Scope::AllocateVariables(CompilationInfo* info, AstNodeFactory* factory) { |
| 640 AstNodeFactory<AstNullVisitor>* factory) { | |
| 641 // 1) Propagate scope information. | 640 // 1) Propagate scope information. |
| 642 bool outer_scope_calls_sloppy_eval = false; | 641 bool outer_scope_calls_sloppy_eval = false; |
| 643 if (outer_scope_ != NULL) { | 642 if (outer_scope_ != NULL) { |
| 644 outer_scope_calls_sloppy_eval = | 643 outer_scope_calls_sloppy_eval = |
| 645 outer_scope_->outer_scope_calls_sloppy_eval() | | 644 outer_scope_->outer_scope_calls_sloppy_eval() | |
| 646 outer_scope_->calls_sloppy_eval(); | 645 outer_scope_->calls_sloppy_eval(); |
| 647 } | 646 } |
| 648 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 647 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
| 649 | 648 |
| 650 // 2) Allocate module instances. | 649 // 2) Allocate module instances. |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 965 init_flag); | 964 init_flag); |
| 966 // Allocate it by giving it a dynamic lookup. | 965 // Allocate it by giving it a dynamic lookup. |
| 967 var->AllocateTo(Variable::LOOKUP, -1); | 966 var->AllocateTo(Variable::LOOKUP, -1); |
| 968 } | 967 } |
| 969 return var; | 968 return var; |
| 970 } | 969 } |
| 971 | 970 |
| 972 | 971 |
| 973 Variable* Scope::LookupRecursive(VariableProxy* proxy, | 972 Variable* Scope::LookupRecursive(VariableProxy* proxy, |
| 974 BindingKind* binding_kind, | 973 BindingKind* binding_kind, |
| 975 AstNodeFactory<AstNullVisitor>* factory) { | 974 AstNodeFactory* factory) { |
| 976 DCHECK(binding_kind != NULL); | 975 DCHECK(binding_kind != NULL); |
| 977 if (already_resolved() && is_with_scope()) { | 976 if (already_resolved() && is_with_scope()) { |
| 978 // Short-cut: if the scope is deserialized from a scope info, variable | 977 // Short-cut: if the scope is deserialized from a scope info, variable |
| 979 // allocation is already fixed. We can simply return with dynamic lookup. | 978 // allocation is already fixed. We can simply return with dynamic lookup. |
| 980 *binding_kind = DYNAMIC_LOOKUP; | 979 *binding_kind = DYNAMIC_LOOKUP; |
| 981 return NULL; | 980 return NULL; |
| 982 } | 981 } |
| 983 | 982 |
| 984 // Try to find the variable in this scope. | 983 // Try to find the variable in this scope. |
| 985 Variable* var = LookupLocal(proxy->raw_name()); | 984 Variable* var = LookupLocal(proxy->raw_name()); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1027 if (*binding_kind == BOUND) { | 1026 if (*binding_kind == BOUND) { |
| 1028 *binding_kind = BOUND_EVAL_SHADOWED; | 1027 *binding_kind = BOUND_EVAL_SHADOWED; |
| 1029 } else if (*binding_kind == UNBOUND) { | 1028 } else if (*binding_kind == UNBOUND) { |
| 1030 *binding_kind = UNBOUND_EVAL_SHADOWED; | 1029 *binding_kind = UNBOUND_EVAL_SHADOWED; |
| 1031 } | 1030 } |
| 1032 } | 1031 } |
| 1033 return var; | 1032 return var; |
| 1034 } | 1033 } |
| 1035 | 1034 |
| 1036 | 1035 |
| 1037 bool Scope::ResolveVariable(CompilationInfo* info, | 1036 bool Scope::ResolveVariable(CompilationInfo* info, VariableProxy* proxy, |
| 1038 VariableProxy* proxy, | 1037 AstNodeFactory* factory) { |
| 1039 AstNodeFactory<AstNullVisitor>* factory) { | |
| 1040 DCHECK(info->global_scope()->is_global_scope()); | 1038 DCHECK(info->global_scope()->is_global_scope()); |
| 1041 | 1039 |
| 1042 // If the proxy is already resolved there's nothing to do | 1040 // If the proxy is already resolved there's nothing to do |
| 1043 // (functions and consts may be resolved by the parser). | 1041 // (functions and consts may be resolved by the parser). |
| 1044 if (proxy->is_resolved()) return true; | 1042 if (proxy->is_resolved()) return true; |
| 1045 | 1043 |
| 1046 // Otherwise, try to resolve the variable. | 1044 // Otherwise, try to resolve the variable. |
| 1047 BindingKind binding_kind; | 1045 BindingKind binding_kind; |
| 1048 Variable* var = LookupRecursive(proxy, &binding_kind, factory); | 1046 Variable* var = LookupRecursive(proxy, &binding_kind, factory); |
| 1049 switch (binding_kind) { | 1047 switch (binding_kind) { |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1136 return false; | 1134 return false; |
| 1137 } | 1135 } |
| 1138 } | 1136 } |
| 1139 | 1137 |
| 1140 proxy->BindTo(var); | 1138 proxy->BindTo(var); |
| 1141 | 1139 |
| 1142 return true; | 1140 return true; |
| 1143 } | 1141 } |
| 1144 | 1142 |
| 1145 | 1143 |
| 1146 bool Scope::ResolveVariablesRecursively( | 1144 bool Scope::ResolveVariablesRecursively(CompilationInfo* info, |
| 1147 CompilationInfo* info, | 1145 AstNodeFactory* factory) { |
| 1148 AstNodeFactory<AstNullVisitor>* factory) { | |
| 1149 DCHECK(info->global_scope()->is_global_scope()); | 1146 DCHECK(info->global_scope()->is_global_scope()); |
| 1150 | 1147 |
| 1151 // Resolve unresolved variables for this scope. | 1148 // Resolve unresolved variables for this scope. |
| 1152 for (int i = 0; i < unresolved_.length(); i++) { | 1149 for (int i = 0; i < unresolved_.length(); i++) { |
| 1153 if (!ResolveVariable(info, unresolved_[i], factory)) return false; | 1150 if (!ResolveVariable(info, unresolved_[i], factory)) return false; |
| 1154 } | 1151 } |
| 1155 | 1152 |
| 1156 // Resolve unresolved variables for inner scopes. | 1153 // Resolve unresolved variables for inner scopes. |
| 1157 for (int i = 0; i < inner_scopes_.length(); i++) { | 1154 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 1158 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) | 1155 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) |
| (...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1423 } | 1420 } |
| 1424 | 1421 |
| 1425 | 1422 |
| 1426 int Scope::ContextLocalCount() const { | 1423 int Scope::ContextLocalCount() const { |
| 1427 if (num_heap_slots() == 0) return 0; | 1424 if (num_heap_slots() == 0) return 0; |
| 1428 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1425 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1429 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1426 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
| 1430 } | 1427 } |
| 1431 | 1428 |
| 1432 } } // namespace v8::internal | 1429 } } // namespace v8::internal |
| OLD | NEW |