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

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

Issue 2280933002: Always deserialize scope infos for parsing (Closed)
Patch Set: updates Created 4 years, 3 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/heap/heap.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 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
279 if (context->IsDebugEvaluateContext()) { 279 if (context->IsDebugEvaluateContext()) {
280 outer_scope->set_is_debug_evaluate_scope(); 280 outer_scope->set_is_debug_evaluate_scope();
281 } 281 }
282 } else if (context->IsScriptContext()) { 282 } else if (context->IsScriptContext()) {
283 // If we reach a script context, it's the outermost context with scope 283 // If we reach a script context, it's the outermost context with scope
284 // info. The next context will be the native context. Install the scope 284 // info. The next context will be the native context. Install the scope
285 // info of this script context onto the existing script scope to avoid 285 // info of this script context onto the existing script scope to avoid
286 // nesting script scopes. 286 // nesting script scopes.
287 Handle<ScopeInfo> scope_info(context->scope_info(), isolate); 287 Handle<ScopeInfo> scope_info(context->scope_info(), isolate);
288 script_scope->SetScriptScopeInfo(scope_info); 288 script_scope->SetScriptScopeInfo(scope_info);
289 script_scope->DeserializeScopeInfo(isolate, ast_value_factory);
290 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) {
291 script_scope->scope_info_ = Handle<ScopeInfo>::null();
292 }
289 DCHECK(context->previous()->IsNativeContext()); 293 DCHECK(context->previous()->IsNativeContext());
290 break; 294 break;
291 } else if (context->IsFunctionContext()) { 295 } else if (context->IsFunctionContext()) {
292 Handle<ScopeInfo> scope_info(context->closure()->shared()->scope_info(), 296 Handle<ScopeInfo> scope_info(context->closure()->shared()->scope_info(),
293 isolate); 297 isolate);
294 // TODO(neis): For an eval scope, we currently create an ordinary function 298 // TODO(neis): For an eval scope, we currently create an ordinary function
295 // context. This is wrong and needs to be fixed. 299 // context. This is wrong and needs to be fixed.
296 // https://bugs.chromium.org/p/v8/issues/detail?id=5295 300 // https://bugs.chromium.org/p/v8/issues/detail?id=5295
297 DCHECK(scope_info->scope_type() == FUNCTION_SCOPE || 301 DCHECK(scope_info->scope_type() == FUNCTION_SCOPE ||
298 scope_info->scope_type() == EVAL_SCOPE); 302 scope_info->scope_type() == EVAL_SCOPE);
(...skipping 15 matching lines...) Expand all
314 } else { 318 } else {
315 DCHECK(context->IsCatchContext()); 319 DCHECK(context->IsCatchContext());
316 String* name = context->catch_name(); 320 String* name = context->catch_name();
317 outer_scope = new (zone) 321 outer_scope = new (zone)
318 Scope(zone, ast_value_factory->GetString(handle(name, isolate))); 322 Scope(zone, ast_value_factory->GetString(handle(name, isolate)));
319 } 323 }
320 if (current_scope != nullptr) { 324 if (current_scope != nullptr) {
321 outer_scope->AddInnerScope(current_scope); 325 outer_scope->AddInnerScope(current_scope);
322 } 326 }
323 current_scope = outer_scope; 327 current_scope = outer_scope;
328 current_scope->DeserializeScopeInfo(isolate, ast_value_factory);
324 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) { 329 if (deserialization_mode == DeserializationMode::kDeserializeOffHeap) {
325 current_scope->DeserializeScopeInfo(isolate, ast_value_factory); 330 current_scope->scope_info_ = Handle<ScopeInfo>::null();
326 } 331 }
327 if (innermost_scope == nullptr) innermost_scope = current_scope; 332 if (innermost_scope == nullptr) innermost_scope = current_scope;
328 context = context->previous(); 333 context = context->previous();
329 } 334 }
330 335
331 if (innermost_scope == nullptr) return script_scope; 336 if (innermost_scope == nullptr) return script_scope;
332 script_scope->AddInnerScope(current_scope); 337 script_scope->AddInnerScope(current_scope);
333 script_scope->PropagateScopeInfo(); 338 script_scope->PropagateScopeInfo();
334 return innermost_scope; 339 return innermost_scope;
335 } 340 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
391 Handle<String> name_handle(scope_info_->FunctionName(), isolate); 396 Handle<String> name_handle(scope_info_->FunctionName(), isolate);
392 const AstRawString* name = ast_value_factory->GetString(name_handle); 397 const AstRawString* name = ast_value_factory->GetString(name_handle);
393 VariableMode mode; 398 VariableMode mode;
394 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode); 399 int index = scope_info_->FunctionContextSlotIndex(*name_handle, &mode);
395 if (index >= 0) { 400 if (index >= 0) {
396 Variable* result = AsDeclarationScope()->DeclareFunctionVar(name); 401 Variable* result = AsDeclarationScope()->DeclareFunctionVar(name);
397 DCHECK_EQ(mode, result->mode()); 402 DCHECK_EQ(mode, result->mode());
398 result->AllocateTo(VariableLocation::CONTEXT, index); 403 result->AllocateTo(VariableLocation::CONTEXT, index);
399 } 404 }
400 } 405 }
401
402 scope_info_ = Handle<ScopeInfo>::null();
403 } 406 }
404 407
405 DeclarationScope* Scope::AsDeclarationScope() { 408 DeclarationScope* Scope::AsDeclarationScope() {
406 DCHECK(is_declaration_scope()); 409 DCHECK(is_declaration_scope());
407 return static_cast<DeclarationScope*>(this); 410 return static_cast<DeclarationScope*>(this);
408 } 411 }
409 412
410 const DeclarationScope* Scope::AsDeclarationScope() const { 413 const DeclarationScope* Scope::AsDeclarationScope() const {
411 DCHECK(is_declaration_scope()); 414 DCHECK(is_declaration_scope());
412 return static_cast<const DeclarationScope*>(this); 415 return static_cast<const DeclarationScope*>(this);
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
602 } 605 }
603 606
604 607
605 void Scope::PropagateUsageFlagsToScope(Scope* other) { 608 void Scope::PropagateUsageFlagsToScope(Scope* other) {
606 DCHECK_NOT_NULL(other); 609 DCHECK_NOT_NULL(other);
607 DCHECK(!already_resolved_); 610 DCHECK(!already_resolved_);
608 DCHECK(!other->already_resolved_); 611 DCHECK(!other->already_resolved_);
609 if (calls_eval()) other->RecordEvalCall(); 612 if (calls_eval()) other->RecordEvalCall();
610 } 613 }
611 614
612 Variable* Scope::LookupInScopeInfo(const AstRawString* name) {
613 Handle<String> name_handle = name->string();
614 // The Scope is backed up by ScopeInfo. This means it cannot operate in a
615 // heap-independent mode, and all strings must be internalized immediately. So
616 // it's ok to get the Handle<String> here.
617 // If we have a serialized scope info, we might find the variable there.
618 // There should be no local slot with the given name.
619 DCHECK(scope_info_->StackSlotIndex(*name_handle) < 0);
620
621 VariableMode mode;
622 InitializationFlag init_flag;
623 MaybeAssignedFlag maybe_assigned_flag;
624
625 VariableLocation location = VariableLocation::CONTEXT;
626 int index = ScopeInfo::ContextSlotIndex(scope_info_, name_handle, &mode,
627 &init_flag, &maybe_assigned_flag);
628 if (index < 0) {
629 location = VariableLocation::GLOBAL;
630 index = ScopeInfo::ContextGlobalSlotIndex(scope_info_, name_handle, &mode,
631 &init_flag, &maybe_assigned_flag);
632 DCHECK(index < 0 || (is_script_scope() && mode == VAR));
633 }
634 if (index < 0) {
635 location = VariableLocation::LOOKUP;
636 index = scope_info_->ParameterIndex(*name_handle);
637 if (index >= 0) {
638 mode = DYNAMIC;
639 init_flag = kCreatedInitialized;
640 // Be conservative and flag parameters as maybe assigned. Better
641 // information would require ScopeInfo to serialize the maybe_assigned bit
642 // also for parameters.
643 maybe_assigned_flag = kMaybeAssigned;
644 }
645 }
646 if (index < 0 && scope_type() == MODULE_SCOPE) {
647 location = VariableLocation::MODULE;
648 index = -1; // TODO(neis): Find module variables in scope info.
649 }
650 if (index < 0) return nullptr; // Nowhere found.
651
652 Variable::Kind kind = Variable::NORMAL;
653 if (location == VariableLocation::CONTEXT &&
654 index == scope_info_->ReceiverContextSlotIndex()) {
655 kind = Variable::THIS;
656 }
657 // TODO(marja, rossberg): Correctly declare FUNCTION, CLASS, NEW_TARGET, and
658 // ARGUMENTS bindings as their corresponding Variable::Kind.
659
660 Variable* var = variables_.Declare(zone(), this, name, mode, kind, init_flag,
661 maybe_assigned_flag);
662 var->AllocateTo(location, index);
663 return var;
664 }
665
666 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name) { 615 Variable* DeclarationScope::LookupFunctionVar(const AstRawString* name) {
667 if (function_ != nullptr && function_->raw_name() == name) { 616 if (function_ != nullptr && function_->raw_name() == name) return function_;
668 return function_; 617 return nullptr;
669 } else if (!scope_info_.is_null()) {
670 // If we are backed by a scope info, try to lookup the variable there.
671 VariableMode mode;
672 int index = scope_info_->FunctionContextSlotIndex(*(name->string()), &mode);
673 if (index < 0) return nullptr;
674 Variable* var = DeclareFunctionVar(name);
675 DCHECK_EQ(mode, var->mode());
676 var->AllocateTo(VariableLocation::CONTEXT, index);
677 return var;
678 } else {
679 return nullptr;
680 }
681 } 618 }
682 619
683 620
684 Variable* Scope::Lookup(const AstRawString* name) { 621 Variable* Scope::Lookup(const AstRawString* name) {
685 for (Scope* scope = this; 622 for (Scope* scope = this;
686 scope != NULL; 623 scope != NULL;
687 scope = scope->outer_scope()) { 624 scope = scope->outer_scope()) {
688 Variable* var = scope->LookupLocal(name); 625 Variable* var = scope->LookupLocal(name);
689 if (var != NULL) return var; 626 if (var != NULL) return var;
690 } 627 }
(...skipping 959 matching lines...) Expand 10 before | Expand all | Expand 10 after
1650 function != nullptr && function->IsContextSlot(); 1587 function != nullptr && function->IsContextSlot();
1651 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() - 1588 return num_heap_slots() - Context::MIN_CONTEXT_SLOTS - num_global_slots() -
1652 (is_function_var_in_context ? 1 : 0); 1589 (is_function_var_in_context ? 1 : 0);
1653 } 1590 }
1654 1591
1655 1592
1656 int Scope::ContextGlobalCount() const { return num_global_slots(); } 1593 int Scope::ContextGlobalCount() const { return num_global_slots(); }
1657 1594
1658 } // namespace internal 1595 } // namespace internal
1659 } // namespace v8 1596 } // namespace v8
OLDNEW
« no previous file with comments | « src/ast/scopes.h ('k') | src/heap/heap.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698