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/ast/ast.h" | 10 #include "src/ast/ast.h" |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 | 301 |
302 bool Scope::IsAsmModule() const { | 302 bool Scope::IsAsmModule() const { |
303 return is_function_scope() && AsDeclarationScope()->asm_module(); | 303 return is_function_scope() && AsDeclarationScope()->asm_module(); |
304 } | 304 } |
305 | 305 |
306 bool Scope::IsAsmFunction() const { | 306 bool Scope::IsAsmFunction() const { |
307 return is_function_scope() && AsDeclarationScope()->asm_function(); | 307 return is_function_scope() && AsDeclarationScope()->asm_function(); |
308 } | 308 } |
309 | 309 |
310 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, | 310 Scope* Scope::DeserializeScopeChain(Isolate* isolate, Zone* zone, |
311 Context* context, | 311 ScopeInfo* scope_info, |
312 DeclarationScope* script_scope, | 312 DeclarationScope* script_scope, |
313 AstValueFactory* ast_value_factory, | 313 AstValueFactory* ast_value_factory, |
314 DeserializationMode deserialization_mode) { | 314 DeserializationMode deserialization_mode) { |
315 // Reconstruct the outer scope chain from a closure's context chain. | 315 // Reconstruct the outer scope chain from a closure's context chain. |
316 Scope* current_scope = nullptr; | 316 Scope* current_scope = nullptr; |
317 Scope* innermost_scope = nullptr; | 317 Scope* innermost_scope = nullptr; |
318 Scope* outer_scope = nullptr; | 318 Scope* outer_scope = nullptr; |
319 while (!context->IsNativeContext()) { | 319 while (scope_info) { |
320 if (context->IsWithContext() || context->IsDebugEvaluateContext()) { | 320 if (scope_info->scope_type() == WITH_SCOPE) { |
321 // For scope analysis, debug-evaluate is equivalent to a with scope. | 321 // For scope analysis, debug-evaluate is equivalent to a with scope. |
322 outer_scope = new (zone) | 322 outer_scope = new (zone) Scope(zone, WITH_SCOPE, handle(scope_info)); |
323 Scope(zone, WITH_SCOPE, Handle<ScopeInfo>(context->scope_info())); | |
324 | 323 |
325 // TODO(yangguo): Remove once debug-evaluate properly keeps track of the | 324 // TODO(yangguo): Remove once debug-evaluate properly keeps track of the |
326 // function scope in which we are evaluating. | 325 // function scope in which we are evaluating. |
327 if (context->IsDebugEvaluateContext()) { | 326 if (scope_info->IsDebugEvaluateScope()) { |
328 outer_scope->set_is_debug_evaluate_scope(); | 327 outer_scope->set_is_debug_evaluate_scope(); |
329 } | 328 } |
330 } else if (context->IsScriptContext()) { | 329 } else if (scope_info->scope_type() == SCRIPT_SCOPE) { |
331 // If we reach a script context, it's the outermost context with scope | 330 // If we reach a script scope, it's the outermost scope. Install the |
332 // info. The next context will be the native context. Install the scope | 331 // scope info of this script context onto the existing script scope to |
333 // info of this script context onto the existing script scope to avoid | 332 // avoid nesting script scopes. |
334 // nesting script scopes. | |
335 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); | |
336 if (deserialization_mode == DeserializationMode::kIncludingVariables) { | 333 if (deserialization_mode == DeserializationMode::kIncludingVariables) { |
337 script_scope->SetScriptScopeInfo(scope_info); | 334 script_scope->SetScriptScopeInfo(handle(scope_info)); |
338 } | 335 } |
339 DCHECK(context->previous()->IsNativeContext()); | 336 DCHECK(!scope_info->HasOuterScopeInfo()); |
340 break; | 337 break; |
341 } else if (context->IsFunctionContext()) { | 338 } else if (scope_info->scope_type() == FUNCTION_SCOPE || |
342 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); | 339 scope_info->scope_type() == EVAL_SCOPE) { |
343 // TODO(neis): For an eval scope, we currently create an ordinary function | 340 // TODO(neis): For an eval scope, we currently create an ordinary function |
344 // context. This is wrong and needs to be fixed. | 341 // context. This is wrong and needs to be fixed. |
345 // https://bugs.chromium.org/p/v8/issues/detail?id=5295 | 342 // https://bugs.chromium.org/p/v8/issues/detail?id=5295 |
346 DCHECK(scope_info->scope_type() == FUNCTION_SCOPE || | |
347 scope_info->scope_type() == EVAL_SCOPE); | |
348 outer_scope = | 343 outer_scope = |
349 new (zone) DeclarationScope(zone, FUNCTION_SCOPE, scope_info); | 344 new (zone) DeclarationScope(zone, FUNCTION_SCOPE, handle(scope_info)); |
350 if (scope_info->IsAsmFunction()) | 345 if (scope_info->IsAsmFunction()) |
351 outer_scope->AsDeclarationScope()->set_asm_function(); | 346 outer_scope->AsDeclarationScope()->set_asm_function(); |
352 if (scope_info->IsAsmModule()) | 347 if (scope_info->IsAsmModule()) |
353 outer_scope->AsDeclarationScope()->set_asm_module(); | 348 outer_scope->AsDeclarationScope()->set_asm_module(); |
354 } else if (context->IsBlockContext()) { | 349 } else if (scope_info->scope_type() == BLOCK_SCOPE) { |
355 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); | |
356 DCHECK_EQ(scope_info->scope_type(), BLOCK_SCOPE); | |
357 if (scope_info->is_declaration_scope()) { | 350 if (scope_info->is_declaration_scope()) { |
358 outer_scope = | 351 outer_scope = |
359 new (zone) DeclarationScope(zone, BLOCK_SCOPE, scope_info); | 352 new (zone) DeclarationScope(zone, BLOCK_SCOPE, handle(scope_info)); |
360 } else { | 353 } else { |
361 outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, scope_info); | 354 outer_scope = new (zone) Scope(zone, BLOCK_SCOPE, handle(scope_info)); |
362 } | 355 } |
363 } else if (context->IsModuleContext()) { | 356 } else if (scope_info->scope_type() == MODULE_SCOPE) { |
364 ScopeInfo* scope_info = context->scope_info(); | 357 outer_scope = new (zone) |
365 DCHECK_EQ(scope_info->scope_type(), MODULE_SCOPE); | 358 ModuleScope(isolate, handle(scope_info), ast_value_factory); |
366 outer_scope = new (zone) ModuleScope( | |
367 isolate, Handle<ScopeInfo>(scope_info), ast_value_factory); | |
368 } else { | 359 } else { |
369 DCHECK(context->IsCatchContext()); | 360 DCHECK_EQ(scope_info->scope_type(), CATCH_SCOPE); |
370 String* name = context->catch_name(); | 361 DCHECK_EQ(scope_info->LocalCount(), 1); |
| 362 String* name = scope_info->LocalName(0); |
371 outer_scope = new (zone) | 363 outer_scope = new (zone) |
372 Scope(zone, ast_value_factory->GetString(handle(name, isolate)), | 364 Scope(zone, ast_value_factory->GetString(handle(name, isolate)), |
373 Handle<ScopeInfo>(context->scope_info())); | 365 handle(scope_info)); |
374 } | 366 } |
375 if (deserialization_mode == DeserializationMode::kScopesOnly) { | 367 if (deserialization_mode == DeserializationMode::kScopesOnly) { |
376 outer_scope->scope_info_ = Handle<ScopeInfo>::null(); | 368 outer_scope->scope_info_ = Handle<ScopeInfo>::null(); |
377 } | 369 } |
378 if (current_scope != nullptr) { | 370 if (current_scope != nullptr) { |
379 outer_scope->AddInnerScope(current_scope); | 371 outer_scope->AddInnerScope(current_scope); |
380 DCHECK_IMPLIES( | |
381 deserialization_mode == DeserializationMode::kIncludingVariables, | |
382 current_scope->scope_info_->HasOuterScopeInfo()); | |
383 DCHECK_IMPLIES( | |
384 deserialization_mode == DeserializationMode::kIncludingVariables, | |
385 outer_scope->scope_info_->Equals( | |
386 current_scope->scope_info_->OuterScopeInfo())); | |
387 } | 372 } |
388 current_scope = outer_scope; | 373 current_scope = outer_scope; |
389 if (innermost_scope == nullptr) innermost_scope = current_scope; | 374 if (innermost_scope == nullptr) innermost_scope = current_scope; |
390 context = context->previous(); | 375 scope_info = scope_info->HasOuterScopeInfo() ? scope_info->OuterScopeInfo() |
| 376 : nullptr; |
391 } | 377 } |
392 | 378 |
393 if (innermost_scope == nullptr) return script_scope; | 379 if (innermost_scope == nullptr) return script_scope; |
394 script_scope->AddInnerScope(current_scope); | 380 script_scope->AddInnerScope(current_scope); |
395 #if DEBUG | |
396 if (deserialization_mode == DeserializationMode::kIncludingVariables) { | |
397 if (script_scope->scope_info_.is_null()) { | |
398 DCHECK(!current_scope->scope_info_->HasOuterScopeInfo()); | |
399 } else { | |
400 DCHECK(!script_scope->scope_info_->HasOuterScopeInfo()); | |
401 DCHECK(script_scope->scope_info_->Equals( | |
402 current_scope->scope_info_->OuterScopeInfo())); | |
403 } | |
404 } | |
405 #endif | |
406 return innermost_scope; | 381 return innermost_scope; |
407 } | 382 } |
408 | 383 |
409 DeclarationScope* Scope::AsDeclarationScope() { | 384 DeclarationScope* Scope::AsDeclarationScope() { |
410 DCHECK(is_declaration_scope()); | 385 DCHECK(is_declaration_scope()); |
411 return static_cast<DeclarationScope*>(this); | 386 return static_cast<DeclarationScope*>(this); |
412 } | 387 } |
413 | 388 |
414 const DeclarationScope* Scope::AsDeclarationScope() const { | 389 const DeclarationScope* Scope::AsDeclarationScope() const { |
415 DCHECK(is_declaration_scope()); | 390 DCHECK(is_declaration_scope()); |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
520 factory->NewExpressionStatement(assignment, kNoSourcePosition); | 495 factory->NewExpressionStatement(assignment, kNoSourcePosition); |
521 delegate->set_statement(statement); | 496 delegate->set_statement(statement); |
522 } | 497 } |
523 } | 498 } |
524 } | 499 } |
525 | 500 |
526 void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { | 501 void DeclarationScope::Analyze(ParseInfo* info, AnalyzeMode mode) { |
527 DCHECK(info->literal() != NULL); | 502 DCHECK(info->literal() != NULL); |
528 DeclarationScope* scope = info->literal()->scope(); | 503 DeclarationScope* scope = info->literal()->scope(); |
529 | 504 |
530 if (!info->context().is_null() && !info->context()->IsNativeContext()) { | 505 Handle<ScopeInfo> outer_scope_info; |
| 506 if (info->maybe_outer_scope_info().ToHandle(&outer_scope_info)) { |
531 if (scope->outer_scope()) { | 507 if (scope->outer_scope()) { |
532 DeclarationScope* script_scope = new (info->zone()) | 508 DeclarationScope* script_scope = new (info->zone()) |
533 DeclarationScope(info->zone(), info->ast_value_factory()); | 509 DeclarationScope(info->zone(), info->ast_value_factory()); |
534 info->set_script_scope(script_scope); | 510 info->set_script_scope(script_scope); |
535 scope->ReplaceOuterScope(Scope::DeserializeScopeChain( | 511 scope->ReplaceOuterScope(Scope::DeserializeScopeChain( |
536 info->isolate(), info->zone(), *info->context(), script_scope, | 512 info->isolate(), info->zone(), *outer_scope_info, script_scope, |
537 info->ast_value_factory(), | 513 info->ast_value_factory(), |
538 Scope::DeserializationMode::kIncludingVariables)); | 514 Scope::DeserializationMode::kIncludingVariables)); |
539 } else { | 515 } else { |
540 DCHECK(info->context()->IsScriptContext()); | 516 DCHECK_EQ(outer_scope_info->scope_type(), SCRIPT_SCOPE); |
541 Handle<ScopeInfo> scope_info(info->context()->scope_info(), | 517 scope->SetScriptScopeInfo(outer_scope_info); |
542 info->isolate()); | |
543 scope->SetScriptScopeInfo(scope_info); | |
544 } | 518 } |
545 } | 519 } |
546 | 520 |
547 if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) { | 521 if (scope->is_eval_scope() && is_sloppy(scope->language_mode())) { |
548 AstNodeFactory factory(info->ast_value_factory()); | 522 AstNodeFactory factory(info->ast_value_factory()); |
549 scope->HoistSloppyBlockFunctions(&factory); | 523 scope->HoistSloppyBlockFunctions(&factory); |
550 } | 524 } |
551 | 525 |
552 // We are compiling one of three cases: | 526 // We are compiling one of three cases: |
553 // 1) top-level code, | 527 // 1) top-level code, |
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1837 Variable* function = | 1811 Variable* function = |
1838 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; | 1812 is_function_scope() ? AsDeclarationScope()->function_var() : nullptr; |
1839 bool is_function_var_in_context = | 1813 bool is_function_var_in_context = |
1840 function != nullptr && function->IsContextSlot(); | 1814 function != nullptr && function->IsContextSlot(); |
1841 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - | 1815 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - |
1842 (is_function_var_in_context ? 1 : 0); | 1816 (is_function_var_in_context ? 1 : 0); |
1843 } | 1817 } |
1844 | 1818 |
1845 } // namespace internal | 1819 } // namespace internal |
1846 } // namespace v8 | 1820 } // namespace v8 |
OLD | NEW |