Chromium Code Reviews| 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" | |
| 8 | |
| 9 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 10 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
| 11 #include "src/compiler.h" | |
| 12 #include "src/messages.h" | 9 #include "src/messages.h" |
| 10 #include "src/parser.h" | |
| 13 #include "src/scopeinfo.h" | 11 #include "src/scopeinfo.h" |
| 12 #include "src/scopes.h" | |
|
marja
2015/03/04 09:24:40
Nit, this should remain at the top...
| |
| 14 | 13 |
| 15 namespace v8 { | 14 namespace v8 { |
| 16 namespace internal { | 15 namespace internal { |
| 17 | 16 |
| 18 // ---------------------------------------------------------------------------- | 17 // ---------------------------------------------------------------------------- |
| 19 // Implementation of LocalsMap | 18 // Implementation of LocalsMap |
| 20 // | 19 // |
| 21 // Note: We are storing the handle locations as key values in the hash map. | 20 // Note: We are storing the handle locations as key values in the hash map. |
| 22 // When inserting a new variable via Declare(), we rely on the fact that | 21 // When inserting a new variable via Declare(), we rely on the fact that |
| 23 // the handle location remains alive for the duration of that variable | 22 // the handle location remains alive for the duration of that variable |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 241 } | 240 } |
| 242 context = context->previous(); | 241 context = context->previous(); |
| 243 } | 242 } |
| 244 | 243 |
| 245 script_scope->AddInnerScope(current_scope); | 244 script_scope->AddInnerScope(current_scope); |
| 246 script_scope->PropagateScopeInfo(false); | 245 script_scope->PropagateScopeInfo(false); |
| 247 return (innermost_scope == NULL) ? script_scope : innermost_scope; | 246 return (innermost_scope == NULL) ? script_scope : innermost_scope; |
| 248 } | 247 } |
| 249 | 248 |
| 250 | 249 |
| 251 bool Scope::Analyze(CompilationInfo* info) { | 250 bool Scope::Analyze(ParseInfo* info) { |
| 252 DCHECK(info->function() != NULL); | 251 DCHECK(info->function() != NULL); |
| 252 DCHECK(info->scope() == NULL); | |
| 253 Scope* scope = info->function()->scope(); | 253 Scope* scope = info->function()->scope(); |
| 254 Scope* top = scope; | 254 Scope* top = scope; |
| 255 | 255 |
| 256 // Traverse the scope tree up to the first unresolved scope or the global | 256 // Traverse the scope tree up to the first unresolved scope or the global |
| 257 // scope and start scope resolution and variable allocation from that scope. | 257 // scope and start scope resolution and variable allocation from that scope. |
| 258 while (!top->is_script_scope() && | 258 while (!top->is_script_scope() && |
| 259 !top->outer_scope()->already_resolved()) { | 259 !top->outer_scope()->already_resolved()) { |
| 260 top = top->outer_scope(); | 260 top = top->outer_scope(); |
| 261 } | 261 } |
| 262 | 262 |
| 263 // Allocate the variables. | 263 // Allocate the variables. |
| 264 { | 264 { |
| 265 AstNodeFactory ast_node_factory(info->ast_value_factory()); | 265 AstNodeFactory ast_node_factory(info->ast_value_factory()); |
| 266 if (!top->AllocateVariables(info, &ast_node_factory)) { | 266 if (!top->AllocateVariables(info, &ast_node_factory)) { |
| 267 DCHECK(top->pending_error_handler_.has_pending_error()); | 267 DCHECK(top->pending_error_handler_.has_pending_error()); |
| 268 top->pending_error_handler_.ThrowPendingError(info->isolate(), | 268 top->pending_error_handler_.ThrowPendingError(info->isolate(), |
| 269 info->script()); | 269 info->script()); |
| 270 return false; | 270 return false; |
| 271 } | 271 } |
| 272 } | 272 } |
| 273 | 273 |
| 274 #ifdef DEBUG | 274 #ifdef DEBUG |
| 275 if (info->isolate()->bootstrapper()->IsActive() | 275 if (info->isolate()->bootstrapper()->IsActive() |
| 276 ? FLAG_print_builtin_scopes | 276 ? FLAG_print_builtin_scopes |
| 277 : FLAG_print_scopes) { | 277 : FLAG_print_scopes) { |
| 278 scope->Print(); | 278 scope->Print(); |
| 279 } | 279 } |
| 280 #endif | 280 #endif |
| 281 | 281 |
| 282 info->PrepareForCompilation(scope); | 282 info->set_scope(scope); |
| 283 return true; | 283 return true; |
| 284 } | 284 } |
| 285 | 285 |
| 286 | 286 |
| 287 void Scope::Initialize(bool subclass_constructor) { | 287 void Scope::Initialize(bool subclass_constructor) { |
| 288 DCHECK(!already_resolved()); | 288 DCHECK(!already_resolved()); |
| 289 | 289 |
| 290 // Add this scope as a new inner scope of the outer scope. | 290 // Add this scope as a new inner scope of the outer scope. |
| 291 if (outer_scope_ != NULL) { | 291 if (outer_scope_ != NULL) { |
| 292 outer_scope_->inner_scopes_.Add(this, zone()); | 292 outer_scope_->inner_scopes_.Add(this, zone()); |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 632 Variable* var = vars[i].var(); | 632 Variable* var = vars[i].var(); |
| 633 if (var->IsStackLocal()) { | 633 if (var->IsStackLocal()) { |
| 634 stack_locals->Add(var, zone()); | 634 stack_locals->Add(var, zone()); |
| 635 } else if (var->IsContextSlot()) { | 635 } else if (var->IsContextSlot()) { |
| 636 context_locals->Add(var, zone()); | 636 context_locals->Add(var, zone()); |
| 637 } | 637 } |
| 638 } | 638 } |
| 639 } | 639 } |
| 640 | 640 |
| 641 | 641 |
| 642 bool Scope::AllocateVariables(CompilationInfo* info, AstNodeFactory* factory) { | 642 bool Scope::AllocateVariables(ParseInfo* info, AstNodeFactory* factory) { |
| 643 // 1) Propagate scope information. | 643 // 1) Propagate scope information. |
| 644 bool outer_scope_calls_sloppy_eval = false; | 644 bool outer_scope_calls_sloppy_eval = false; |
| 645 if (outer_scope_ != NULL) { | 645 if (outer_scope_ != NULL) { |
| 646 outer_scope_calls_sloppy_eval = | 646 outer_scope_calls_sloppy_eval = |
| 647 outer_scope_->outer_scope_calls_sloppy_eval() | | 647 outer_scope_->outer_scope_calls_sloppy_eval() | |
| 648 outer_scope_->calls_sloppy_eval(); | 648 outer_scope_->calls_sloppy_eval(); |
| 649 } | 649 } |
| 650 PropagateScopeInfo(outer_scope_calls_sloppy_eval); | 650 PropagateScopeInfo(outer_scope_calls_sloppy_eval); |
| 651 | 651 |
| 652 // 2) Allocate module instances. | 652 // 2) Allocate module instances. |
| (...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1048 if (*binding_kind == BOUND) { | 1048 if (*binding_kind == BOUND) { |
| 1049 *binding_kind = BOUND_EVAL_SHADOWED; | 1049 *binding_kind = BOUND_EVAL_SHADOWED; |
| 1050 } else if (*binding_kind == UNBOUND) { | 1050 } else if (*binding_kind == UNBOUND) { |
| 1051 *binding_kind = UNBOUND_EVAL_SHADOWED; | 1051 *binding_kind = UNBOUND_EVAL_SHADOWED; |
| 1052 } | 1052 } |
| 1053 } | 1053 } |
| 1054 return var; | 1054 return var; |
| 1055 } | 1055 } |
| 1056 | 1056 |
| 1057 | 1057 |
| 1058 bool Scope::ResolveVariable(CompilationInfo* info, VariableProxy* proxy, | 1058 bool Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy, |
| 1059 AstNodeFactory* factory) { | 1059 AstNodeFactory* factory) { |
| 1060 DCHECK(info->script_scope()->is_script_scope()); | 1060 DCHECK(info->script_scope()->is_script_scope()); |
| 1061 | 1061 |
| 1062 // If the proxy is already resolved there's nothing to do | 1062 // If the proxy is already resolved there's nothing to do |
| 1063 // (functions and consts may be resolved by the parser). | 1063 // (functions and consts may be resolved by the parser). |
| 1064 if (proxy->is_resolved()) return true; | 1064 if (proxy->is_resolved()) return true; |
| 1065 | 1065 |
| 1066 // Otherwise, try to resolve the variable. | 1066 // Otherwise, try to resolve the variable. |
| 1067 BindingKind binding_kind; | 1067 BindingKind binding_kind; |
| 1068 Variable* var = LookupRecursive(proxy, &binding_kind, factory); | 1068 Variable* var = LookupRecursive(proxy, &binding_kind, factory); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1130 | 1130 |
| 1131 DCHECK(var != NULL); | 1131 DCHECK(var != NULL); |
| 1132 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1132 if (proxy->is_assigned()) var->set_maybe_assigned(); |
| 1133 | 1133 |
| 1134 proxy->BindTo(var); | 1134 proxy->BindTo(var); |
| 1135 | 1135 |
| 1136 return true; | 1136 return true; |
| 1137 } | 1137 } |
| 1138 | 1138 |
| 1139 | 1139 |
| 1140 bool Scope::ResolveVariablesRecursively(CompilationInfo* info, | 1140 bool Scope::ResolveVariablesRecursively(ParseInfo* info, |
| 1141 AstNodeFactory* factory) { | 1141 AstNodeFactory* factory) { |
| 1142 DCHECK(info->script_scope()->is_script_scope()); | 1142 DCHECK(info->script_scope()->is_script_scope()); |
| 1143 | 1143 |
| 1144 // Resolve unresolved variables for this scope. | 1144 // Resolve unresolved variables for this scope. |
| 1145 for (int i = 0; i < unresolved_.length(); i++) { | 1145 for (int i = 0; i < unresolved_.length(); i++) { |
| 1146 if (!ResolveVariable(info, unresolved_[i], factory)) return false; | 1146 if (!ResolveVariable(info, unresolved_[i], factory)) return false; |
| 1147 } | 1147 } |
| 1148 | 1148 |
| 1149 // Resolve unresolved variables for inner scopes. | 1149 // Resolve unresolved variables for inner scopes. |
| 1150 for (int i = 0; i < inner_scopes_.length(); i++) { | 1150 for (int i = 0; i < inner_scopes_.length(); i++) { |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1425 } | 1425 } |
| 1426 | 1426 |
| 1427 | 1427 |
| 1428 int Scope::ContextLocalCount() const { | 1428 int Scope::ContextLocalCount() const { |
| 1429 if (num_heap_slots() == 0) return 0; | 1429 if (num_heap_slots() == 0) return 0; |
| 1430 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1430 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1431 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); | 1431 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
| 1432 } | 1432 } |
| 1433 | 1433 |
| 1434 } } // namespace v8::internal | 1434 } } // namespace v8::internal |
| OLD | NEW |