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 |