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

Side by Side Diff: src/ast/scopes.cc

Issue 2237873002: Declare 'this' as DYNAMIC_GLOBAL on the script_scope (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase and partly restore for debugger Created 4 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
« no previous file with comments | « src/ast/scopes.h ('k') | src/parsing/parser.cc » ('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 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/ast/scopes.h" 5 #include "src/ast/scopes.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "src/accessors.h" 9 #include "src/accessors.h"
10 #include "src/bootstrapper.h" 10 #include "src/bootstrapper.h"
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 language_mode_ = is_module_scope() ? STRICT : SLOPPY; 202 language_mode_ = is_module_scope() ? STRICT : SLOPPY;
203 203
204 scope_inside_with_ = false; 204 scope_inside_with_ = false;
205 scope_calls_eval_ = false; 205 scope_calls_eval_ = false;
206 scope_uses_super_property_ = false; 206 scope_uses_super_property_ = false;
207 has_arguments_parameter_ = false; 207 has_arguments_parameter_ = false;
208 asm_module_ = false; 208 asm_module_ = false;
209 asm_function_ = false; 209 asm_function_ = false;
210 scope_nonlinear_ = false; 210 scope_nonlinear_ = false;
211 is_hidden_ = false; 211 is_hidden_ = false;
212 is_debug_evaluate_scope_ = false;
212 213
213 outer_scope_calls_sloppy_eval_ = false; 214 outer_scope_calls_sloppy_eval_ = false;
214 inner_scope_calls_eval_ = false; 215 inner_scope_calls_eval_ = false;
215 force_eager_compilation_ = false; 216 force_eager_compilation_ = false;
216 force_context_allocation_ = false; 217 force_context_allocation_ = false;
217 218
218 is_declaration_scope_ = false; 219 is_declaration_scope_ = false;
219 } 220 }
220 221
221 bool Scope::HasSimpleParameters() { 222 bool Scope::HasSimpleParameters() {
222 DeclarationScope* scope = GetClosureScope(); 223 DeclarationScope* scope = GetClosureScope();
223 return !scope->is_function_scope() || scope->has_simple_parameters(); 224 return !scope->is_function_scope() || scope->has_simple_parameters();
224 } 225 }
225 226
226 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, 227 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone,
227 Context* context, 228 Context* context,
228 DeclarationScope* script_scope, 229 DeclarationScope* script_scope,
229 AstValueFactory* ast_value_factory, 230 AstValueFactory* ast_value_factory,
230 DeserializationMode deserialization_mode) { 231 DeserializationMode deserialization_mode) {
231 // Reconstruct the outer scope chain from a closure's context chain. 232 // Reconstruct the outer scope chain from a closure's context chain.
232 Scope* current_scope = nullptr; 233 Scope* current_scope = nullptr;
233 Scope* innermost_scope = nullptr; 234 Scope* innermost_scope = nullptr;
234 while (!context->IsNativeContext()) { 235 while (!context->IsNativeContext()) {
235 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { 236 if (context->IsWithContext() || context->IsDebugEvaluateContext()) {
236 // For scope analysis, debug-evaluate is equivalent to a with scope. 237 // For scope analysis, debug-evaluate is equivalent to a with scope.
237 Scope* with_scope = new (zone) 238 Scope* with_scope = new (zone)
238 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null()); 239 Scope(zone, current_scope, WITH_SCOPE, Handle<ScopeInfo>::null());
240 // TODO(yangguo): Remove once debug-evaluate properly keeps track of the
241 // function scope in which we are evaluating.
242 if (context->IsDebugEvaluateContext()) {
243 with_scope->set_is_debug_evaluate_scope();
244 }
239 current_scope = with_scope; 245 current_scope = with_scope;
240 // All the inner scopes are inside a with. 246 // All the inner scopes are inside a with.
241 for (Scope* s = innermost_scope; s != nullptr; s = s->outer_scope()) { 247 for (Scope* s = innermost_scope; s != nullptr; s = s->outer_scope()) {
242 s->scope_inside_with_ = true; 248 s->scope_inside_with_ = true;
243 } 249 }
244 } else if (context->IsScriptContext()) { 250 } else if (context->IsScriptContext()) {
245 ScopeInfo* scope_info = context->scope_info(); 251 ScopeInfo* scope_info = context->scope_info();
246 current_scope = new (zone) DeclarationScope( 252 current_scope = new (zone) DeclarationScope(
247 zone, current_scope, SCRIPT_SCOPE, Handle<ScopeInfo>(scope_info)); 253 zone, current_scope, SCRIPT_SCOPE, Handle<ScopeInfo>(scope_info));
248 } else if (context->IsFunctionContext()) { 254 } else if (context->IsFunctionContext()) {
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
547 Variable* result = variables_.Lookup(name); 553 Variable* result = variables_.Lookup(name);
548 if (result != NULL || scope_info_.is_null()) { 554 if (result != NULL || scope_info_.is_null()) {
549 return result; 555 return result;
550 } 556 }
551 Handle<String> name_handle = name->string(); 557 Handle<String> name_handle = name->string();
552 // The Scope is backed up by ScopeInfo. This means it cannot operate in a 558 // The Scope is backed up by ScopeInfo. This means it cannot operate in a
553 // heap-independent mode, and all strings must be internalized immediately. So 559 // heap-independent mode, and all strings must be internalized immediately. So
554 // it's ok to get the Handle<String> here. 560 // it's ok to get the Handle<String> here.
555 // If we have a serialized scope info, we might find the variable there. 561 // If we have a serialized scope info, we might find the variable there.
556 // There should be no local slot with the given name. 562 // There should be no local slot with the given name.
557 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0 || is_block_scope()); 563 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0);
Toon Verwaest 2016/08/12 08:50:20 I don't see how this would be valid for block scop
558 564
559 // Check context slot lookup. 565 // Check context slot lookup.
560 VariableMode mode; 566 VariableMode mode;
561 VariableLocation location = VariableLocation::CONTEXT; 567 VariableLocation location = VariableLocation::CONTEXT;
562 InitializationFlag init_flag; 568 InitializationFlag init_flag;
563 MaybeAssignedFlag maybe_assigned_flag; 569 MaybeAssignedFlag maybe_assigned_flag;
564 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode, 570 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
565 &init_flag, &maybe_assigned_flag); 571 &init_flag, &maybe_assigned_flag);
566 if (index < 0) { 572 if (index < 0) {
567 location = VariableLocation::GLOBAL; 573 location = VariableLocation::GLOBAL;
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
1236 } 1242 }
1237 } 1243 }
1238 1244
1239 void Scope::CheckZones() { 1245 void Scope::CheckZones() {
1240 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { 1246 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) {
1241 CHECK_EQ(scope->zone(), zone()); 1247 CHECK_EQ(scope->zone(), zone());
1242 } 1248 }
1243 } 1249 }
1244 #endif // DEBUG 1250 #endif // DEBUG
1245 1251
1246 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode, 1252 Variable* Scope::NonLocal(const AstRawString* name, VariableMode mode) {
1247 Variable::Kind kind) {
1248 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone()); 1253 if (dynamics_ == NULL) dynamics_ = new (zone()) DynamicScopePart(zone());
1249 VariableMap* map = dynamics_->GetMap(mode); 1254 VariableMap* map = dynamics_->GetMap(mode);
1250 Variable* var = map->Lookup(name); 1255 Variable* var = map->Lookup(name);
1251 if (var == NULL) { 1256 if (var == NULL) {
1252 // Declare a new non-local. 1257 // Declare a new non-local.
1253 DCHECK(!IsLexicalVariableMode(mode)); 1258 DCHECK(!IsLexicalVariableMode(mode));
1254 var = map->Declare(zone(), NULL, name, mode, kind, kCreatedInitialized); 1259 var = map->Declare(zone(), NULL, name, mode, Variable::NORMAL,
1260 kCreatedInitialized);
1255 // Allocate it by giving it a dynamic lookup. 1261 // Allocate it by giving it a dynamic lookup.
1256 var->AllocateTo(VariableLocation::LOOKUP, -1); 1262 var->AllocateTo(VariableLocation::LOOKUP, -1);
1257 } 1263 }
1258 return var; 1264 return var;
1259 } 1265 }
1260 1266
1261 Variable* Scope::LookupRecursive(VariableProxy* proxy, 1267 Variable* Scope::LookupRecursive(VariableProxy* proxy,
1262 BindingKind* binding_kind, 1268 BindingKind* binding_kind,
1263 AstNodeFactory* factory, 1269 AstNodeFactory* factory,
1264 Scope* outer_scope_end) { 1270 Scope* outer_scope_end) {
1265 DCHECK_NE(outer_scope_end, this); 1271 DCHECK_NE(outer_scope_end, this);
1266 DCHECK_NOT_NULL(binding_kind); 1272 DCHECK_NOT_NULL(binding_kind);
1267 DCHECK_EQ(UNBOUND, *binding_kind); 1273 DCHECK_EQ(UNBOUND, *binding_kind);
1268 if (already_resolved() && is_with_scope()) { 1274 // Short-cut: whenever we find a debug-evaluate scope, just look everything up
1269 // Short-cut: if the scope is deserialized from a scope info, variable 1275 // dynamically. Debug-evaluate doesn't properly create scope info for the
1270 // allocation is already fixed. We can simply return with dynamic lookup. 1276 // lookups it does. It may not have a valid 'this' declaration, and anything
1277 // accessed through debug-evaluate might invalidly resolve to stack-allocated
1278 // variables.
1279 // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the
1280 // scopes in which it's evaluating.
1281 if (is_debug_evaluate_scope_) {
1271 *binding_kind = DYNAMIC_LOOKUP; 1282 *binding_kind = DYNAMIC_LOOKUP;
1272 return nullptr; 1283 return nullptr;
1273 } 1284 }
1274 1285
1275 // Try to find the variable in this scope. 1286 // Try to find the variable in this scope.
1276 Variable* var = LookupLocal(proxy->raw_name()); 1287 Variable* var = LookupLocal(proxy->raw_name());
1277 1288
1278 // We found a variable and we are done. (Even if there is an 'eval' in this 1289 // We found a variable and we are done. (Even if there is an 'eval' in this
1279 // scope which introduces the same variable again, the resulting variable 1290 // scope which introduces the same variable again, the resulting variable
1280 // remains the same.) 1291 // remains the same.)
(...skipping 17 matching lines...) Expand all
1298 outer_scope_end); 1309 outer_scope_end);
1299 if (*binding_kind == BOUND && is_function_scope()) { 1310 if (*binding_kind == BOUND && is_function_scope()) {
1300 var->ForceContextAllocation(); 1311 var->ForceContextAllocation();
1301 } 1312 }
1302 // "this" can't be shadowed by "eval"-introduced bindings or by "with" 1313 // "this" can't be shadowed by "eval"-introduced bindings or by "with"
1303 // scopes. 1314 // scopes.
1304 // TODO(wingo): There are other variables in this category; add them. 1315 // TODO(wingo): There are other variables in this category; add them.
1305 if (var != nullptr && var->is_this()) return var; 1316 if (var != nullptr && var->is_this()) return var;
1306 1317
1307 if (is_with_scope()) { 1318 if (is_with_scope()) {
1308 DCHECK(!already_resolved());
1309 // The current scope is a with scope, so the variable binding can not be 1319 // The current scope is a with scope, so the variable binding can not be
1310 // statically resolved. However, note that it was necessary to do a lookup 1320 // statically resolved. However, note that it was necessary to do a lookup
1311 // in the outer scope anyway, because if a binding exists in an outer 1321 // in the outer scope anyway, because if a binding exists in an outer
1312 // scope, the associated variable has to be marked as potentially being 1322 // scope, the associated variable has to be marked as potentially being
1313 // accessed from inside of an inner with scope (the property may not be in 1323 // accessed from inside of an inner with scope (the property may not be in
1314 // the 'with' object). 1324 // the 'with' object).
1315 if (var != nullptr) { 1325 if (var != nullptr && !already_resolved()) {
1316 var->set_is_used(); 1326 var->set_is_used();
1317 var->ForceContextAllocation(); 1327 var->ForceContextAllocation();
1318 if (proxy->is_assigned()) var->set_maybe_assigned(); 1328 if (proxy->is_assigned()) var->set_maybe_assigned();
1319 } 1329 }
1320 *binding_kind = DYNAMIC_LOOKUP; 1330 *binding_kind = DYNAMIC_LOOKUP;
1321 return nullptr; 1331 return nullptr;
1322 } 1332 }
1323 } else { 1333 } else {
1324 DCHECK(is_function_scope() || is_script_scope() || is_eval_scope()); 1334 DCHECK(is_function_scope() || is_script_scope() || is_eval_scope());
1325 DCHECK(!is_with_scope()); 1335 DCHECK(!is_with_scope());
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1374 name->ToCString().get()); 1384 name->ToCString().get());
1375 } 1385 }
1376 VariableLocation location = var->location(); 1386 VariableLocation location = var->location();
1377 CHECK(location == VariableLocation::LOCAL || 1387 CHECK(location == VariableLocation::LOCAL ||
1378 location == VariableLocation::CONTEXT || 1388 location == VariableLocation::CONTEXT ||
1379 location == VariableLocation::PARAMETER || 1389 location == VariableLocation::PARAMETER ||
1380 location == VariableLocation::UNALLOCATED); 1390 location == VariableLocation::UNALLOCATED);
1381 } 1391 }
1382 #endif 1392 #endif
1383 1393
1384 // TODO(verwaest): 'this' should always be declared and found. That way we can
1385 // remove this workaround.
1386 Variable::Kind kind = proxy->is_this() ? Variable::THIS : Variable::NORMAL;
1387 switch (binding_kind) { 1394 switch (binding_kind) {
1388 case BOUND: 1395 case BOUND:
1389 break; 1396 break;
1390 1397
1391 case BOUND_EVAL_SHADOWED: 1398 case BOUND_EVAL_SHADOWED:
1392 // We either found a variable binding that might be shadowed by eval or 1399 // We either found a variable binding that might be shadowed by eval or
1393 // gave up on it (e.g. by encountering a local with the same in the outer 1400 // gave up on it (e.g. by encountering a local with the same in the outer
1394 // scope which was not promoted to a context, this can happen if we use 1401 // scope which was not promoted to a context, this can happen if we use
1395 // debugger to evaluate arbitrary expressions at a break point). 1402 // debugger to evaluate arbitrary expressions at a break point).
1396 if (var->IsGlobalObjectProperty()) { 1403 if (var->IsGlobalObjectProperty()) {
1397 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL, kind); 1404 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL);
1398 } else if (var->is_dynamic()) { 1405 } else if (var->is_dynamic()) {
1399 var = NonLocal(proxy->raw_name(), DYNAMIC, kind); 1406 var = NonLocal(proxy->raw_name(), DYNAMIC);
1400 } else { 1407 } else {
1401 Variable* invalidated = var; 1408 Variable* invalidated = var;
1402 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL, kind); 1409 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL);
1403 var->set_local_if_not_shadowed(invalidated); 1410 var->set_local_if_not_shadowed(invalidated);
1404 } 1411 }
1405 break; 1412 break;
1406 1413
1407 case UNBOUND: 1414 case UNBOUND:
1408 // No binding has been found. Declare a variable on the global object. 1415 // No binding has been found. Declare a variable on the global object.
1409 var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name(), kind); 1416 var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name(),
1417 Variable::NORMAL);
1410 break; 1418 break;
1411 1419
1412 case UNBOUND_EVAL_SHADOWED: 1420 case UNBOUND_EVAL_SHADOWED:
1413 // No binding has been found. But some scope makes a sloppy 'eval' call. 1421 // No binding has been found. But some scope makes a sloppy 'eval' call.
1414 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL, kind); 1422 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL);
1415 break; 1423 break;
1416 1424
1417 case DYNAMIC_LOOKUP: 1425 case DYNAMIC_LOOKUP:
1418 // The variable could not be resolved statically. 1426 // The variable could not be resolved statically.
1419 var = NonLocal(proxy->raw_name(), DYNAMIC, kind); 1427 var = NonLocal(proxy->raw_name(), DYNAMIC);
1420 break; 1428 break;
1421 } 1429 }
1422 1430
1423 DCHECK(var != NULL); 1431 DCHECK(var != NULL);
1424 if (proxy->is_assigned()) var->set_maybe_assigned(); 1432 if (proxy->is_assigned()) var->set_maybe_assigned();
1425 1433
1426 proxy->BindTo(var); 1434 proxy->BindTo(var);
1427 } 1435 }
1428 1436
1429 void Scope::ResolveVariablesRecursively(ParseInfo* info, 1437 void Scope::ResolveVariablesRecursively(ParseInfo* info,
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 function != nullptr && function->IsContextSlot(); 1798 function != nullptr && function->IsContextSlot();
1791 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - 1799 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
1792 (is_function_var_in_context ? 1 : 0); 1800 (is_function_var_in_context ? 1 : 0);
1793 } 1801 }
1794 1802
1795 1803
1796 int Scope::ContextGlobalCount() const { return num_global_slots(); } 1804 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1797 1805
1798 } // namespace internal 1806 } // namespace internal
1799 } // namespace v8 1807 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/parsing/parser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698