| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 } | 249 } |
| 250 | 250 |
| 251 // Declare convenience variables. | 251 // Declare convenience variables. |
| 252 // Declare and allocate receiver (even for the global scope, and even | 252 // Declare and allocate receiver (even for the global scope, and even |
| 253 // if naccesses_ == 0). | 253 // if naccesses_ == 0). |
| 254 // NOTE: When loading parameters in the global scope, we must take | 254 // NOTE: When loading parameters in the global scope, we must take |
| 255 // care not to access them as properties of the global object, but | 255 // care not to access them as properties of the global object, but |
| 256 // instead load them directly from the stack. Currently, the only | 256 // instead load them directly from the stack. Currently, the only |
| 257 // such parameter is 'this' which is passed on the stack when | 257 // such parameter is 'this' which is passed on the stack when |
| 258 // invoking scripts | 258 // invoking scripts |
| 259 Variable* var = | 259 if (is_catch_scope()) { |
| 260 variables_.Declare(this, FACTORY->this_symbol(), Variable::VAR, | 260 ASSERT(outer_scope() != NULL); |
| 261 false, Variable::THIS); | 261 receiver_ = outer_scope()->receiver(); |
| 262 var->set_rewrite(new Slot(var, Slot::PARAMETER, -1)); | 262 } else { |
| 263 receiver_ = var; | 263 Variable* var = |
| 264 variables_.Declare(this, FACTORY->this_symbol(), Variable::VAR, |
| 265 false, Variable::THIS); |
| 266 var->set_rewrite(new Slot(var, Slot::PARAMETER, -1)); |
| 267 receiver_ = var; |
| 268 } |
| 264 | 269 |
| 265 if (is_function_scope()) { | 270 if (is_function_scope()) { |
| 266 // Declare 'arguments' variable which exists in all functions. | 271 // Declare 'arguments' variable which exists in all functions. |
| 267 // Note that it might never be accessed, in which case it won't be | 272 // Note that it might never be accessed, in which case it won't be |
| 268 // allocated during variable allocation. | 273 // allocated during variable allocation. |
| 269 variables_.Declare(this, FACTORY->arguments_symbol(), Variable::VAR, | 274 variables_.Declare(this, FACTORY->arguments_symbol(), Variable::VAR, |
| 270 true, Variable::ARGUMENTS); | 275 true, Variable::ARGUMENTS); |
| 271 } | 276 } |
| 272 } | 277 } |
| 273 | 278 |
| (...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 507 return n; | 512 return n; |
| 508 } | 513 } |
| 509 | 514 |
| 510 | 515 |
| 511 #ifdef DEBUG | 516 #ifdef DEBUG |
| 512 static const char* Header(Scope::Type type) { | 517 static const char* Header(Scope::Type type) { |
| 513 switch (type) { | 518 switch (type) { |
| 514 case Scope::EVAL_SCOPE: return "eval"; | 519 case Scope::EVAL_SCOPE: return "eval"; |
| 515 case Scope::FUNCTION_SCOPE: return "function"; | 520 case Scope::FUNCTION_SCOPE: return "function"; |
| 516 case Scope::GLOBAL_SCOPE: return "global"; | 521 case Scope::GLOBAL_SCOPE: return "global"; |
| 522 case Scope::CATCH_SCOPE: return "catch"; |
| 517 } | 523 } |
| 518 UNREACHABLE(); | 524 UNREACHABLE(); |
| 519 return NULL; | 525 return NULL; |
| 520 } | 526 } |
| 521 | 527 |
| 522 | 528 |
| 523 static void Indent(int n, const char* str) { | 529 static void Indent(int n, const char* str) { |
| 524 PrintF("%*s%s", n, "", str); | 530 PrintF("%*s%s", n, "", str); |
| 525 } | 531 } |
| 526 | 532 |
| (...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 return scope_calls_eval_ || inner_scope_calls_eval_; | 863 return scope_calls_eval_ || inner_scope_calls_eval_; |
| 858 } | 864 } |
| 859 | 865 |
| 860 | 866 |
| 861 bool Scope::MustAllocate(Variable* var) { | 867 bool Scope::MustAllocate(Variable* var) { |
| 862 // Give var a read/write use if there is a chance it might be accessed | 868 // Give var a read/write use if there is a chance it might be accessed |
| 863 // via an eval() call. This is only possible if the variable has a | 869 // via an eval() call. This is only possible if the variable has a |
| 864 // visible name. | 870 // visible name. |
| 865 if ((var->is_this() || var->name()->length() > 0) && | 871 if ((var->is_this() || var->name()->length() > 0) && |
| 866 (var->is_accessed_from_inner_scope() || | 872 (var->is_accessed_from_inner_scope() || |
| 867 scope_calls_eval_ || inner_scope_calls_eval_ || | 873 scope_calls_eval_ || |
| 868 scope_contains_with_)) { | 874 inner_scope_calls_eval_ || |
| 875 scope_contains_with_ || |
| 876 is_catch_scope())) { |
| 869 var->set_is_used(true); | 877 var->set_is_used(true); |
| 870 } | 878 } |
| 871 // Global variables do not need to be allocated. | 879 // Global variables do not need to be allocated. |
| 872 return !var->is_global() && var->is_used(); | 880 return !var->is_global() && var->is_used(); |
| 873 } | 881 } |
| 874 | 882 |
| 875 | 883 |
| 876 bool Scope::MustAllocateInContext(Variable* var) { | 884 bool Scope::MustAllocateInContext(Variable* var) { |
| 877 // If var is accessed from an inner scope, or if there is a | 885 // If var is accessed from an inner scope, or if there is a possibility |
| 878 // possibility that it might be accessed from the current or an inner | 886 // that it might be accessed from the current or an inner scope (through |
| 879 // scope (through an eval() call), it must be allocated in the | 887 // an eval() call or a runtime with lookup), it must be allocated in the |
| 880 // context. Exception: temporary variables are not allocated in the | |
| 881 // context. | 888 // context. |
| 882 return | 889 // |
| 883 var->mode() != Variable::TEMPORARY && | 890 // Exceptions: temporary variables are never allocated in a context; |
| 884 (var->is_accessed_from_inner_scope() || | 891 // catch-bound variables are always allocated in a context. |
| 885 scope_calls_eval_ || inner_scope_calls_eval_ || | 892 if (var->mode() == Variable::TEMPORARY) return false; |
| 886 scope_contains_with_ || var->is_global()); | 893 if (is_catch_scope()) return true; |
| 894 return var->is_accessed_from_inner_scope() || |
| 895 scope_calls_eval_ || |
| 896 inner_scope_calls_eval_ || |
| 897 scope_contains_with_ || |
| 898 var->is_global(); |
| 887 } | 899 } |
| 888 | 900 |
| 889 | 901 |
| 890 bool Scope::HasArgumentsParameter() { | 902 bool Scope::HasArgumentsParameter() { |
| 891 for (int i = 0; i < params_.length(); i++) { | 903 for (int i = 0; i < params_.length(); i++) { |
| 892 if (params_[i]->name().is_identical_to(FACTORY->arguments_symbol())) | 904 if (params_[i]->name().is_identical_to(FACTORY->arguments_symbol())) |
| 893 return true; | 905 return true; |
| 894 } | 906 } |
| 895 return false; | 907 return false; |
| 896 } | 908 } |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1036 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && | 1048 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && |
| 1037 !must_have_local_context) { | 1049 !must_have_local_context) { |
| 1038 num_heap_slots_ = 0; | 1050 num_heap_slots_ = 0; |
| 1039 } | 1051 } |
| 1040 | 1052 |
| 1041 // Allocation done. | 1053 // Allocation done. |
| 1042 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); | 1054 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); |
| 1043 } | 1055 } |
| 1044 | 1056 |
| 1045 } } // namespace v8::internal | 1057 } } // namespace v8::internal |
| OLD | NEW |