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 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 true, | 408 true, |
409 Variable::NORMAL, | 409 Variable::NORMAL, |
410 init_flag); | 410 init_flag); |
411 var->AllocateTo(location, index); | 411 var->AllocateTo(location, index); |
412 return var; | 412 return var; |
413 } | 413 } |
414 | 414 |
415 | 415 |
416 Variable* Scope::LookupFunctionVar(Handle<String> name, | 416 Variable* Scope::LookupFunctionVar(Handle<String> name, |
417 AstNodeFactory<AstNullVisitor>* factory) { | 417 AstNodeFactory<AstNullVisitor>* factory) { |
418 if (function_ != NULL && function_->name().is_identical_to(name)) { | 418 if (function_ != NULL && function_->proxy()->name().is_identical_to(name)) { |
419 return function_->var(); | 419 return function_->proxy()->var(); |
420 } else if (!scope_info_.is_null()) { | 420 } else if (!scope_info_.is_null()) { |
421 // If we are backed by a scope info, try to lookup the variable there. | 421 // If we are backed by a scope info, try to lookup the variable there. |
422 VariableMode mode; | 422 VariableMode mode; |
423 int index = scope_info_->FunctionContextSlotIndex(*name, &mode); | 423 int index = scope_info_->FunctionContextSlotIndex(*name, &mode); |
424 if (index < 0) return NULL; | 424 if (index < 0) return NULL; |
425 Variable* var = DeclareFunctionVar(name, mode, factory); | 425 Variable* var = new Variable( |
| 426 this, name, mode, true /* is valid LHS */, |
| 427 Variable::NORMAL, kCreatedInitialized); |
| 428 VariableProxy* proxy = factory->NewVariableProxy(var); |
| 429 VariableDeclaration* declaration = |
| 430 factory->NewVariableDeclaration(proxy, mode, this); |
| 431 DeclareFunctionVar(declaration); |
426 var->AllocateTo(Variable::CONTEXT, index); | 432 var->AllocateTo(Variable::CONTEXT, index); |
427 return var; | 433 return var; |
428 } else { | 434 } else { |
429 return NULL; | 435 return NULL; |
430 } | 436 } |
431 } | 437 } |
432 | 438 |
433 | 439 |
434 Variable* Scope::Lookup(Handle<String> name) { | 440 Variable* Scope::Lookup(Handle<String> name) { |
435 for (Scope* scope = this; | 441 for (Scope* scope = this; |
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 PrintName(params_[i]->name()); | 793 PrintName(params_[i]->name()); |
788 } | 794 } |
789 PrintF(")"); | 795 PrintF(")"); |
790 } | 796 } |
791 | 797 |
792 PrintF(" { // (%d, %d)\n", start_position(), end_position()); | 798 PrintF(" { // (%d, %d)\n", start_position(), end_position()); |
793 | 799 |
794 // Function name, if any (named function literals, only). | 800 // Function name, if any (named function literals, only). |
795 if (function_ != NULL) { | 801 if (function_ != NULL) { |
796 Indent(n1, "// (local) function name: "); | 802 Indent(n1, "// (local) function name: "); |
797 PrintName(function_->name()); | 803 PrintName(function_->proxy()->name()); |
798 PrintF("\n"); | 804 PrintF("\n"); |
799 } | 805 } |
800 | 806 |
801 // Scope info. | 807 // Scope info. |
802 if (HasTrivialOuterContext()) { | 808 if (HasTrivialOuterContext()) { |
803 Indent(n1, "// scope has trivial outer context\n"); | 809 Indent(n1, "// scope has trivial outer context\n"); |
804 } | 810 } |
805 switch (language_mode()) { | 811 switch (language_mode()) { |
806 case CLASSIC_MODE: | 812 case CLASSIC_MODE: |
807 break; | 813 break; |
(...skipping 12 matching lines...) Expand all Loading... |
820 } | 826 } |
821 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); | 827 if (inner_scope_calls_eval_) Indent(n1, "// inner scope calls 'eval'\n"); |
822 if (num_stack_slots_ > 0) { Indent(n1, "// "); | 828 if (num_stack_slots_ > 0) { Indent(n1, "// "); |
823 PrintF("%d stack slots\n", num_stack_slots_); } | 829 PrintF("%d stack slots\n", num_stack_slots_); } |
824 if (num_heap_slots_ > 0) { Indent(n1, "// "); | 830 if (num_heap_slots_ > 0) { Indent(n1, "// "); |
825 PrintF("%d heap slots\n", num_heap_slots_); } | 831 PrintF("%d heap slots\n", num_heap_slots_); } |
826 | 832 |
827 // Print locals. | 833 // Print locals. |
828 Indent(n1, "// function var\n"); | 834 Indent(n1, "// function var\n"); |
829 if (function_ != NULL) { | 835 if (function_ != NULL) { |
830 PrintVar(n1, function_->var()); | 836 PrintVar(n1, function_->proxy()->var()); |
831 } | 837 } |
832 | 838 |
833 Indent(n1, "// temporary vars\n"); | 839 Indent(n1, "// temporary vars\n"); |
834 for (int i = 0; i < temps_.length(); i++) { | 840 for (int i = 0; i < temps_.length(); i++) { |
835 PrintVar(n1, temps_[i]); | 841 PrintVar(n1, temps_[i]); |
836 } | 842 } |
837 | 843 |
838 Indent(n1, "// local vars\n"); | 844 Indent(n1, "// local vars\n"); |
839 PrintMap(n1, &variables_); | 845 PrintMap(n1, &variables_); |
840 | 846 |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 | 1092 |
1087 bool Scope::MustAllocateInContext(Variable* var) { | 1093 bool Scope::MustAllocateInContext(Variable* var) { |
1088 // If var is accessed from an inner scope, or if there is a possibility | 1094 // If var is accessed from an inner scope, or if there is a possibility |
1089 // that it might be accessed from the current or an inner scope (through | 1095 // that it might be accessed from the current or an inner scope (through |
1090 // an eval() call or a runtime with lookup), it must be allocated in the | 1096 // an eval() call or a runtime with lookup), it must be allocated in the |
1091 // context. | 1097 // context. |
1092 // | 1098 // |
1093 // Exceptions: temporary variables are never allocated in a context; | 1099 // Exceptions: temporary variables are never allocated in a context; |
1094 // catch-bound variables are always allocated in a context. | 1100 // catch-bound variables are always allocated in a context. |
1095 if (var->mode() == TEMPORARY) return false; | 1101 if (var->mode() == TEMPORARY) return false; |
1096 if (is_catch_scope() || is_block_scope()) return true; | 1102 if (is_catch_scope() || is_block_scope() || is_module_scope()) return true; |
1097 return var->has_forced_context_allocation() || | 1103 return var->has_forced_context_allocation() || |
1098 scope_calls_eval_ || | 1104 scope_calls_eval_ || |
1099 inner_scope_calls_eval_ || | 1105 inner_scope_calls_eval_ || |
1100 scope_contains_with_ || | 1106 scope_contains_with_ || |
1101 var->is_global(); | 1107 var->is_global(); |
1102 } | 1108 } |
1103 | 1109 |
1104 | 1110 |
1105 bool Scope::HasArgumentsParameter() { | 1111 bool Scope::HasArgumentsParameter() { |
1106 for (int i = 0; i < params_.length(); i++) { | 1112 for (int i = 0; i < params_.length(); i++) { |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1204 p = variables_.Next(p)) { | 1210 p = variables_.Next(p)) { |
1205 Variable* var = reinterpret_cast<Variable*>(p->value); | 1211 Variable* var = reinterpret_cast<Variable*>(p->value); |
1206 AllocateNonParameterLocal(var); | 1212 AllocateNonParameterLocal(var); |
1207 } | 1213 } |
1208 | 1214 |
1209 // For now, function_ must be allocated at the very end. If it gets | 1215 // For now, function_ must be allocated at the very end. If it gets |
1210 // allocated in the context, it must be the last slot in the context, | 1216 // allocated in the context, it must be the last slot in the context, |
1211 // because of the current ScopeInfo implementation (see | 1217 // because of the current ScopeInfo implementation (see |
1212 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). | 1218 // ScopeInfo::ScopeInfo(FunctionScope* scope) constructor). |
1213 if (function_ != NULL) { | 1219 if (function_ != NULL) { |
1214 AllocateNonParameterLocal(function_->var()); | 1220 AllocateNonParameterLocal(function_->proxy()->var()); |
1215 } | 1221 } |
1216 } | 1222 } |
1217 | 1223 |
1218 | 1224 |
1219 void Scope::AllocateVariablesRecursively() { | 1225 void Scope::AllocateVariablesRecursively() { |
1220 // Allocate variables for inner scopes. | 1226 // Allocate variables for inner scopes. |
1221 for (int i = 0; i < inner_scopes_.length(); i++) { | 1227 for (int i = 0; i < inner_scopes_.length(); i++) { |
1222 inner_scopes_[i]->AllocateVariablesRecursively(); | 1228 inner_scopes_[i]->AllocateVariablesRecursively(); |
1223 } | 1229 } |
1224 | 1230 |
1225 // If scope is already resolved, we still need to allocate | 1231 // If scope is already resolved, we still need to allocate |
1226 // variables in inner scopes which might not had been resolved yet. | 1232 // variables in inner scopes which might not had been resolved yet. |
1227 if (already_resolved()) return; | 1233 if (already_resolved()) return; |
1228 // The number of slots required for variables. | 1234 // The number of slots required for variables. |
1229 num_stack_slots_ = 0; | 1235 num_stack_slots_ = 0; |
1230 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; | 1236 num_heap_slots_ = Context::MIN_CONTEXT_SLOTS; |
1231 | 1237 |
1232 // Allocate variables for this scope. | 1238 // Allocate variables for this scope. |
1233 // Parameters must be allocated first, if any. | 1239 // Parameters must be allocated first, if any. |
1234 if (is_function_scope()) AllocateParameterLocals(); | 1240 if (is_function_scope()) AllocateParameterLocals(); |
1235 AllocateNonParameterLocals(); | 1241 AllocateNonParameterLocals(); |
1236 | 1242 |
1237 // Force allocation of a context for this scope if necessary. For a 'with' | 1243 // Force allocation of a context for this scope if necessary. For a 'with' |
1238 // scope and for a function scope that makes an 'eval' call we need a context, | 1244 // scope and for a function scope that makes an 'eval' call we need a context, |
1239 // even if no local variables were statically allocated in the scope. | 1245 // even if no local variables were statically allocated in the scope. |
1240 bool must_have_context = is_with_scope() || | 1246 // Likewise for modules. |
| 1247 bool must_have_context = is_with_scope() || is_module_scope() || |
1241 (is_function_scope() && calls_eval()); | 1248 (is_function_scope() && calls_eval()); |
1242 | 1249 |
1243 // If we didn't allocate any locals in the local context, then we only | 1250 // If we didn't allocate any locals in the local context, then we only |
1244 // need the minimal number of slots if we must have a context. | 1251 // need the minimal number of slots if we must have a context. |
1245 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1252 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
1246 num_heap_slots_ = 0; | 1253 num_heap_slots_ = 0; |
1247 } | 1254 } |
1248 | 1255 |
1249 // Allocation done. | 1256 // Allocation done. |
1250 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1257 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
1251 } | 1258 } |
1252 | 1259 |
1253 | 1260 |
1254 int Scope::StackLocalCount() const { | 1261 int Scope::StackLocalCount() const { |
1255 return num_stack_slots() - | 1262 return num_stack_slots() - |
1256 (function_ != NULL && function_->var()->IsStackLocal() ? 1 : 0); | 1263 (function_ != NULL && function_->proxy()->var()->IsStackLocal() ? 1 : 0); |
1257 } | 1264 } |
1258 | 1265 |
1259 | 1266 |
1260 int Scope::ContextLocalCount() const { | 1267 int Scope::ContextLocalCount() const { |
1261 if (num_heap_slots() == 0) return 0; | 1268 if (num_heap_slots() == 0) return 0; |
1262 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1269 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1263 (function_ != NULL && function_->var()->IsContextSlot() ? 1 : 0); | 1270 (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
1264 } | 1271 } |
1265 | 1272 |
1266 } } // namespace v8::internal | 1273 } } // namespace v8::internal |
OLD | NEW |