Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: src/scopes.cc

Issue 7549008: Preliminary code for block scopes and block contexts. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Next iteration Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 already_resolved_(false) { 139 already_resolved_(false) {
140 SetDefaults(type, outer_scope, Handle<SerializedScopeInfo>::null()); 140 SetDefaults(type, outer_scope, Handle<SerializedScopeInfo>::null());
141 // At some point we might want to provide outer scopes to 141 // At some point we might want to provide outer scopes to
142 // eval scopes (by walking the stack and reading the scope info). 142 // eval scopes (by walking the stack and reading the scope info).
143 // In that case, the ASSERT below needs to be adjusted. 143 // In that case, the ASSERT below needs to be adjusted.
144 ASSERT((type == GLOBAL_SCOPE || type == EVAL_SCOPE) == (outer_scope == NULL)); 144 ASSERT((type == GLOBAL_SCOPE || type == EVAL_SCOPE) == (outer_scope == NULL));
145 ASSERT(!HasIllegalRedeclaration()); 145 ASSERT(!HasIllegalRedeclaration());
146 } 146 }
147 147
148 148
149 Scope::Scope(Scope* inner_scope, Handle<SerializedScopeInfo> scope_info) 149 Scope::Scope(Scope* inner_scope, Type type, Handle<SerializedScopeInfo> scope_in fo)
150 : isolate_(Isolate::Current()), 150 : isolate_(Isolate::Current()),
151 inner_scopes_(4), 151 inner_scopes_(4),
152 variables_(), 152 variables_(),
153 temps_(4), 153 temps_(4),
154 params_(4), 154 params_(4),
155 unresolved_(16), 155 unresolved_(16),
156 decls_(4), 156 decls_(4),
157 already_resolved_(true) { 157 already_resolved_(true) {
158 ASSERT(!scope_info.is_null()); 158 ASSERT(!scope_info.is_null());
159 SetDefaults(FUNCTION_SCOPE, NULL, scope_info); 159 SetDefaults(type, NULL, scope_info);
160 if (scope_info->HasHeapAllocatedLocals()) { 160 if (scope_info->HasHeapAllocatedLocals()) {
161 num_heap_slots_ = scope_info_->NumberOfContextSlots(); 161 num_heap_slots_ = scope_info_->NumberOfContextSlots();
162 } 162 }
163 AddInnerScope(inner_scope); 163 AddInnerScope(inner_scope);
164 } 164 }
165 165
166 166
167 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name) 167 Scope::Scope(Scope* inner_scope, Handle<String> catch_variable_name)
168 : isolate_(Isolate::Current()), 168 : isolate_(Isolate::Current()),
169 inner_scopes_(1), 169 inner_scopes_(1),
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 if (context->IsWithContext()) { 225 if (context->IsWithContext()) {
226 // All the inner scopes are inside a with. 226 // All the inner scopes are inside a with.
227 contains_with = true; 227 contains_with = true;
228 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { 228 for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) {
229 s->scope_inside_with_ = true; 229 s->scope_inside_with_ = true;
230 } 230 }
231 } else { 231 } else {
232 if (context->IsFunctionContext()) { 232 if (context->IsFunctionContext()) {
233 SerializedScopeInfo* scope_info = 233 SerializedScopeInfo* scope_info =
234 context->closure()->shared()->scope_info(); 234 context->closure()->shared()->scope_info();
235 current_scope = 235 current_scope = new Scope(current_scope, FUNCTION_SCOPE,
236 new Scope(current_scope, Handle<SerializedScopeInfo>(scope_info)); 236 Handle<SerializedScopeInfo>(scope_info));
237 } else if (context->IsBlockContext()) {
238 SerializedScopeInfo* scope_info =
239 SerializedScopeInfo::cast(context->extension());
240 current_scope = new Scope(current_scope, BLOCK_SCOPE,
241 Handle<SerializedScopeInfo>(scope_info));
237 } else { 242 } else {
238 ASSERT(context->IsCatchContext()); 243 ASSERT(context->IsCatchContext());
239 String* name = String::cast(context->extension()); 244 String* name = String::cast(context->extension());
240 current_scope = new Scope(current_scope, Handle<String>(name)); 245 current_scope = new Scope(current_scope, Handle<String>(name));
241 } 246 }
242 if (contains_with) current_scope->RecordWithStatement(); 247 if (contains_with) current_scope->RecordWithStatement();
243 if (innermost_scope == NULL) innermost_scope = current_scope; 248 if (innermost_scope == NULL) innermost_scope = current_scope;
244 } 249 }
245 250
246 // Forget about a with when we move to a context for a different function. 251 // Forget about a with when we move to a context for a different function.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
287 } 292 }
288 293
289 // Declare convenience variables. 294 // Declare convenience variables.
290 // Declare and allocate receiver (even for the global scope, and even 295 // Declare and allocate receiver (even for the global scope, and even
291 // if naccesses_ == 0). 296 // if naccesses_ == 0).
292 // NOTE: When loading parameters in the global scope, we must take 297 // NOTE: When loading parameters in the global scope, we must take
293 // care not to access them as properties of the global object, but 298 // care not to access them as properties of the global object, but
294 // instead load them directly from the stack. Currently, the only 299 // instead load them directly from the stack. Currently, the only
295 // such parameter is 'this' which is passed on the stack when 300 // such parameter is 'this' which is passed on the stack when
296 // invoking scripts 301 // invoking scripts
297 if (is_catch_scope()) { 302 if (is_catch_scope() || is_block_scope()) {
298 ASSERT(outer_scope() != NULL); 303 ASSERT(outer_scope() != NULL);
299 receiver_ = outer_scope()->receiver(); 304 receiver_ = outer_scope()->receiver();
300 } else { 305 } else {
306 ASSERT(is_function_scope() ||
307 is_global_scope() ||
308 is_eval_scope());
301 Variable* var = 309 Variable* var =
302 variables_.Declare(this, 310 variables_.Declare(this,
303 isolate_->factory()->this_symbol(), 311 isolate_->factory()->this_symbol(),
304 Variable::VAR, 312 Variable::VAR,
305 false, 313 false,
306 Variable::THIS); 314 Variable::THIS);
307 var->set_rewrite(NewSlot(var, Slot::PARAMETER, -1)); 315 var->set_rewrite(NewSlot(var, Slot::PARAMETER, -1));
308 receiver_ = var; 316 receiver_ = var;
309 } 317 }
310 318
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
552 for (Scope* s = this; s != scope; s = s->outer_scope_) { 560 for (Scope* s = this; s != scope; s = s->outer_scope_) {
553 ASSERT(s != NULL); // scope must be in the scope chain 561 ASSERT(s != NULL); // scope must be in the scope chain
554 if (s->num_heap_slots() > 0) n++; 562 if (s->num_heap_slots() > 0) n++;
555 } 563 }
556 return n; 564 return n;
557 } 565 }
558 566
559 567
560 Scope* Scope::DeclarationScope() { 568 Scope* Scope::DeclarationScope() {
561 Scope* scope = this; 569 Scope* scope = this;
562 while (scope->is_catch_scope()) { 570 while (scope->is_catch_scope() ||
571 scope->is_block_scope()) {
563 scope = scope->outer_scope(); 572 scope = scope->outer_scope();
564 } 573 }
565 return scope; 574 return scope;
566 } 575 }
567 576
568 577
578 Handle<SerializedScopeInfo> Scope::GetSerializedScopeInfo() {
579 if (scope_info_.is_null()) {
580 scope_info_ = SerializedScopeInfo::Create(this);
581 }
582 return scope_info_;
583 }
584
585
569 #ifdef DEBUG 586 #ifdef DEBUG
570 static const char* Header(Scope::Type type) { 587 static const char* Header(Scope::Type type) {
571 switch (type) { 588 switch (type) {
572 case Scope::EVAL_SCOPE: return "eval"; 589 case Scope::EVAL_SCOPE: return "eval";
573 case Scope::FUNCTION_SCOPE: return "function"; 590 case Scope::FUNCTION_SCOPE: return "function";
574 case Scope::GLOBAL_SCOPE: return "global"; 591 case Scope::GLOBAL_SCOPE: return "global";
575 case Scope::CATCH_SCOPE: return "catch"; 592 case Scope::CATCH_SCOPE: return "catch";
593 case Scope::BLOCK_SCOPE: return "block";
576 } 594 }
577 UNREACHABLE(); 595 UNREACHABLE();
578 return NULL; 596 return NULL;
579 } 597 }
580 598
581 599
582 static void Indent(int n, const char* str) { 600 static void Indent(int n, const char* str) {
583 PrintF("%*s%s", n, "", str); 601 PrintF("%*s%s", n, "", str);
584 } 602 }
585 603
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 // only present - if at all - for function scopes. 764 // only present - if at all - for function scopes.
747 // 765 //
748 // This lookup corresponds to a lookup in the "intermediate" scope sitting 766 // This lookup corresponds to a lookup in the "intermediate" scope sitting
749 // between this scope and the outer scope. (ECMA-262, 3rd., requires that 767 // between this scope and the outer scope. (ECMA-262, 3rd., requires that
750 // the name of named function literal is kept in an intermediate scope 768 // the name of named function literal is kept in an intermediate scope
751 // in between this scope and the next outer scope.) 769 // in between this scope and the next outer scope.)
752 if (function_ != NULL && function_->name().is_identical_to(name)) { 770 if (function_ != NULL && function_->name().is_identical_to(name)) {
753 var = function_; 771 var = function_;
754 772
755 } else if (outer_scope_ != NULL) { 773 } else if (outer_scope_ != NULL) {
756 var = outer_scope_->LookupRecursive(name, true, invalidated_local); 774 var = outer_scope_->LookupRecursive(
775 name,
776 is_block_scope() || is_catch_scope() ? inner_lookup : true,
Kevin Millikin (Chromium) 2011/08/10 11:19:27 This is subtle. I'd probably change all the ident
Steven 2011/08/10 12:21:00 Done.
777 invalidated_local);
757 // We may have found a variable in an outer scope. However, if 778 // We may have found a variable in an outer scope. However, if
758 // the current scope is inside a 'with', the actual variable may 779 // the current scope is inside a 'with', the actual variable may
759 // be a property introduced via the 'with' statement. Then, the 780 // be a property introduced via the 'with' statement. Then, the
760 // variable we may have found is just a guess. 781 // variable we may have found is just a guess.
761 if (scope_inside_with_) 782 if (scope_inside_with_)
762 guess = true; 783 guess = true;
763 } 784 }
764 785
765 // If we did not find a variable, we are done. 786 // If we did not find a variable, we are done.
766 if (var == NULL) 787 if (var == NULL)
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
919 940
920 bool Scope::MustAllocate(Variable* var) { 941 bool Scope::MustAllocate(Variable* var) {
921 // Give var a read/write use if there is a chance it might be accessed 942 // Give var a read/write use if there is a chance it might be accessed
922 // via an eval() call. This is only possible if the variable has a 943 // via an eval() call. This is only possible if the variable has a
923 // visible name. 944 // visible name.
924 if ((var->is_this() || var->name()->length() > 0) && 945 if ((var->is_this() || var->name()->length() > 0) &&
925 (var->is_accessed_from_inner_scope() || 946 (var->is_accessed_from_inner_scope() ||
926 scope_calls_eval_ || 947 scope_calls_eval_ ||
927 inner_scope_calls_eval_ || 948 inner_scope_calls_eval_ ||
928 scope_contains_with_ || 949 scope_contains_with_ ||
929 is_catch_scope())) { 950 is_catch_scope() ||
951 is_block_scope())) {
930 var->set_is_used(true); 952 var->set_is_used(true);
931 } 953 }
932 // Global variables do not need to be allocated. 954 // Global variables do not need to be allocated.
933 return !var->is_global() && var->is_used(); 955 return !var->is_global() && var->is_used();
934 } 956 }
935 957
936 958
937 bool Scope::MustAllocateInContext(Variable* var) { 959 bool Scope::MustAllocateInContext(Variable* var) {
938 // If var is accessed from an inner scope, or if there is a possibility 960 // If var is accessed from an inner scope, or if there is a possibility
939 // that it might be accessed from the current or an inner scope (through 961 // that it might be accessed from the current or an inner scope (through
940 // an eval() call or a runtime with lookup), it must be allocated in the 962 // an eval() call or a runtime with lookup), it must be allocated in the
941 // context. 963 // context.
942 // 964 //
943 // Exceptions: temporary variables are never allocated in a context; 965 // Exceptions: temporary variables are never allocated in a context;
944 // catch-bound variables are always allocated in a context. 966 // catch-bound variables are always allocated in a context.
945 if (var->mode() == Variable::TEMPORARY) return false; 967 if (var->mode() == Variable::TEMPORARY) return false;
946 if (is_catch_scope()) return true; 968 if (is_catch_scope() || is_block_scope()) return true;
947 return var->is_accessed_from_inner_scope() || 969 return var->is_accessed_from_inner_scope() ||
948 scope_calls_eval_ || 970 scope_calls_eval_ ||
949 inner_scope_calls_eval_ || 971 inner_scope_calls_eval_ ||
950 scope_contains_with_ || 972 scope_contains_with_ ||
951 var->is_global(); 973 var->is_global();
952 } 974 }
953 975
954 976
955 bool Scope::HasArgumentsParameter() { 977 bool Scope::HasArgumentsParameter() {
956 for (int i = 0; i < params_.length(); i++) { 978 for (int i = 0; i < params_.length(); i++) {
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1103 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 1125 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
1104 !must_have_local_context) { 1126 !must_have_local_context) {
1105 num_heap_slots_ = 0; 1127 num_heap_slots_ = 0;
1106 } 1128 }
1107 1129
1108 // Allocation done. 1130 // Allocation done.
1109 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1131 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
1110 } 1132 }
1111 1133
1112 } } // namespace v8::internal 1134 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698