 Chromium Code Reviews
 Chromium Code Reviews Issue 2262393004:
  Let LookupRecursive bind to NonLocals properly.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master
    
  
    Issue 2262393004:
  Let LookupRecursive bind to NonLocals properly.  (Closed) 
  Base URL: https://chromium.googlesource.com/v8/v8.git@master| 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/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 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 DeclarationScope* scope = info->literal()->scope(); | 415 DeclarationScope* scope = info->literal()->scope(); | 
| 416 | 416 | 
| 417 // We are compiling one of three cases: | 417 // We are compiling one of three cases: | 
| 418 // 1) top-level code, | 418 // 1) top-level code, | 
| 419 // 2) a function/eval/module on the top-level | 419 // 2) a function/eval/module on the top-level | 
| 420 // 3) a function/eval in a scope that was already resolved. | 420 // 3) a function/eval in a scope that was already resolved. | 
| 421 DCHECK(scope->scope_type() == SCRIPT_SCOPE || | 421 DCHECK(scope->scope_type() == SCRIPT_SCOPE || | 
| 422 scope->outer_scope()->scope_type() == SCRIPT_SCOPE || | 422 scope->outer_scope()->scope_type() == SCRIPT_SCOPE || | 
| 423 scope->outer_scope()->already_resolved_); | 423 scope->outer_scope()->already_resolved_); | 
| 424 | 424 | 
| 425 // Allocate the variables. | 425 // Allocate the variables. | 
| 
adamk
2016/08/23 18:15:10
Let's kill this comment while we're here.
 
Toon Verwaest
2016/08/23 20:09:11
Done.
 | |
| 426 { | 426 scope->AllocateVariables(info); | 
| 427 AstNodeFactory ast_node_factory(info->ast_value_factory()); | |
| 428 scope->AllocateVariables(info, &ast_node_factory); | |
| 429 } | |
| 430 | 427 | 
| 431 #ifdef DEBUG | 428 #ifdef DEBUG | 
| 432 if (info->script_is_native() ? FLAG_print_builtin_scopes | 429 if (info->script_is_native() ? FLAG_print_builtin_scopes | 
| 433 : FLAG_print_scopes) { | 430 : FLAG_print_scopes) { | 
| 434 scope->Print(); | 431 scope->Print(); | 
| 435 } | 432 } | 
| 436 scope->CheckScopePositions(); | 433 scope->CheckScopePositions(); | 
| 437 scope->CheckZones(); | 434 scope->CheckZones(); | 
| 438 #endif | 435 #endif | 
| 439 } | 436 } | 
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 837 if (var->IsStackLocal()) { | 834 if (var->IsStackLocal()) { | 
| 838 stack_locals->Add(var, zone()); | 835 stack_locals->Add(var, zone()); | 
| 839 } else if (var->IsContextSlot()) { | 836 } else if (var->IsContextSlot()) { | 
| 840 context_locals->Add(var, zone()); | 837 context_locals->Add(var, zone()); | 
| 841 } else if (var->IsGlobalSlot()) { | 838 } else if (var->IsGlobalSlot()) { | 
| 842 context_globals->Add(var, zone()); | 839 context_globals->Add(var, zone()); | 
| 843 } | 840 } | 
| 844 } | 841 } | 
| 845 } | 842 } | 
| 846 | 843 | 
| 847 void DeclarationScope::AllocateVariables(ParseInfo* info, | 844 void DeclarationScope::AllocateVariables(ParseInfo* info) { | 
| 848 AstNodeFactory* factory) { | |
| 849 // 1) Propagate scope information. | 845 // 1) Propagate scope information. | 
| 850 PropagateScopeInfo(); | 846 PropagateScopeInfo(); | 
| 851 | 847 | 
| 852 // 2) Resolve variables. | 848 // 2) Resolve variables. | 
| 853 ResolveVariablesRecursively(info, factory); | 849 ResolveVariablesRecursively(info); | 
| 854 | 850 | 
| 855 // 3) Allocate variables. | 851 // 3) Allocate variables. | 
| 856 AllocateVariablesRecursively(); | 852 AllocateVariablesRecursively(); | 
| 857 } | 853 } | 
| 858 | 854 | 
| 859 | 855 | 
| 860 bool Scope::AllowsLazyParsing() const { | 856 bool Scope::AllowsLazyParsing() const { | 
| 861 // If we are inside a block scope, we must parse eagerly to find out how | 857 // If we are inside a block scope, we must parse eagerly to find out how | 
| 862 // to allocate variables on the block scope. At this point, declarations may | 858 // to allocate variables on the block scope. At this point, declarations may | 
| 863 // not have yet been parsed. | 859 // not have yet been parsed. | 
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1222 // Declare a new non-local. | 1218 // Declare a new non-local. | 
| 1223 DCHECK(!IsLexicalVariableMode(mode)); | 1219 DCHECK(!IsLexicalVariableMode(mode)); | 
| 1224 var = map->Declare(zone(), NULL, name, mode, Variable::NORMAL, | 1220 var = map->Declare(zone(), NULL, name, mode, Variable::NORMAL, | 
| 1225 kCreatedInitialized); | 1221 kCreatedInitialized); | 
| 1226 // Allocate it by giving it a dynamic lookup. | 1222 // Allocate it by giving it a dynamic lookup. | 
| 1227 var->AllocateTo(VariableLocation::LOOKUP, -1); | 1223 var->AllocateTo(VariableLocation::LOOKUP, -1); | 
| 1228 } | 1224 } | 
| 1229 return var; | 1225 return var; | 
| 1230 } | 1226 } | 
| 1231 | 1227 | 
| 1232 Variable* Scope::LookupRecursive(VariableProxy* proxy, | 1228 Variable* Scope::LookupRecursive(VariableProxy* proxy, bool resolve_free, | 
| 1233 BindingKind* binding_kind, | |
| 1234 AstNodeFactory* factory, | |
| 1235 Scope* outer_scope_end) { | 1229 Scope* outer_scope_end) { | 
| 1236 DCHECK_NE(outer_scope_end, this); | 1230 DCHECK_NE(outer_scope_end, this); | 
| 1237 DCHECK_NOT_NULL(binding_kind); | |
| 1238 DCHECK_EQ(UNBOUND, *binding_kind); | |
| 1239 // Short-cut: whenever we find a debug-evaluate scope, just look everything up | 1231 // Short-cut: whenever we find a debug-evaluate scope, just look everything up | 
| 1240 // dynamically. Debug-evaluate doesn't properly create scope info for the | 1232 // dynamically. Debug-evaluate doesn't properly create scope info for the | 
| 1241 // lookups it does. It may not have a valid 'this' declaration, and anything | 1233 // lookups it does. It may not have a valid 'this' declaration, and anything | 
| 1242 // accessed through debug-evaluate might invalidly resolve to stack-allocated | 1234 // accessed through debug-evaluate might invalidly resolve to stack-allocated | 
| 1243 // variables. | 1235 // variables. | 
| 1244 // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the | 1236 // TODO(yangguo): Remove once debug-evaluate creates proper ScopeInfo for the | 
| 1245 // scopes in which it's evaluating. | 1237 // scopes in which it's evaluating. | 
| 1246 if (is_debug_evaluate_scope_) { | 1238 if (is_debug_evaluate_scope_) { | 
| 1247 *binding_kind = DYNAMIC_LOOKUP; | 1239 if (!resolve_free) return nullptr; | 
| 1248 return nullptr; | 1240 return NonLocal(proxy->raw_name(), DYNAMIC); | 
| 1249 } | 1241 } | 
| 1250 | 1242 | 
| 1251 // Try to find the variable in this scope. | 1243 // Try to find the variable in this scope. | 
| 1252 Variable* var = LookupLocal(proxy->raw_name()); | 1244 Variable* var = LookupLocal(proxy->raw_name()); | 
| 1253 | 1245 | 
| 1254 // We found a variable and we are done. (Even if there is an 'eval' in this | 1246 // We found a variable and we are done. (Even if there is an 'eval' in this | 
| 1255 // scope which introduces the same variable again, the resulting variable | 1247 // scope which introduces the same variable again, the resulting variable | 
| 1256 // remains the same.) | 1248 // remains the same.) | 
| 1257 if (var != nullptr) { | 1249 if (var != nullptr) return var; | 
| 1258 *binding_kind = BOUND; | |
| 1259 return var; | |
| 1260 } | |
| 1261 | 1250 | 
| 1262 // We did not find a variable locally. Check against the function variable, if | 1251 // We did not find a variable locally. Check against the function variable, if | 
| 1263 // any. | 1252 // any. | 
| 1264 if (is_function_scope()) { | 1253 if (is_function_scope()) { | 
| 1265 var = AsDeclarationScope()->LookupFunctionVar(proxy->raw_name()); | 1254 var = AsDeclarationScope()->LookupFunctionVar(proxy->raw_name()); | 
| 1266 if (var != nullptr) { | 1255 if (var != nullptr) { | 
| 1267 *binding_kind = calls_sloppy_eval() ? BOUND_EVAL_SHADOWED : BOUND; | 1256 if (calls_sloppy_eval()) return NonLocal(proxy->raw_name(), DYNAMIC); | 
| 1268 return var; | 1257 return var; | 
| 1269 } | 1258 } | 
| 1270 } | 1259 } | 
| 1271 | 1260 | 
| 1272 if (outer_scope_ != outer_scope_end) { | 1261 if (outer_scope_ != outer_scope_end) { | 
| 1273 var = outer_scope_->LookupRecursive(proxy, binding_kind, factory, | 1262 var = outer_scope_->LookupRecursive(proxy, resolve_free, outer_scope_end); | 
| 1274 outer_scope_end); | 1263 | 
| 1275 if (*binding_kind == BOUND && is_function_scope()) { | 1264 // The variable could not be resolved statically. | 
| 1265 if (var == nullptr) return var; | |
| 1266 | |
| 1267 if (is_function_scope() && !var->is_dynamic()) { | |
| 1276 var->ForceContextAllocation(); | 1268 var->ForceContextAllocation(); | 
| 1277 } | 1269 } | 
| 1278 // "this" can't be shadowed by "eval"-introduced bindings or by "with" | 1270 // "this" can't be shadowed by "eval"-introduced bindings or by "with" | 
| 1279 // scopes. | 1271 // scopes. | 
| 1280 // TODO(wingo): There are other variables in this category; add them. | 1272 // TODO(wingo): There are other variables in this category; add them. | 
| 1281 if (var != nullptr && var->is_this()) return var; | 1273 if (var->is_this()) return var; | 
| 1282 | 1274 | 
| 1283 if (is_with_scope()) { | 1275 if (is_with_scope()) { | 
| 1284 // The current scope is a with scope, so the variable binding can not be | 1276 // The current scope is a with scope, so the variable binding can not be | 
| 1285 // statically resolved. However, note that it was necessary to do a lookup | 1277 // statically resolved. However, note that it was necessary to do a lookup | 
| 1286 // in the outer scope anyway, because if a binding exists in an outer | 1278 // in the outer scope anyway, because if a binding exists in an outer | 
| 1287 // scope, the associated variable has to be marked as potentially being | 1279 // scope, the associated variable has to be marked as potentially being | 
| 1288 // accessed from inside of an inner with scope (the property may not be in | 1280 // accessed from inside of an inner with scope (the property may not be in | 
| 1289 // the 'with' object). | 1281 // the 'with' object). | 
| 1290 if (var != nullptr && var->IsUnallocated()) { | 1282 if (!var->is_dynamic() && var->IsUnallocated()) { | 
| 1291 DCHECK(!already_resolved_); | 1283 DCHECK(!already_resolved_); | 
| 1292 var->set_is_used(); | 1284 var->set_is_used(); | 
| 1293 var->ForceContextAllocation(); | 1285 var->ForceContextAllocation(); | 
| 1294 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1286 if (proxy->is_assigned()) var->set_maybe_assigned(); | 
| 1295 } | 1287 } | 
| 1296 *binding_kind = DYNAMIC_LOOKUP; | 1288 return NonLocal(proxy->raw_name(), DYNAMIC); | 
| 1297 return nullptr; | |
| 1298 } | 1289 } | 
| 1290 } else if (!resolve_free) { | |
| 1291 return nullptr; | |
| 1299 } else { | 1292 } else { | 
| 1300 DCHECK(!is_with_scope()); | 1293 DCHECK(is_script_scope()); | 
| 1301 DCHECK(is_function_scope() || is_script_scope() || is_eval_scope()); | 1294 // No binding has been found. Declare a variable on the global object. | 
| 1295 return AsDeclarationScope()->DeclareDynamicGlobal(proxy->raw_name(), | |
| 1296 Variable::NORMAL); | |
| 1302 } | 1297 } | 
| 1303 | 1298 | 
| 
adamk
2016/08/23 18:15:09
Can you add a few DCHECKs?
DCHECK(resolve_free);
 
Toon Verwaest
2016/08/23 20:09:11
I've changed the branches to make it more obvious.
 | |
| 1304 if (calls_sloppy_eval() && is_declaration_scope() && !is_script_scope()) { | 1299 if (calls_sloppy_eval() && is_declaration_scope()) { | 
| 1305 // A variable binding may have been found in an outer scope, but the current | 1300 // A variable binding may have been found in an outer scope, but the current | 
| 1306 // scope makes a sloppy 'eval' call, so the found variable may not be the | 1301 // scope makes a sloppy 'eval' call, so the found variable may not be the | 
| 1307 // correct one (the 'eval' may introduce a binding with the same name). In | 1302 // correct one (the 'eval' may introduce a binding with the same name). In | 
| 1308 // that case, change the lookup result to reflect this situation. Only | 1303 // that case, change the lookup result to reflect this situation. Only | 
| 1309 // scopes that can host var bindings (declaration scopes) need be considered | 1304 // scopes that can host var bindings (declaration scopes) need be considered | 
| 1310 // here (this excludes block and catch scopes), and variable lookups at | 1305 // here (this excludes block and catch scopes), and variable lookups at | 
| 1311 // script scope are always dynamic. | 1306 // script scope are always dynamic. | 
| 1312 if (*binding_kind == BOUND) { | 1307 if (var->IsGlobalObjectProperty()) { | 
| 1313 *binding_kind = BOUND_EVAL_SHADOWED; | 1308 return NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); | 
| 1314 } else if (*binding_kind == UNBOUND) { | |
| 1315 *binding_kind = UNBOUND_EVAL_SHADOWED; | |
| 1316 } | 1309 } | 
| 1310 | |
| 1311 if (var->is_dynamic()) return var; | |
| 1312 | |
| 1313 Variable* invalidated = var; | |
| 1314 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL); | |
| 1315 var->set_local_if_not_shadowed(invalidated); | |
| 1317 } | 1316 } | 
| 1318 | 1317 | 
| 1319 return var; | 1318 return var; | 
| 1320 } | 1319 } | 
| 1321 | 1320 | 
| 1322 void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy, | 1321 void Scope::ResolveVariable(ParseInfo* info, VariableProxy* proxy) { | 
| 1323 AstNodeFactory* factory) { | |
| 1324 DCHECK(info->script_scope()->is_script_scope()); | 1322 DCHECK(info->script_scope()->is_script_scope()); | 
| 1325 | 1323 | 
| 1326 // If the proxy is already resolved there's nothing to do | 1324 // If the proxy is already resolved there's nothing to do | 
| 1327 // (functions and consts may be resolved by the parser). | 1325 // (functions and consts may be resolved by the parser). | 
| 1328 if (proxy->is_resolved()) return; | 1326 if (proxy->is_resolved()) return; | 
| 1329 | 1327 | 
| 1330 // Otherwise, try to resolve the variable. | 1328 // Otherwise, try to resolve the variable. | 
| 1331 BindingKind binding_kind = UNBOUND; | 1329 Variable* var = LookupRecursive(proxy, true, nullptr); | 
| 1332 Variable* var = LookupRecursive(proxy, &binding_kind, factory); | |
| 1333 | 1330 | 
| 1334 ResolveTo(info, binding_kind, proxy, var); | 1331 ResolveTo(info, proxy, var); | 
| 1335 } | 1332 } | 
| 1336 | 1333 | 
| 1337 void Scope::ResolveTo(ParseInfo* info, BindingKind binding_kind, | 1334 void Scope::ResolveTo(ParseInfo* info, VariableProxy* proxy, Variable* var) { | 
| 1338 VariableProxy* proxy, Variable* var) { | |
| 1339 #ifdef DEBUG | 1335 #ifdef DEBUG | 
| 1340 if (info->script_is_native()) { | 1336 if (info->script_is_native()) { | 
| 1341 // To avoid polluting the global object in native scripts | 1337 // To avoid polluting the global object in native scripts | 
| 1342 // - Variables must not be allocated to the global scope. | 1338 // - Variables must not be allocated to the global scope. | 
| 1343 CHECK_NOT_NULL(outer_scope()); | 1339 CHECK_NOT_NULL(outer_scope()); | 
| 1344 // - Variables must be bound locally or unallocated. | 1340 // - Variables must be bound locally or unallocated. | 
| 1345 if (BOUND != binding_kind) { | 1341 if (var->IsGlobalObjectProperty()) { | 
| 1346 // The following variable name may be minified. If so, disable | 1342 // The following variable name may be minified. If so, disable | 
| 1347 // minification in js2c.py for better output. | 1343 // minification in js2c.py for better output. | 
| 1348 Handle<String> name = proxy->raw_name()->string(); | 1344 Handle<String> name = proxy->raw_name()->string(); | 
| 1349 V8_Fatal(__FILE__, __LINE__, "Unbound variable: '%s' in native script.", | 1345 V8_Fatal(__FILE__, __LINE__, "Unbound variable: '%s' in native script.", | 
| 1350 name->ToCString().get()); | 1346 name->ToCString().get()); | 
| 1351 } | 1347 } | 
| 1352 VariableLocation location = var->location(); | 1348 VariableLocation location = var->location(); | 
| 1353 CHECK(location == VariableLocation::LOCAL || | 1349 CHECK(location == VariableLocation::LOCAL || | 
| 1354 location == VariableLocation::CONTEXT || | 1350 location == VariableLocation::CONTEXT || | 
| 1355 location == VariableLocation::PARAMETER || | 1351 location == VariableLocation::PARAMETER || | 
| 1356 location == VariableLocation::UNALLOCATED); | 1352 location == VariableLocation::UNALLOCATED); | 
| 1357 } | 1353 } | 
| 1358 #endif | 1354 #endif | 
| 1359 | 1355 | 
| 1360 switch (binding_kind) { | 1356 DCHECK_NOT_NULL(var); | 
| 1361 case BOUND: | |
| 1362 break; | |
| 1363 | |
| 1364 case BOUND_EVAL_SHADOWED: | |
| 1365 // We either found a variable binding that might be shadowed by eval or | |
| 1366 // gave up on it (e.g. by encountering a local with the same in the outer | |
| 1367 // scope which was not promoted to a context, this can happen if we use | |
| 1368 // debugger to evaluate arbitrary expressions at a break point). | |
| 1369 if (var->IsGlobalObjectProperty()) { | |
| 1370 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); | |
| 1371 } else if (var->is_dynamic()) { | |
| 1372 var = NonLocal(proxy->raw_name(), DYNAMIC); | |
| 1373 } else { | |
| 1374 Variable* invalidated = var; | |
| 1375 var = NonLocal(proxy->raw_name(), DYNAMIC_LOCAL); | |
| 1376 var->set_local_if_not_shadowed(invalidated); | |
| 1377 } | |
| 1378 break; | |
| 1379 | |
| 1380 case UNBOUND: | |
| 1381 // No binding has been found. Declare a variable on the global object. | |
| 1382 var = info->script_scope()->DeclareDynamicGlobal(proxy->raw_name(), | |
| 1383 Variable::NORMAL); | |
| 1384 break; | |
| 1385 | |
| 1386 case UNBOUND_EVAL_SHADOWED: | |
| 1387 // No binding has been found. But some scope makes a sloppy 'eval' call. | |
| 1388 var = NonLocal(proxy->raw_name(), DYNAMIC_GLOBAL); | |
| 1389 break; | |
| 1390 | |
| 1391 case DYNAMIC_LOOKUP: | |
| 1392 // The variable could not be resolved statically. | |
| 1393 var = NonLocal(proxy->raw_name(), DYNAMIC); | |
| 1394 break; | |
| 1395 } | |
| 1396 | |
| 1397 DCHECK(var != NULL); | |
| 1398 if (proxy->is_assigned()) var->set_maybe_assigned(); | 1357 if (proxy->is_assigned()) var->set_maybe_assigned(); | 
| 1399 | |
| 1400 proxy->BindTo(var); | 1358 proxy->BindTo(var); | 
| 1401 } | 1359 } | 
| 1402 | 1360 | 
| 1403 void Scope::ResolveVariablesRecursively(ParseInfo* info, | 1361 void Scope::ResolveVariablesRecursively(ParseInfo* info) { | 
| 1404 AstNodeFactory* factory) { | |
| 1405 DCHECK(info->script_scope()->is_script_scope()); | 1362 DCHECK(info->script_scope()->is_script_scope()); | 
| 1406 | 1363 | 
| 1407 // Resolve unresolved variables for this scope. | 1364 // Resolve unresolved variables for this scope. | 
| 1408 for (VariableProxy* proxy = unresolved_; proxy != nullptr; | 1365 for (VariableProxy* proxy = unresolved_; proxy != nullptr; | 
| 1409 proxy = proxy->next_unresolved()) { | 1366 proxy = proxy->next_unresolved()) { | 
| 1410 ResolveVariable(info, proxy, factory); | 1367 ResolveVariable(info, proxy); | 
| 1411 } | 1368 } | 
| 1412 | 1369 | 
| 1413 // Resolve unresolved variables for inner scopes. | 1370 // Resolve unresolved variables for inner scopes. | 
| 1414 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1371 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 
| 1415 scope->ResolveVariablesRecursively(info, factory); | 1372 scope->ResolveVariablesRecursively(info); | 
| 1416 } | 1373 } | 
| 1417 } | 1374 } | 
| 1418 | 1375 | 
| 1419 VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope, | 1376 VariableProxy* Scope::FetchFreeVariables(DeclarationScope* max_outer_scope, | 
| 1420 ParseInfo* info, | 1377 ParseInfo* info, | 
| 1421 VariableProxy* stack) { | 1378 VariableProxy* stack) { | 
| 1422 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; | 1379 for (VariableProxy *proxy = unresolved_, *next = nullptr; proxy != nullptr; | 
| 1423 proxy = next) { | 1380 proxy = next) { | 
| 1424 next = proxy->next_unresolved(); | 1381 next = proxy->next_unresolved(); | 
| 1425 if (proxy->is_resolved()) continue; | 1382 if (proxy->is_resolved()) continue; | 
| 1426 // Note that we pass nullptr as AstNodeFactory: this phase should not create | 1383 // Note that we pass nullptr as AstNodeFactory: this phase should not create | 
| 
adamk
2016/08/23 18:15:09
Dead comment
 
Toon Verwaest
2016/08/23 20:09:11
Done.
 | |
| 1427 // any new AstNodes, since none of the Scopes involved are backed up by | 1384 // any new AstNodes, since none of the Scopes involved are backed up by | 
| 1428 // ScopeInfo. | 1385 // ScopeInfo. | 
| 1429 BindingKind binding_kind = UNBOUND; | 1386 Variable* var = | 
| 1430 Variable* var = LookupRecursive(proxy, &binding_kind, nullptr, | 1387 LookupRecursive(proxy, false, max_outer_scope->outer_scope()); | 
| 1431 max_outer_scope->outer_scope()); | |
| 1432 if (var == nullptr) { | 1388 if (var == nullptr) { | 
| 1433 proxy->set_next_unresolved(stack); | 1389 proxy->set_next_unresolved(stack); | 
| 1434 stack = proxy; | 1390 stack = proxy; | 
| 1435 } else if (info != nullptr) { | 1391 } else if (info != nullptr) { | 
| 1436 DCHECK_NE(UNBOUND, binding_kind); | 1392 ResolveTo(info, proxy, var); | 
| 1437 DCHECK_NE(UNBOUND_EVAL_SHADOWED, binding_kind); | |
| 1438 ResolveTo(info, binding_kind, proxy, var); | |
| 1439 } | 1393 } | 
| 1440 } | 1394 } | 
| 1441 | 1395 | 
| 1442 // Clear unresolved_ as it's in an inconsistent state. | 1396 // Clear unresolved_ as it's in an inconsistent state. | 
| 1443 unresolved_ = nullptr; | 1397 unresolved_ = nullptr; | 
| 1444 | 1398 | 
| 1445 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 1399 for (Scope* scope = inner_scope_; scope != nullptr; scope = scope->sibling_) { | 
| 1446 stack = scope->FetchFreeVariables(max_outer_scope, info, stack); | 1400 stack = scope->FetchFreeVariables(max_outer_scope, info, stack); | 
| 1447 } | 1401 } | 
| 1448 | 1402 | 
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1725 function != nullptr && function->IsContextSlot(); | 1679 function != nullptr && function->IsContextSlot(); | 
| 1726 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 1680 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - | 
| 1727 (is_function_var_in_context ? 1 : 0); | 1681 (is_function_var_in_context ? 1 : 0); | 
| 1728 } | 1682 } | 
| 1729 | 1683 | 
| 1730 | 1684 | 
| 1731 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 1685 int Scope::ContextGlobalCount() const { return num_global_slots(); } | 
| 1732 | 1686 | 
| 1733 } // namespace internal | 1687 } // namespace internal | 
| 1734 } // namespace v8 | 1688 } // namespace v8 | 
| OLD | NEW |