| 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/scopes.h" | 5 #include "src/scopes.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/bootstrapper.h" | 8 #include "src/bootstrapper.h" |
| 9 #include "src/messages.h" | 9 #include "src/messages.h" |
| 10 #include "src/parser.h" | 10 #include "src/parser.h" |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 module_var_ = NULL; | 182 module_var_ = NULL; |
| 183 has_simple_parameters_ = true; | 183 has_simple_parameters_ = true; |
| 184 rest_parameter_ = NULL; | 184 rest_parameter_ = NULL; |
| 185 rest_index_ = -1; | 185 rest_index_ = -1; |
| 186 scope_info_ = scope_info; | 186 scope_info_ = scope_info; |
| 187 start_position_ = RelocInfo::kNoPosition; | 187 start_position_ = RelocInfo::kNoPosition; |
| 188 end_position_ = RelocInfo::kNoPosition; | 188 end_position_ = RelocInfo::kNoPosition; |
| 189 if (!scope_info.is_null()) { | 189 if (!scope_info.is_null()) { |
| 190 scope_calls_eval_ = scope_info->CallsEval(); | 190 scope_calls_eval_ = scope_info->CallsEval(); |
| 191 language_mode_ = scope_info->language_mode(); | 191 language_mode_ = scope_info->language_mode(); |
| 192 is_declaration_scope_ = scope_info->is_declaration_scope(); |
| 192 function_kind_ = scope_info->function_kind(); | 193 function_kind_ = scope_info->function_kind(); |
| 193 } | 194 } |
| 194 } | 195 } |
| 195 | 196 |
| 196 | 197 |
| 197 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 198 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
| 198 Context* context, Scope* script_scope) { | 199 Context* context, Scope* script_scope) { |
| 199 // Reconstruct the outer scope chain from a closure's context chain. | 200 // Reconstruct the outer scope chain from a closure's context chain. |
| 200 Scope* current_scope = NULL; | 201 Scope* current_scope = NULL; |
| 201 Scope* innermost_scope = NULL; | 202 Scope* innermost_scope = NULL; |
| 202 bool contains_with = false; | 203 bool contains_with = false; |
| 203 while (!context->IsNativeContext()) { | 204 while (!context->IsNativeContext()) { |
| 204 if (context->IsWithContext()) { | 205 if (context->IsWithContext()) { |
| 205 Scope* with_scope = new (zone) | 206 Scope* with_scope = new (zone) |
| 206 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null(), | 207 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null(), |
| 207 script_scope->ast_value_factory_); | 208 script_scope->ast_value_factory_); |
| 208 current_scope = with_scope; | 209 current_scope = with_scope; |
| 209 // All the inner scopes are inside a with. | 210 // All the inner scopes are inside a with. |
| 210 contains_with = true; | 211 contains_with = true; |
| 211 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { | 212 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
| 212 s->scope_inside_with_ = true; | 213 s->scope_inside_with_ = true; |
| 213 } | 214 } |
| 214 } else if (context->IsScriptContext()) { | 215 } else if (context->IsScriptContext()) { |
| 215 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); | 216 ScopeInfo* scope_info = context->scope_info(); |
| 216 current_scope = new (zone) Scope(zone, current_scope, SCRIPT_SCOPE, | 217 current_scope = new (zone) Scope(zone, current_scope, SCRIPT_SCOPE, |
| 217 Handle<ScopeInfo>(scope_info), | 218 Handle<ScopeInfo>(scope_info), |
| 218 script_scope->ast_value_factory_); | 219 script_scope->ast_value_factory_); |
| 219 } else if (context->IsModuleContext()) { | 220 } else if (context->IsModuleContext()) { |
| 220 ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info()); | 221 ScopeInfo* scope_info = context->module()->scope_info(); |
| 221 current_scope = new (zone) Scope(zone, current_scope, MODULE_SCOPE, | 222 current_scope = new (zone) Scope(zone, current_scope, MODULE_SCOPE, |
| 222 Handle<ScopeInfo>(scope_info), | 223 Handle<ScopeInfo>(scope_info), |
| 223 script_scope->ast_value_factory_); | 224 script_scope->ast_value_factory_); |
| 224 } else if (context->IsFunctionContext()) { | 225 } else if (context->IsFunctionContext()) { |
| 225 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); | 226 ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
| 226 current_scope = new (zone) Scope(zone, current_scope, FUNCTION_SCOPE, | 227 current_scope = new (zone) Scope(zone, current_scope, FUNCTION_SCOPE, |
| 227 Handle<ScopeInfo>(scope_info), | 228 Handle<ScopeInfo>(scope_info), |
| 228 script_scope->ast_value_factory_); | 229 script_scope->ast_value_factory_); |
| 229 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; | 230 if (scope_info->IsAsmFunction()) current_scope->asm_function_ = true; |
| 230 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; | 231 if (scope_info->IsAsmModule()) current_scope->asm_module_ = true; |
| 231 } else if (context->IsBlockContext()) { | 232 } else if (context->IsBlockContext()) { |
| 232 ScopeInfo* scope_info = ScopeInfo::cast(context->extension()); | 233 ScopeInfo* scope_info = context->scope_info(); |
| 233 current_scope = new (zone) | 234 current_scope = new (zone) |
| 234 Scope(zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info), | 235 Scope(zone, current_scope, BLOCK_SCOPE, Handle<ScopeInfo>(scope_info), |
| 235 script_scope->ast_value_factory_); | 236 script_scope->ast_value_factory_); |
| 236 } else { | 237 } else { |
| 237 DCHECK(context->IsCatchContext()); | 238 DCHECK(context->IsCatchContext()); |
| 238 String* name = String::cast(context->extension()); | 239 String* name = context->catch_name(); |
| 239 current_scope = new (zone) Scope( | 240 current_scope = new (zone) Scope( |
| 240 zone, current_scope, | 241 zone, current_scope, |
| 241 script_scope->ast_value_factory_->GetString(Handle<String>(name)), | 242 script_scope->ast_value_factory_->GetString(Handle<String>(name)), |
| 242 script_scope->ast_value_factory_); | 243 script_scope->ast_value_factory_); |
| 243 } | 244 } |
| 244 if (contains_with) current_scope->RecordWithStatement(); | 245 if (contains_with) current_scope->RecordWithStatement(); |
| 245 if (innermost_scope == NULL) innermost_scope = current_scope; | 246 if (innermost_scope == NULL) innermost_scope = current_scope; |
| 246 | 247 |
| 247 // Forget about a with when we move to a context for a different function. | 248 // Forget about a with when we move to a context for a different function. |
| 248 if (context->previous()->closure() != context->closure()) { | 249 if (context->previous()->closure() != context->closure()) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 337 } | 338 } |
| 338 } | 339 } |
| 339 } | 340 } |
| 340 | 341 |
| 341 | 342 |
| 342 Scope* Scope::FinalizeBlockScope() { | 343 Scope* Scope::FinalizeBlockScope() { |
| 343 DCHECK(is_block_scope()); | 344 DCHECK(is_block_scope()); |
| 344 DCHECK(temps_.is_empty()); | 345 DCHECK(temps_.is_empty()); |
| 345 DCHECK(params_.is_empty()); | 346 DCHECK(params_.is_empty()); |
| 346 | 347 |
| 347 if (num_var_or_const() > 0) return this; | 348 if (num_var_or_const() > 0 || |
| 349 (is_declaration_scope() && calls_sloppy_eval())) { |
| 350 return this; |
| 351 } |
| 348 | 352 |
| 349 // Remove this scope from outer scope. | 353 // Remove this scope from outer scope. |
| 350 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) { | 354 for (int i = 0; i < outer_scope_->inner_scopes_.length(); i++) { |
| 351 if (outer_scope_->inner_scopes_[i] == this) { | 355 if (outer_scope_->inner_scopes_[i] == this) { |
| 352 outer_scope_->inner_scopes_.Remove(i); | 356 outer_scope_->inner_scopes_.Remove(i); |
| 353 break; | 357 break; |
| 354 } | 358 } |
| 355 } | 359 } |
| 356 | 360 |
| 357 // Reparent inner scopes. | 361 // Reparent inner scopes. |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 while (!top->is_script_scope() && !top->outer_scope()->already_resolved()) { | 808 while (!top->is_script_scope() && !top->outer_scope()->already_resolved()) { |
| 805 top = top->outer_scope(); | 809 top = top->outer_scope(); |
| 806 } | 810 } |
| 807 | 811 |
| 808 top->pending_error_handler_.ReportMessageAt(start_position, end_position, | 812 top->pending_error_handler_.ReportMessageAt(start_position, end_position, |
| 809 message, arg, kReferenceError); | 813 message, arg, kReferenceError); |
| 810 } | 814 } |
| 811 | 815 |
| 812 | 816 |
| 813 #ifdef DEBUG | 817 #ifdef DEBUG |
| 814 static const char* Header(ScopeType scope_type) { | 818 static const char* Header(ScopeType scope_type, bool is_declaration_scope) { |
| 815 switch (scope_type) { | 819 switch (scope_type) { |
| 816 case EVAL_SCOPE: return "eval"; | 820 case EVAL_SCOPE: return "eval"; |
| 817 case FUNCTION_SCOPE: return "function"; | 821 case FUNCTION_SCOPE: return "function"; |
| 818 case MODULE_SCOPE: return "module"; | 822 case MODULE_SCOPE: return "module"; |
| 819 case SCRIPT_SCOPE: return "global"; | 823 case SCRIPT_SCOPE: return "global"; |
| 820 case CATCH_SCOPE: return "catch"; | 824 case CATCH_SCOPE: return "catch"; |
| 821 case BLOCK_SCOPE: return "block"; | 825 case BLOCK_SCOPE: return is_declaration_scope ? "varblock" : "block"; |
| 822 case WITH_SCOPE: return "with"; | 826 case WITH_SCOPE: return "with"; |
| 823 case ARROW_SCOPE: return "arrow"; | 827 case ARROW_SCOPE: return "arrow"; |
| 824 } | 828 } |
| 825 UNREACHABLE(); | 829 UNREACHABLE(); |
| 826 return NULL; | 830 return NULL; |
| 827 } | 831 } |
| 828 | 832 |
| 829 | 833 |
| 830 static void Indent(int n, const char* str) { | 834 static void Indent(int n, const char* str) { |
| 831 PrintF("%*s%s", n, "", str); | 835 PrintF("%*s%s", n, "", str); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 } | 899 } |
| 896 } | 900 } |
| 897 } | 901 } |
| 898 | 902 |
| 899 | 903 |
| 900 void Scope::Print(int n) { | 904 void Scope::Print(int n) { |
| 901 int n0 = (n > 0 ? n : 0); | 905 int n0 = (n > 0 ? n : 0); |
| 902 int n1 = n0 + 2; // indentation | 906 int n1 = n0 + 2; // indentation |
| 903 | 907 |
| 904 // Print header. | 908 // Print header. |
| 905 Indent(n0, Header(scope_type_)); | 909 Indent(n0, Header(scope_type_, is_declaration_scope())); |
| 906 if (!scope_name_->IsEmpty()) { | 910 if (!scope_name_->IsEmpty()) { |
| 907 PrintF(" "); | 911 PrintF(" "); |
| 908 PrintName(scope_name_); | 912 PrintName(scope_name_); |
| 909 } | 913 } |
| 910 | 914 |
| 911 // Print parameters, if any. | 915 // Print parameters, if any. |
| 912 if (is_function_scope()) { | 916 if (is_function_scope()) { |
| 913 PrintF(" ("); | 917 PrintF(" ("); |
| 914 for (int i = 0; i < params_.length(); i++) { | 918 for (int i = 0; i < params_.length(); i++) { |
| 915 if (i > 0) PrintF(", "); | 919 if (i > 0) PrintF(", "); |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1560 // Allocate variables for this scope. | 1564 // Allocate variables for this scope. |
| 1561 // Parameters must be allocated first, if any. | 1565 // Parameters must be allocated first, if any. |
| 1562 if (is_function_scope()) AllocateParameterLocals(isolate); | 1566 if (is_function_scope()) AllocateParameterLocals(isolate); |
| 1563 if (has_this_declaration()) AllocateReceiver(); | 1567 if (has_this_declaration()) AllocateReceiver(); |
| 1564 AllocateNonParameterLocalsAndDeclaredGlobals(isolate); | 1568 AllocateNonParameterLocalsAndDeclaredGlobals(isolate); |
| 1565 | 1569 |
| 1566 // Force allocation of a context for this scope if necessary. For a 'with' | 1570 // Force allocation of a context for this scope if necessary. For a 'with' |
| 1567 // scope and for a function scope that makes an 'eval' call we need a context, | 1571 // scope and for a function scope that makes an 'eval' call we need a context, |
| 1568 // even if no local variables were statically allocated in the scope. | 1572 // even if no local variables were statically allocated in the scope. |
| 1569 // Likewise for modules. | 1573 // Likewise for modules. |
| 1570 bool must_have_context = is_with_scope() || is_module_scope() || | 1574 bool must_have_context = |
| 1571 (is_function_scope() && calls_sloppy_eval()); | 1575 is_with_scope() || is_module_scope() || |
| 1576 (is_function_scope() && calls_sloppy_eval()) || |
| 1577 (is_block_scope() && is_declaration_scope() && calls_sloppy_eval()); |
| 1572 | 1578 |
| 1573 // If we didn't allocate any locals in the local context, then we only | 1579 // If we didn't allocate any locals in the local context, then we only |
| 1574 // need the minimal number of slots if we must have a context. | 1580 // need the minimal number of slots if we must have a context. |
| 1575 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { | 1581 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && !must_have_context) { |
| 1576 num_heap_slots_ = 0; | 1582 num_heap_slots_ = 0; |
| 1577 } | 1583 } |
| 1578 | 1584 |
| 1579 // Allocation done. | 1585 // Allocation done. |
| 1580 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1586 DCHECK(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
| 1581 } | 1587 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1610 function_ != NULL && function_->proxy()->var()->IsContextSlot(); | 1616 function_ != NULL && function_->proxy()->var()->IsContextSlot(); |
| 1611 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1617 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - |
| 1612 (is_function_var_in_context ? 1 : 0); | 1618 (is_function_var_in_context ? 1 : 0); |
| 1613 } | 1619 } |
| 1614 | 1620 |
| 1615 | 1621 |
| 1616 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1622 int Scope::ContextGlobalCount() const { return num_global_slots(); } |
| 1617 | 1623 |
| 1618 } // namespace internal | 1624 } // namespace internal |
| 1619 } // namespace v8 | 1625 } // namespace v8 |
| OLD | NEW |