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 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 60 VariableMap::VariableMap() : ZoneHashMap(Match, 8) {} | 60 VariableMap::VariableMap() : ZoneHashMap(Match, 8) {} |
| 61 VariableMap::~VariableMap() {} | 61 VariableMap::~VariableMap() {} |
| 62 | 62 |
| 63 | 63 |
| 64 Variable* VariableMap::Declare( | 64 Variable* VariableMap::Declare( |
| 65 Scope* scope, | 65 Scope* scope, |
| 66 Handle<String> name, | 66 Handle<String> name, |
| 67 VariableMode mode, | 67 VariableMode mode, |
| 68 bool is_valid_lhs, | 68 bool is_valid_lhs, |
| 69 Variable::Kind kind, | 69 Variable::Kind kind, |
| 70 InitializationFlag initialization_flag) { | 70 InitializationFlag initialization_flag, |
| 71 Interface* interface) { | |
| 71 Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true); | 72 Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), true); |
| 72 if (p->value == NULL) { | 73 if (p->value == NULL) { |
| 73 // The variable has not been declared yet -> insert it. | 74 // The variable has not been declared yet -> insert it. |
| 74 ASSERT(p->key == name.location()); | 75 ASSERT(p->key == name.location()); |
| 75 p->value = new Variable(scope, | 76 p->value = new Variable(scope, |
| 76 name, | 77 name, |
| 77 mode, | 78 mode, |
| 78 is_valid_lhs, | 79 is_valid_lhs, |
| 79 kind, | 80 kind, |
| 80 initialization_flag); | 81 initialization_flag, |
| 82 interface); | |
| 81 } | 83 } |
| 82 return reinterpret_cast<Variable*>(p->value); | 84 return reinterpret_cast<Variable*>(p->value); |
| 83 } | 85 } |
| 84 | 86 |
| 85 | 87 |
| 86 Variable* VariableMap::Lookup(Handle<String> name) { | 88 Variable* VariableMap::Lookup(Handle<String> name) { |
| 87 Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), false); | 89 Entry* p = ZoneHashMap::Lookup(name.location(), name->Hash(), false); |
| 88 if (p != NULL) { | 90 if (p != NULL) { |
| 89 ASSERT(*reinterpret_cast<String**>(p->key) == *name); | 91 ASSERT(*reinterpret_cast<String**>(p->key) == *name); |
| 90 ASSERT(p->value != NULL); | 92 ASSERT(p->value != NULL); |
| 91 return reinterpret_cast<Variable*>(p->value); | 93 return reinterpret_cast<Variable*>(p->value); |
| 92 } | 94 } |
| 93 return NULL; | 95 return NULL; |
| 94 } | 96 } |
| 95 | 97 |
| 96 | 98 |
| 97 // ---------------------------------------------------------------------------- | 99 // ---------------------------------------------------------------------------- |
| 98 // Implementation of Scope | 100 // Implementation of Scope |
| 99 | 101 |
| 100 Scope::Scope(Scope* outer_scope, ScopeType type) | 102 Scope::Scope(Scope* outer_scope, ScopeType type) |
| 101 : isolate_(Isolate::Current()), | 103 : isolate_(Isolate::Current()), |
| 102 inner_scopes_(4), | 104 inner_scopes_(4), |
| 103 variables_(), | 105 variables_(), |
| 104 temps_(4), | 106 temps_(4), |
| 105 params_(4), | 107 params_(4), |
| 106 unresolved_(16), | 108 unresolved_(16), |
| 107 decls_(4), | 109 decls_(4), |
| 110 interface_(FLAG_harmony_modules && | |
| 111 (type == MODULE_SCOPE || type == GLOBAL_SCOPE) | |
| 112 ? Interface::NewModule() : NULL), | |
| 108 already_resolved_(false) { | 113 already_resolved_(false) { |
| 109 SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); | 114 SetDefaults(type, outer_scope, Handle<ScopeInfo>::null()); |
| 110 // At some point we might want to provide outer scopes to | 115 // At some point we might want to provide outer scopes to |
| 111 // eval scopes (by walking the stack and reading the scope info). | 116 // eval scopes (by walking the stack and reading the scope info). |
| 112 // In that case, the ASSERT below needs to be adjusted. | 117 // In that case, the ASSERT below needs to be adjusted. |
| 113 ASSERT_EQ(type == GLOBAL_SCOPE, outer_scope == NULL); | 118 ASSERT_EQ(type == GLOBAL_SCOPE, outer_scope == NULL); |
| 114 ASSERT(!HasIllegalRedeclaration()); | 119 ASSERT(!HasIllegalRedeclaration()); |
| 115 } | 120 } |
| 116 | 121 |
| 117 | 122 |
| 118 Scope::Scope(Scope* inner_scope, | 123 Scope::Scope(Scope* inner_scope, |
| 119 ScopeType type, | 124 ScopeType type, |
| 120 Handle<ScopeInfo> scope_info) | 125 Handle<ScopeInfo> scope_info) |
| 121 : isolate_(Isolate::Current()), | 126 : isolate_(Isolate::Current()), |
| 122 inner_scopes_(4), | 127 inner_scopes_(4), |
| 123 variables_(), | 128 variables_(), |
| 124 temps_(4), | 129 temps_(4), |
| 125 params_(4), | 130 params_(4), |
| 126 unresolved_(16), | 131 unresolved_(16), |
| 127 decls_(4), | 132 decls_(4), |
| 133 interface_(NULL), | |
| 128 already_resolved_(true) { | 134 already_resolved_(true) { |
| 129 SetDefaults(type, NULL, scope_info); | 135 SetDefaults(type, NULL, scope_info); |
| 130 if (!scope_info.is_null()) { | 136 if (!scope_info.is_null()) { |
| 131 num_heap_slots_ = scope_info_->ContextLength(); | 137 num_heap_slots_ = scope_info_->ContextLength(); |
| 132 } | 138 } |
| 133 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. | 139 // Ensure at least MIN_CONTEXT_SLOTS to indicate a materialized context. |
| 134 num_heap_slots_ = Max(num_heap_slots_, | 140 num_heap_slots_ = Max(num_heap_slots_, |
| 135 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); | 141 static_cast<int>(Context::MIN_CONTEXT_SLOTS)); |
| 136 AddInnerScope(inner_scope); | 142 AddInnerScope(inner_scope); |
| 137 } | 143 } |
| 138 | 144 |
| 139 | 145 |
| 140 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name) | 146 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name) |
| 141 : isolate_(Isolate::Current()), | 147 : isolate_(Isolate::Current()), |
| 142 inner_scopes_(1), | 148 inner_scopes_(1), |
| 143 variables_(), | 149 variables_(), |
| 144 temps_(0), | 150 temps_(0), |
| 145 params_(0), | 151 params_(0), |
| 146 unresolved_(0), | 152 unresolved_(0), |
| 147 decls_(0), | 153 decls_(0), |
| 154 interface_(NULL), | |
| 148 already_resolved_(true) { | 155 already_resolved_(true) { |
| 149 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); | 156 SetDefaults(CATCH_SCOPE, NULL, Handle<ScopeInfo>::null()); |
| 150 AddInnerScope(inner_scope); | 157 AddInnerScope(inner_scope); |
| 151 ++num_var_or_const_; | 158 ++num_var_or_const_; |
| 152 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 159 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
| 153 Variable* variable = variables_.Declare(this, | 160 Variable* variable = variables_.Declare(this, |
| 154 catch_variable_name, | 161 catch_variable_name, |
| 155 VAR, | 162 VAR, |
| 156 true, // Valid left-hand side. | 163 true, // Valid left-hand side. |
| 157 Variable::NORMAL, | 164 Variable::NORMAL, |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 248 // Traverse the scope tree up to the first unresolved scope or the global | 255 // Traverse the scope tree up to the first unresolved scope or the global |
| 249 // scope and start scope resolution and variable allocation from that scope. | 256 // scope and start scope resolution and variable allocation from that scope. |
| 250 while (!top->is_global_scope() && | 257 while (!top->is_global_scope() && |
| 251 !top->outer_scope()->already_resolved()) { | 258 !top->outer_scope()->already_resolved()) { |
| 252 top = top->outer_scope(); | 259 top = top->outer_scope(); |
| 253 } | 260 } |
| 254 | 261 |
| 255 // Allocate the variables. | 262 // Allocate the variables. |
| 256 { | 263 { |
| 257 AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate()); | 264 AstNodeFactory<AstNullVisitor> ast_node_factory(info->isolate()); |
| 258 top->AllocateVariables(info->global_scope(), &ast_node_factory); | 265 if (!top->AllocateVariables(info, &ast_node_factory)) return false; |
| 259 } | 266 } |
| 260 | 267 |
| 261 #ifdef DEBUG | 268 #ifdef DEBUG |
| 262 if (info->isolate()->bootstrapper()->IsActive() | 269 if (info->isolate()->bootstrapper()->IsActive() |
| 263 ? FLAG_print_builtin_scopes | 270 ? FLAG_print_builtin_scopes |
| 264 : FLAG_print_scopes) { | 271 : FLAG_print_scopes) { |
| 265 scope->Print(); | 272 scope->Print(); |
| 266 } | 273 } |
| 274 | |
| 275 if (FLAG_harmony_modules && FLAG_print_interfaces && top->is_global_scope()) { | |
| 276 PrintF("global : "); | |
| 277 top->interface()->Print(); | |
| 278 } | |
| 267 #endif | 279 #endif |
| 268 | 280 |
| 269 if (FLAG_harmony_scoping) { | 281 if (FLAG_harmony_scoping) { |
| 270 VariableProxy* proxy = scope->CheckAssignmentToConst(); | 282 VariableProxy* proxy = scope->CheckAssignmentToConst(); |
| 271 if (proxy != NULL) { | 283 if (proxy != NULL) { |
| 272 // Found an assignment to const. Throw a syntax error. | 284 // Found an assignment to const. Throw a syntax error. |
| 273 MessageLocation location(info->script(), | 285 MessageLocation location(info->script(), |
| 274 proxy->position(), | 286 proxy->position(), |
| 275 proxy->position()); | 287 proxy->position()); |
| 276 Isolate* isolate = info->isolate(); | 288 Isolate* isolate = info->isolate(); |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 ASSERT(!already_resolved()); | 443 ASSERT(!already_resolved()); |
| 432 ASSERT(is_function_scope()); | 444 ASSERT(is_function_scope()); |
| 433 Variable* var = variables_.Declare( | 445 Variable* var = variables_.Declare( |
| 434 this, name, mode, true, Variable::NORMAL, kCreatedInitialized); | 446 this, name, mode, true, Variable::NORMAL, kCreatedInitialized); |
| 435 params_.Add(var); | 447 params_.Add(var); |
| 436 } | 448 } |
| 437 | 449 |
| 438 | 450 |
| 439 Variable* Scope::DeclareLocal(Handle<String> name, | 451 Variable* Scope::DeclareLocal(Handle<String> name, |
| 440 VariableMode mode, | 452 VariableMode mode, |
| 441 InitializationFlag init_flag) { | 453 InitializationFlag init_flag, |
| 454 Interface* interface) { | |
| 442 ASSERT(!already_resolved()); | 455 ASSERT(!already_resolved()); |
| 443 // This function handles VAR and CONST modes. DYNAMIC variables are | 456 // This function handles VAR and CONST modes. DYNAMIC variables are |
| 444 // introduces during variable allocation, INTERNAL variables are allocated | 457 // introduces during variable allocation, INTERNAL variables are allocated |
| 445 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). | 458 // explicitly, and TEMPORARY variables are allocated via NewTemporary(). |
| 446 ASSERT(mode == VAR || | 459 ASSERT(mode == VAR || |
| 447 mode == CONST || | 460 mode == CONST || |
| 448 mode == CONST_HARMONY || | 461 mode == CONST_HARMONY || |
| 449 mode == LET); | 462 mode == LET); |
| 450 ++num_var_or_const_; | 463 ++num_var_or_const_; |
| 451 return | 464 return variables_.Declare( |
| 452 variables_.Declare(this, name, mode, true, Variable::NORMAL, init_flag); | 465 this, name, mode, true, Variable::NORMAL, init_flag, interface); |
| 453 } | 466 } |
| 454 | 467 |
| 455 | 468 |
| 456 Variable* Scope::DeclareGlobal(Handle<String> name) { | 469 Variable* Scope::DeclareGlobal(Handle<String> name) { |
| 457 ASSERT(is_global_scope()); | 470 ASSERT(is_global_scope()); |
| 458 return variables_.Declare(this, | 471 return variables_.Declare(this, |
| 459 name, | 472 name, |
| 460 DYNAMIC_GLOBAL, | 473 DYNAMIC_GLOBAL, |
| 461 true, | 474 true, |
| 462 Variable::NORMAL, | 475 Variable::NORMAL, |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 579 if (var->IsStackLocal()) { | 592 if (var->IsStackLocal()) { |
| 580 stack_locals->Add(var); | 593 stack_locals->Add(var); |
| 581 } else if (var->IsContextSlot()) { | 594 } else if (var->IsContextSlot()) { |
| 582 context_locals->Add(var); | 595 context_locals->Add(var); |
| 583 } | 596 } |
| 584 } | 597 } |
| 585 } | 598 } |
| 586 } | 599 } |
| 587 | 600 |
| 588 | 601 |
| 589 void Scope::AllocateVariables(Scope* global_scope, | 602 bool Scope::AllocateVariables(CompilationInfo* info, |
| 590 AstNodeFactory<AstNullVisitor>* factory) { | 603 AstNodeFactory<AstNullVisitor>* factory) { |
| 591 // 1) Propagate scope information. | 604 // 1) Propagate scope information. |
| 592 bool outer_scope_calls_non_strict_eval = false; | 605 bool outer_scope_calls_non_strict_eval = false; |
| 593 if (outer_scope_ != NULL) { | 606 if (outer_scope_ != NULL) { |
| 594 outer_scope_calls_non_strict_eval = | 607 outer_scope_calls_non_strict_eval = |
| 595 outer_scope_->outer_scope_calls_non_strict_eval() | | 608 outer_scope_->outer_scope_calls_non_strict_eval() | |
| 596 outer_scope_->calls_non_strict_eval(); | 609 outer_scope_->calls_non_strict_eval(); |
| 597 } | 610 } |
| 598 PropagateScopeInfo(outer_scope_calls_non_strict_eval); | 611 PropagateScopeInfo(outer_scope_calls_non_strict_eval); |
| 599 | 612 |
| 600 // 2) Resolve variables. | 613 // 2) Resolve variables. |
| 601 ResolveVariablesRecursively(global_scope, factory); | 614 if (!ResolveVariablesRecursively(info, factory)) return false; |
| 602 | 615 |
| 603 // 3) Allocate variables. | 616 // 3) Allocate variables. |
| 604 AllocateVariablesRecursively(); | 617 AllocateVariablesRecursively(); |
| 618 | |
| 619 return true; | |
| 605 } | 620 } |
| 606 | 621 |
| 607 | 622 |
| 608 bool Scope::AllowsLazyCompilation() const { | 623 bool Scope::AllowsLazyCompilation() const { |
| 609 return !force_eager_compilation_ && HasTrivialOuterContext(); | 624 return !force_eager_compilation_ && HasTrivialOuterContext(); |
| 610 } | 625 } |
| 611 | 626 |
| 612 | 627 |
| 613 bool Scope::HasTrivialContext() const { | 628 bool Scope::HasTrivialContext() const { |
| 614 // A function scope has a trivial context if it always is the global | 629 // A function scope has a trivial context if it always is the global |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 909 if (*binding_kind == BOUND) { | 924 if (*binding_kind == BOUND) { |
| 910 *binding_kind = BOUND_EVAL_SHADOWED; | 925 *binding_kind = BOUND_EVAL_SHADOWED; |
| 911 } else if (*binding_kind == UNBOUND) { | 926 } else if (*binding_kind == UNBOUND) { |
| 912 *binding_kind = UNBOUND_EVAL_SHADOWED; | 927 *binding_kind = UNBOUND_EVAL_SHADOWED; |
| 913 } | 928 } |
| 914 } | 929 } |
| 915 return var; | 930 return var; |
| 916 } | 931 } |
| 917 | 932 |
| 918 | 933 |
| 919 void Scope::ResolveVariable(Scope* global_scope, | 934 bool Scope::ResolveVariable(CompilationInfo* info, |
| 920 VariableProxy* proxy, | 935 VariableProxy* proxy, |
| 921 AstNodeFactory<AstNullVisitor>* factory) { | 936 AstNodeFactory<AstNullVisitor>* factory) { |
| 922 ASSERT(global_scope == NULL || global_scope->is_global_scope()); | 937 ASSERT(info->global_scope()->is_global_scope()); |
| 923 | 938 |
| 924 // If the proxy is already resolved there's nothing to do | 939 // If the proxy is already resolved there's nothing to do |
| 925 // (functions and consts may be resolved by the parser). | 940 // (functions and consts may be resolved by the parser). |
| 926 if (proxy->var() != NULL) return; | 941 if (proxy->var() != NULL) return true; |
| 927 | 942 |
| 928 // Otherwise, try to resolve the variable. | 943 // Otherwise, try to resolve the variable. |
| 929 BindingKind binding_kind; | 944 BindingKind binding_kind; |
| 930 Variable* var = LookupRecursive(proxy->name(), &binding_kind, factory); | 945 Variable* var = LookupRecursive(proxy->name(), &binding_kind, factory); |
| 931 switch (binding_kind) { | 946 switch (binding_kind) { |
| 932 case BOUND: | 947 case BOUND: |
| 933 // We found a variable binding. | 948 // We found a variable binding. |
| 934 break; | 949 break; |
| 935 | 950 |
| 936 case BOUND_EVAL_SHADOWED: | 951 case BOUND_EVAL_SHADOWED: |
| 937 // We found a variable variable binding that might be shadowed | 952 // We found a variable variable binding that might be shadowed |
| 938 // by 'eval' introduced variable bindings. | 953 // by 'eval' introduced variable bindings. |
| 939 if (var->is_global()) { | 954 if (var->is_global()) { |
| 940 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); | 955 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); |
| 941 } else { | 956 } else { |
| 942 Variable* invalidated = var; | 957 Variable* invalidated = var; |
| 943 var = NonLocal(proxy->name(), DYNAMIC_LOCAL); | 958 var = NonLocal(proxy->name(), DYNAMIC_LOCAL); |
| 944 var->set_local_if_not_shadowed(invalidated); | 959 var->set_local_if_not_shadowed(invalidated); |
| 945 } | 960 } |
| 946 break; | 961 break; |
| 947 | 962 |
| 948 case UNBOUND: | 963 case UNBOUND: |
| 949 // No binding has been found. Declare a variable in global scope. | 964 // No binding has been found. Declare a variable in global scope. |
| 950 ASSERT(global_scope != NULL); | 965 var = info->global_scope()->DeclareGlobal(proxy->name()); |
| 951 var = global_scope->DeclareGlobal(proxy->name()); | |
| 952 break; | 966 break; |
| 953 | 967 |
| 954 case UNBOUND_EVAL_SHADOWED: | 968 case UNBOUND_EVAL_SHADOWED: |
| 955 // No binding has been found. But some scope makes a | 969 // No binding has been found. But some scope makes a |
| 956 // non-strict 'eval' call. | 970 // non-strict 'eval' call. |
| 957 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); | 971 var = NonLocal(proxy->name(), DYNAMIC_GLOBAL); |
| 958 break; | 972 break; |
| 959 | 973 |
| 960 case DYNAMIC_LOOKUP: | 974 case DYNAMIC_LOOKUP: |
| 961 // The variable could not be resolved statically. | 975 // The variable could not be resolved statically. |
| 962 var = NonLocal(proxy->name(), DYNAMIC); | 976 var = NonLocal(proxy->name(), DYNAMIC); |
| 963 break; | 977 break; |
| 964 } | 978 } |
| 965 | 979 |
| 966 ASSERT(var != NULL); | 980 ASSERT(var != NULL); |
| 967 proxy->BindTo(var); | 981 proxy->BindTo(var); |
| 982 | |
| 983 if (FLAG_harmony_modules) { | |
| 984 bool ok; | |
| 985 #ifdef DEBUG | |
| 986 if (FLAG_print_interface_details) | |
| 987 PrintF("# Resolve %s:\n", var->name()->ToAsciiArray()); | |
| 988 #endif | |
| 989 proxy->interface()->Unify(var->interface(), &ok); | |
| 990 if (!ok) { | |
| 991 #ifdef DEBUG | |
| 992 if (FLAG_print_interfaces) { | |
| 993 PrintF("SCOPES TYPE ERROR\n"); | |
| 994 PrintF("proxy: "); | |
| 995 proxy->interface()->Print(); | |
| 996 PrintF("var: "); | |
| 997 var->interface()->Print(); | |
| 998 } | |
| 999 #endif | |
| 1000 | |
| 1001 // Inconsistent use of module. Throw a syntax error. | |
| 1002 // TODO(rossberg): generate more helpful error message. | |
| 1003 MessageLocation location(info->script(), | |
| 1004 proxy->position(), | |
| 1005 proxy->position()); | |
| 1006 Isolate* isolate = Isolate::Current(); | |
| 1007 Factory* factory = isolate->factory(); | |
| 1008 Handle<JSArray> array = factory->NewJSArray(1); | |
| 1009 array->SetElement(array, 0, var->name(), NONE, kStrictMode); | |
| 1010 Handle<Object> result = | |
| 1011 factory->NewSyntaxError("module_type_error", array); | |
| 1012 isolate->Throw(*result, &location); | |
| 1013 return false; | |
| 1014 } | |
| 1015 } | |
| 1016 | |
| 1017 return true; | |
| 968 } | 1018 } |
| 969 | 1019 |
| 970 | 1020 |
| 971 void Scope::ResolveVariablesRecursively( | 1021 bool Scope::ResolveVariablesRecursively( |
| 972 Scope* global_scope, | 1022 CompilationInfo* info, |
| 973 AstNodeFactory<AstNullVisitor>* factory) { | 1023 AstNodeFactory<AstNullVisitor>* factory) { |
| 974 ASSERT(global_scope == NULL || global_scope->is_global_scope()); | 1024 ASSERT(info->global_scope()->is_global_scope()); |
| 975 | 1025 |
| 976 // Resolve unresolved variables for this scope. | 1026 // Resolve unresolved variables for this scope. |
| 977 for (int i = 0; i < unresolved_.length(); i++) { | 1027 for (int i = 0; i < unresolved_.length(); i++) { |
| 978 ResolveVariable(global_scope, unresolved_[i], factory); | 1028 if (!ResolveVariable(info, unresolved_[i], factory)) return false; |
| 979 } | 1029 } |
| 980 | 1030 |
| 981 // Resolve unresolved variables for inner scopes. | 1031 // Resolve unresolved variables for inner scopes. |
| 982 for (int i = 0; i < inner_scopes_.length(); i++) { | 1032 for (int i = 0; i < inner_scopes_.length(); i++) { |
| 983 inner_scopes_[i]->ResolveVariablesRecursively(global_scope, factory); | 1033 if (!inner_scopes_[i]->ResolveVariablesRecursively(info, factory)) |
|
Sven Panne
2012/03/08 08:55:00
I know that this recursive call has been there bef
rossberg
2012/03/08 10:47:06
See my respective comment in interface.cc.
| |
| 1034 return false; | |
| 984 } | 1035 } |
| 1036 | |
| 1037 return true; | |
| 985 } | 1038 } |
| 986 | 1039 |
| 987 | 1040 |
| 988 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) { | 1041 bool Scope::PropagateScopeInfo(bool outer_scope_calls_non_strict_eval ) { |
| 989 if (outer_scope_calls_non_strict_eval) { | 1042 if (outer_scope_calls_non_strict_eval) { |
| 990 outer_scope_calls_non_strict_eval_ = true; | 1043 outer_scope_calls_non_strict_eval_ = true; |
| 991 } | 1044 } |
| 992 | 1045 |
| 993 bool calls_non_strict_eval = | 1046 bool calls_non_strict_eval = |
| 994 this->calls_non_strict_eval() || outer_scope_calls_non_strict_eval_; | 1047 this->calls_non_strict_eval() || outer_scope_calls_non_strict_eval_; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1197 } | 1250 } |
| 1198 | 1251 |
| 1199 | 1252 |
| 1200 int Scope::ContextLocalCount() const { | 1253 int Scope::ContextLocalCount() const { |
| 1201 if (num_heap_slots() == 0) return 0; | 1254 if (num_heap_slots() == 0) return 0; |
| 1202 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1255 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
| 1203 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0); | 1256 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0); |
| 1204 } | 1257 } |
| 1205 | 1258 |
| 1206 } } // namespace v8::internal | 1259 } } // namespace v8::internal |
| OLD | NEW |