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

Side by Side Diff: src/scopes.cc

Issue 7172030: Revert "Merge arguments branch to bleeding merge." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 6 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
« no previous file with comments | « src/scopes.h ('k') | src/stub-cache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 unresolved_(16), 150 unresolved_(16),
151 decls_(4) { 151 decls_(4) {
152 ASSERT(!scope_info.is_null()); 152 ASSERT(!scope_info.is_null());
153 SetDefaults(FUNCTION_SCOPE, NULL, scope_info); 153 SetDefaults(FUNCTION_SCOPE, NULL, scope_info);
154 ASSERT(resolved()); 154 ASSERT(resolved());
155 if (scope_info->HasHeapAllocatedLocals()) { 155 if (scope_info->HasHeapAllocatedLocals()) {
156 num_heap_slots_ = scope_info_->NumberOfContextSlots(); 156 num_heap_slots_ = scope_info_->NumberOfContextSlots();
157 } 157 }
158 158
159 AddInnerScope(inner_scope); 159 AddInnerScope(inner_scope);
160
161 // This scope's arguments shadow (if present) is context-allocated if an inner
162 // scope accesses this one's parameters. Allocate the arguments_shadow_
163 // variable if necessary.
164 Isolate* isolate = Isolate::Current();
165 Variable::Mode mode;
166 int arguments_shadow_index =
167 scope_info_->ContextSlotIndex(
168 isolate->heap()->arguments_shadow_symbol(), &mode);
169 if (arguments_shadow_index >= 0) {
170 ASSERT(mode == Variable::INTERNAL);
171 arguments_shadow_ = new Variable(
172 this,
173 isolate->factory()->arguments_shadow_symbol(),
174 Variable::INTERNAL,
175 true,
176 Variable::ARGUMENTS);
177 arguments_shadow_->set_rewrite(
178 new Slot(arguments_shadow_, Slot::CONTEXT, arguments_shadow_index));
179 arguments_shadow_->set_is_used(true);
180 }
160 } 181 }
161 182
162 183
163 void Scope::SetDefaults(Type type, 184 void Scope::SetDefaults(Type type,
164 Scope* outer_scope, 185 Scope* outer_scope,
165 Handle<SerializedScopeInfo> scope_info) { 186 Handle<SerializedScopeInfo> scope_info) {
166 outer_scope_ = outer_scope; 187 outer_scope_ = outer_scope;
167 type_ = type; 188 type_ = type;
168 scope_name_ = FACTORY->empty_symbol(); 189 scope_name_ = FACTORY->empty_symbol();
169 dynamics_ = NULL; 190 dynamics_ = NULL;
170 receiver_ = NULL; 191 receiver_ = NULL;
171 function_ = NULL; 192 function_ = NULL;
172 arguments_ = NULL; 193 arguments_ = NULL;
194 arguments_shadow_ = NULL;
173 illegal_redecl_ = NULL; 195 illegal_redecl_ = NULL;
174 scope_inside_with_ = false; 196 scope_inside_with_ = false;
175 scope_contains_with_ = false; 197 scope_contains_with_ = false;
176 scope_calls_eval_ = false; 198 scope_calls_eval_ = false;
177 // Inherit the strict mode from the parent scope. 199 // Inherit the strict mode from the parent scope.
178 strict_mode_ = (outer_scope != NULL) && outer_scope->strict_mode_; 200 strict_mode_ = (outer_scope != NULL) && outer_scope->strict_mode_;
179 outer_scope_calls_eval_ = false; 201 outer_scope_calls_eval_ = false;
180 outer_scope_calls_non_strict_eval_ = false; 202 outer_scope_calls_non_strict_eval_ = false;
181 inner_scope_calls_eval_ = false; 203 inner_scope_calls_eval_ = false;
182 outer_scope_is_eval_scope_ = false; 204 outer_scope_is_eval_scope_ = false;
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
270 true, Variable::ARGUMENTS); 292 true, Variable::ARGUMENTS);
271 } 293 }
272 } 294 }
273 295
274 296
275 Variable* Scope::LocalLookup(Handle<String> name) { 297 Variable* Scope::LocalLookup(Handle<String> name) {
276 Variable* result = variables_.Lookup(name); 298 Variable* result = variables_.Lookup(name);
277 if (result != NULL || !resolved()) { 299 if (result != NULL || !resolved()) {
278 return result; 300 return result;
279 } 301 }
280 // If the scope is resolved, we can find a variable in serialized scope 302 // If the scope is resolved, we can find a variable in serialized scope info.
281 // info. 303
282 // 304 // We should never lookup 'arguments' in this scope
283 // We should never lookup 'arguments' in this scope as it is implicitly 305 // as it is implicitly present in any scope.
284 // present in every scope.
285 ASSERT(*name != *FACTORY->arguments_symbol()); 306 ASSERT(*name != *FACTORY->arguments_symbol());
286 // There should be no local slot with the given name. 307
308 // Assert that there is no local slot with the given name.
287 ASSERT(scope_info_->StackSlotIndex(*name) < 0); 309 ASSERT(scope_info_->StackSlotIndex(*name) < 0);
288 310
289 // Check context slot lookup. 311 // Check context slot lookup.
290 Variable::Mode mode; 312 Variable::Mode mode;
291 int index = scope_info_->ContextSlotIndex(*name, &mode); 313 int index = scope_info_->ContextSlotIndex(*name, &mode);
292 if (index < 0) { 314 if (index >= 0) {
293 // Check parameters. 315 Variable* var =
294 mode = Variable::VAR; 316 variables_.Declare(this, name, mode, true, Variable::NORMAL);
295 index = scope_info_->ParameterIndex(*name); 317 var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
296 if (index < 0) { 318 return var;
297 // Check the function name.
298 index = scope_info_->FunctionContextSlotIndex(*name);
299 if (index < 0) return NULL;
300 }
301 } 319 }
302 320
303 Variable* var = 321 index = scope_info_->ParameterIndex(*name);
304 variables_.Declare(this, name, mode, true, Variable::NORMAL); 322 if (index >= 0) {
305 var->set_rewrite(new Slot(var, Slot::CONTEXT, index)); 323 // ".arguments" must be present in context slots.
306 return var; 324 ASSERT(arguments_shadow_ != NULL);
325 Variable* var =
326 variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL);
327 Property* rewrite =
328 new Property(new VariableProxy(arguments_shadow_),
329 new Literal(Handle<Object>(Smi::FromInt(index))),
330 RelocInfo::kNoPosition,
331 Property::SYNTHETIC);
332 rewrite->set_is_arguments_access(true);
333 var->set_rewrite(rewrite);
334 return var;
335 }
336
337 index = scope_info_->FunctionContextSlotIndex(*name);
338 if (index >= 0) {
339 // Check that there is no local slot with the given name.
340 ASSERT(scope_info_->StackSlotIndex(*name) < 0);
341 Variable* var =
342 variables_.Declare(this, name, Variable::VAR, true, Variable::NORMAL);
343 var->set_rewrite(new Slot(var, Slot::CONTEXT, index));
344 return var;
345 }
346
347 return NULL;
307 } 348 }
308 349
309 350
310 Variable* Scope::Lookup(Handle<String> name) { 351 Variable* Scope::Lookup(Handle<String> name) {
311 for (Scope* scope = this; 352 for (Scope* scope = this;
312 scope != NULL; 353 scope != NULL;
313 scope = scope->outer_scope()) { 354 scope = scope->outer_scope()) {
314 Variable* var = scope->LocalLookup(name); 355 Variable* var = scope->LocalLookup(name);
315 if (var != NULL) return var; 356 if (var != NULL) return var;
316 } 357 }
(...skipping 587 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 void Scope::AllocateHeapSlot(Variable* var) { 945 void Scope::AllocateHeapSlot(Variable* var) {
905 var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++)); 946 var->set_rewrite(new Slot(var, Slot::CONTEXT, num_heap_slots_++));
906 } 947 }
907 948
908 949
909 void Scope::AllocateParameterLocals() { 950 void Scope::AllocateParameterLocals() {
910 ASSERT(is_function_scope()); 951 ASSERT(is_function_scope());
911 Variable* arguments = LocalLookup(FACTORY->arguments_symbol()); 952 Variable* arguments = LocalLookup(FACTORY->arguments_symbol());
912 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly 953 ASSERT(arguments != NULL); // functions have 'arguments' declared implicitly
913 954
914 bool uses_nonstrict_arguments = false; 955 // Parameters are rewritten to arguments[i] if 'arguments' is used in
956 // a non-strict mode function. Strict mode code doesn't alias arguments.
957 bool rewrite_parameters = false;
915 958
916 if (MustAllocate(arguments) && !HasArgumentsParameter()) { 959 if (MustAllocate(arguments) && !HasArgumentsParameter()) {
917 // 'arguments' is used. Unless there is also a parameter called 960 // 'arguments' is used. Unless there is also a parameter called
918 // 'arguments', we must be conservative and allocate all parameters to 961 // 'arguments', we must be conservative and access all parameters via
919 // the context assuming they will be captured by the arguments object. 962 // the arguments object: The i'th parameter is rewritten into
920 // If we have a parameter named 'arguments', a (new) value is always 963 // '.arguments[i]' (*). If we have a parameter named 'arguments', a
921 // assigned to it via the function invocation. Then 'arguments' denotes 964 // (new) value is always assigned to it via the function
922 // that specific parameter value and cannot be used to access the 965 // invocation. Then 'arguments' denotes that specific parameter value
923 // parameters, which is why we don't need to allocate an arguments 966 // and cannot be used to access the parameters, which is why we don't
924 // object in that case. 967 // need to rewrite in that case.
968 //
969 // (*) Instead of having a parameter called 'arguments', we may have an
970 // assignment to 'arguments' in the function body, at some arbitrary
971 // point in time (possibly through an 'eval()' call!). After that
972 // assignment any re-write of parameters would be invalid (was bug
973 // 881452). Thus, we introduce a shadow '.arguments'
974 // variable which also points to the arguments object. For rewrites we
975 // use '.arguments' which remains valid even if we assign to
976 // 'arguments'. To summarize: If we need to rewrite, we allocate an
977 // 'arguments' object dynamically upon function invocation. The compiler
978 // introduces 2 local variables 'arguments' and '.arguments', both of
979 // which originally point to the arguments object that was
980 // allocated. All parameters are rewritten into property accesses via
981 // the '.arguments' variable. Thus, any changes to properties of
982 // 'arguments' are reflected in the variables and vice versa. If the
983 // 'arguments' variable is changed, '.arguments' still points to the
984 // correct arguments object and the rewrites still work.
925 985
926 // We are using 'arguments'. Tell the code generator that is needs to 986 // We are using 'arguments'. Tell the code generator that is needs to
927 // allocate the arguments object by setting 'arguments_'. 987 // allocate the arguments object by setting 'arguments_'.
928 arguments_ = arguments; 988 arguments_ = arguments;
929 989
930 // In strict mode 'arguments' does not alias formal parameters. 990 // In strict mode 'arguments' does not alias formal parameters.
931 // Therefore in strict mode we allocate parameters as if 'arguments' 991 // Therefore in strict mode we allocate parameters as if 'arguments'
932 // were not used. 992 // were not used.
933 uses_nonstrict_arguments = !is_strict_mode(); 993 rewrite_parameters = !is_strict_mode();
934 } 994 }
935 995
936 // The same parameter may occur multiple times in the parameters_ list. 996 if (rewrite_parameters) {
937 // If it does, and if it is not copied into the context object, it must 997 // We also need the '.arguments' shadow variable. Declare it and create
938 // receive the highest parameter index for that parameter; thus iteration 998 // and bind the corresponding proxy. It's ok to declare it only now
939 // order is relevant! 999 // because it's a local variable that is allocated after the parameters
940 for (int i = params_.length() - 1; i >= 0; --i) { 1000 // have been allocated.
941 Variable* var = params_[i]; 1001 //
942 ASSERT(var->scope() == this); 1002 // Note: This is "almost" at temporary variable but we cannot use
943 if (uses_nonstrict_arguments) { 1003 // NewTemporary() because the mode needs to be INTERNAL since this
944 // Give the parameter a use from an inner scope, to force allocation 1004 // variable may be allocated in the heap-allocated context (temporaries
945 // to the context. 1005 // are never allocated in the context).
946 var->MarkAsAccessedFromInnerScope(); 1006 arguments_shadow_ = new Variable(this,
1007 FACTORY->arguments_shadow_symbol(),
1008 Variable::INTERNAL,
1009 true,
1010 Variable::ARGUMENTS);
1011 arguments_shadow_->set_is_used(true);
1012 temps_.Add(arguments_shadow_);
1013
1014 // Allocate the parameters by rewriting them into '.arguments[i]' accesses.
1015 for (int i = 0; i < params_.length(); i++) {
1016 Variable* var = params_[i];
1017 ASSERT(var->scope() == this);
1018 if (MustAllocate(var)) {
1019 if (MustAllocateInContext(var)) {
1020 // It is ok to set this only now, because arguments is a local
1021 // variable that is allocated after the parameters have been
1022 // allocated.
1023 arguments_shadow_->MarkAsAccessedFromInnerScope();
1024 }
1025 Property* rewrite =
1026 new Property(new VariableProxy(arguments_shadow_),
1027 new Literal(Handle<Object>(Smi::FromInt(i))),
1028 RelocInfo::kNoPosition,
1029 Property::SYNTHETIC);
1030 rewrite->set_is_arguments_access(true);
1031 var->set_rewrite(rewrite);
1032 }
947 } 1033 }
948 1034
949 if (MustAllocate(var)) { 1035 } else {
950 if (MustAllocateInContext(var)) { 1036 // The arguments object is not used, so we can access parameters directly.
951 ASSERT(var->rewrite() == NULL || var->IsContextSlot()); 1037 // The same parameter may occur multiple times in the parameters_ list.
952 if (var->rewrite() == NULL) { 1038 // If it does, and if it is not copied into the context object, it must
953 AllocateHeapSlot(var); 1039 // receive the highest parameter index for that parameter; thus iteration
954 } 1040 // order is relevant!
955 } else { 1041 for (int i = 0; i < params_.length(); i++) {
956 ASSERT(var->rewrite() == NULL || var->IsParameter()); 1042 Variable* var = params_[i];
957 if (var->rewrite() == NULL) { 1043 ASSERT(var->scope() == this);
1044 if (MustAllocate(var)) {
1045 if (MustAllocateInContext(var)) {
1046 ASSERT(var->rewrite() == NULL ||
1047 (var->AsSlot() != NULL &&
1048 var->AsSlot()->type() == Slot::CONTEXT));
1049 if (var->rewrite() == NULL) {
1050 // Only set the heap allocation if the parameter has not
1051 // been allocated yet.
1052 AllocateHeapSlot(var);
1053 }
1054 } else {
1055 ASSERT(var->rewrite() == NULL ||
1056 (var->AsSlot() != NULL &&
1057 var->AsSlot()->type() == Slot::PARAMETER));
1058 // Set the parameter index always, even if the parameter
1059 // was seen before! (We need to access the actual parameter
1060 // supplied for the last occurrence of a multiply declared
1061 // parameter.)
958 var->set_rewrite(new Slot(var, Slot::PARAMETER, i)); 1062 var->set_rewrite(new Slot(var, Slot::PARAMETER, i));
959 } 1063 }
960 } 1064 }
961 } 1065 }
962 } 1066 }
963 } 1067 }
964 1068
965 1069
966 void Scope::AllocateNonParameterLocal(Variable* var) { 1070 void Scope::AllocateNonParameterLocal(Variable* var) {
967 ASSERT(var->scope() == this); 1071 ASSERT(var->scope() == this);
968 ASSERT(var->rewrite() == NULL || 1072 ASSERT(var->rewrite() == NULL ||
969 !var->IsVariable(FACTORY->result_symbol()) || 1073 (!var->IsVariable(FACTORY->result_symbol())) ||
970 var->AsSlot() == NULL || 1074 (var->AsSlot() == NULL || var->AsSlot()->type() != Slot::LOCAL));
971 var->AsSlot()->type() != Slot::LOCAL);
972 if (var->rewrite() == NULL && MustAllocate(var)) { 1075 if (var->rewrite() == NULL && MustAllocate(var)) {
973 if (MustAllocateInContext(var)) { 1076 if (MustAllocateInContext(var)) {
974 AllocateHeapSlot(var); 1077 AllocateHeapSlot(var);
975 } else { 1078 } else {
976 AllocateStackSlot(var); 1079 AllocateStackSlot(var);
977 } 1080 }
978 } 1081 }
979 } 1082 }
980 1083
981 1084
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS && 1139 if (num_heap_slots_ == Context::MIN_CONTEXT_SLOTS &&
1037 !must_have_local_context) { 1140 !must_have_local_context) {
1038 num_heap_slots_ = 0; 1141 num_heap_slots_ = 0;
1039 } 1142 }
1040 1143
1041 // Allocation done. 1144 // Allocation done.
1042 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS); 1145 ASSERT(num_heap_slots_ == 0 || num_heap_slots_ >= Context::MIN_CONTEXT_SLOTS);
1043 } 1146 }
1044 1147
1045 } } // namespace v8::internal 1148 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopes.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698