LCOV - code coverage report
Current view: top level - src/objects - scope-info.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 278 309 90.0 %
Date: 2017-04-26 Functions: 49 59 83.1 %

          Line data    Source code
       1             : // Copyright 2011 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include <stdlib.h>
       6             : 
       7             : #include "src/objects/scope-info.h"
       8             : 
       9             : #include "src/ast/context-slot-cache.h"
      10             : #include "src/ast/scopes.h"
      11             : #include "src/ast/variables.h"
      12             : #include "src/bootstrapper.h"
      13             : #include "src/objects-inl.h"
      14             : 
      15             : namespace v8 {
      16             : namespace internal {
      17             : 
      18             : // An entry in ModuleVariableEntries consists of several slots:
      19             : enum ModuleVariableEntryOffset {
      20             :   kModuleVariableNameOffset,
      21             :   kModuleVariableIndexOffset,
      22             :   kModuleVariablePropertiesOffset,
      23             :   kModuleVariableEntryLength  // Sentinel value.
      24             : };
      25             : 
      26             : #ifdef DEBUG
      27             : bool ScopeInfo::Equals(ScopeInfo* other) const {
      28             :   if (length() != other->length()) return false;
      29             :   for (int index = 0; index < length(); ++index) {
      30             :     Object* entry = get(index);
      31             :     Object* other_entry = other->get(index);
      32             :     if (entry->IsSmi()) {
      33             :       if (entry != other_entry) return false;
      34             :     } else {
      35             :       if (HeapObject::cast(entry)->map()->instance_type() !=
      36             :           HeapObject::cast(other_entry)->map()->instance_type()) {
      37             :         return false;
      38             :       }
      39             :       if (entry->IsString()) {
      40             :         if (!String::cast(entry)->Equals(String::cast(other_entry))) {
      41             :           return false;
      42             :         }
      43             :       } else if (entry->IsScopeInfo()) {
      44             :         if (!ScopeInfo::cast(entry)->Equals(ScopeInfo::cast(other_entry))) {
      45             :           return false;
      46             :         }
      47             :       } else if (entry->IsModuleInfo()) {
      48             :         if (!ModuleInfo::cast(entry)->Equals(ModuleInfo::cast(other_entry))) {
      49             :           return false;
      50             :         }
      51             :       } else {
      52             :         UNREACHABLE();
      53             :         return false;
      54             :       }
      55             :     }
      56             :   }
      57             :   return true;
      58             : }
      59             : #endif
      60             : 
      61    24196748 : Handle<ScopeInfo> ScopeInfo::Create(Isolate* isolate, Zone* zone, Scope* scope,
      62             :                                     MaybeHandle<ScopeInfo> outer_scope) {
      63             :   // Collect variables.
      64             :   int stack_local_count = 0;
      65             :   int context_local_count = 0;
      66             :   int module_vars_count = 0;
      67             :   // Stack allocated block scope variables are allocated in the parent
      68             :   // declaration scope, but are recorded in the block scope's scope info. First
      69             :   // slot index indicates at which offset a particular scope starts in the
      70             :   // parent declaration scope.
      71             :   int first_slot_index = 0;
      72    57660025 :   for (Variable* var : *scope->locals()) {
      73    23700511 :     switch (var->location()) {
      74             :       case VariableLocation::LOCAL:
      75     8862161 :         if (stack_local_count == 0) first_slot_index = var->index();
      76     8862161 :         stack_local_count++;
      77     8862161 :         break;
      78             :       case VariableLocation::CONTEXT:
      79     3476878 :         context_local_count++;
      80     3476878 :         break;
      81             :       case VariableLocation::MODULE:
      82        1780 :         module_vars_count++;
      83        1780 :         break;
      84             :       default:
      85             :         break;
      86             :     }
      87             :   }
      88             :   DCHECK(module_vars_count == 0 || scope->is_module_scope());
      89             : 
      90             :   // Make sure we allocate the correct amount.
      91             :   DCHECK_EQ(scope->ContextLocalCount(), context_local_count);
      92             : 
      93             :   // Determine use and location of the "this" binding if it is present.
      94             :   VariableAllocationInfo receiver_info;
      95     7735232 :   if (scope->is_declaration_scope() &&
      96     3702444 :       scope->AsDeclarationScope()->has_this_declaration()) {
      97     2065822 :     Variable* var = scope->AsDeclarationScope()->receiver();
      98     2065828 :     if (!var->is_used()) {
      99             :       receiver_info = UNUSED;
     100      586230 :     } else if (var->IsContextSlot()) {
     101             :       receiver_info = CONTEXT;
     102             :     } else {
     103             :       DCHECK(var->IsParameter());
     104             :       receiver_info = STACK;
     105             :     }
     106             :   } else {
     107             :     receiver_info = NONE;
     108             :   }
     109             : 
     110             :   bool has_new_target =
     111     7735241 :       scope->is_declaration_scope() &&
     112     3702437 :       scope->AsDeclarationScope()->new_target_var() != nullptr;
     113             : 
     114             :   // Determine use and location of the function variable if it is present.
     115             :   VariableAllocationInfo function_name_info;
     116     6147140 :   if (scope->is_function_scope() &&
     117     2114336 :       scope->AsDeclarationScope()->function_var() != nullptr) {
     118      177410 :     Variable* var = scope->AsDeclarationScope()->function_var();
     119      177415 :     if (!var->is_used()) {
     120             :       function_name_info = UNUSED;
     121      177419 :     } else if (var->IsContextSlot()) {
     122             :       function_name_info = CONTEXT;
     123             :     } else {
     124             :       DCHECK(var->IsStackLocal());
     125             :       function_name_info = STACK;
     126             :     }
     127             :   } else {
     128             :     function_name_info = NONE;
     129             :   }
     130             : 
     131     4032809 :   const bool has_function_name = function_name_info != NONE;
     132     4032809 :   const bool has_receiver = receiver_info == STACK || receiver_info == CONTEXT;
     133     4032809 :   const int parameter_count = scope->num_parameters();
     134     4032790 :   const bool has_outer_scope_info = !outer_scope.is_null();
     135     8065580 :   const int length = kVariablePartIndex + parameter_count +
     136     8065580 :                      (1 + stack_local_count) + 2 * context_local_count +
     137     4032790 :                      (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0) +
     138     4039246 :                      (has_outer_scope_info ? 1 : 0) +
     139             :                      (scope->is_module_scope()
     140        6456 :                           ? 2 + kModuleVariableEntryLength * module_vars_count
     141     4032790 :                           : 0);
     142             : 
     143             :   Factory* factory = isolate->factory();
     144     4032790 :   Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
     145             : 
     146             :   bool has_simple_parameters = false;
     147             :   bool asm_module = false;
     148             :   bool asm_function = false;
     149     4032790 :   if (scope->is_function_scope()) {
     150     2114335 :     DeclarationScope* function_scope = scope->AsDeclarationScope();
     151             :     has_simple_parameters = function_scope->has_simple_parameters();
     152             :     asm_module = function_scope->asm_module();
     153             :     asm_function = function_scope->asm_function();
     154             :   }
     155             :   FunctionKind function_kind = kNormalFunction;
     156     4032790 :   if (scope->is_declaration_scope()) {
     157     3702441 :     function_kind = scope->AsDeclarationScope()->function_kind();
     158             :   }
     159             : 
     160             :   // Encode the flags.
     161             :   int flags =
     162     4032791 :       ScopeTypeField::encode(scope->scope_type()) |
     163     4032791 :       CallsEvalField::encode(scope->calls_eval()) |
     164     4032791 :       LanguageModeField::encode(scope->language_mode()) |
     165     4032791 :       DeclarationScopeField::encode(scope->is_declaration_scope()) |
     166     4032791 :       ReceiverVariableField::encode(receiver_info) |
     167     4032791 :       HasNewTargetField::encode(has_new_target) |
     168     4032791 :       FunctionVariableField::encode(function_name_info) |
     169     4032791 :       AsmModuleField::encode(asm_module) |
     170     4032791 :       AsmFunctionField::encode(asm_function) |
     171     4032791 :       HasSimpleParametersField::encode(has_simple_parameters) |
     172     4032791 :       FunctionKindField::encode(function_kind) |
     173     4032791 :       HasOuterScopeInfoField::encode(has_outer_scope_info) |
     174     4032791 :       IsDebugEvaluateScopeField::encode(scope->is_debug_evaluate_scope());
     175             :   scope_info->SetFlags(flags);
     176             : 
     177             :   scope_info->SetParameterCount(parameter_count);
     178             :   scope_info->SetStackLocalCount(stack_local_count);
     179             :   scope_info->SetContextLocalCount(context_local_count);
     180             : 
     181             :   int index = kVariablePartIndex;
     182             :   // Add parameters.
     183             :   DCHECK_EQ(index, scope_info->ParameterNamesIndex());
     184     4032791 :   if (scope->is_declaration_scope()) {
     185     3894844 :     for (int i = 0; i < parameter_count; ++i) {
     186             :       scope_info->set(index++,
     187    15579376 :                       *scope->AsDeclarationScope()->parameter(i)->name());
     188             :     }
     189             :   }
     190             : 
     191             :   // Add stack locals' names, context locals' names and info, module variables'
     192             :   // names and info. We are assuming that the stack locals' slots are allocated
     193             :   // in increasing order, so we can simply add them to the ScopeInfo object.
     194             :   // Context locals are added using their index.
     195             :   DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
     196     4032791 :   scope_info->set(index++, Smi::FromInt(first_slot_index));
     197             :   DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
     198             : 
     199             :   int stack_local_base = index;
     200     4032791 :   int context_local_base = stack_local_base + stack_local_count;
     201     4032791 :   int context_local_info_base = context_local_base + context_local_count;
     202             :   int module_var_entry = scope_info->ModuleVariablesIndex();
     203             : 
     204    80150072 :   for (Variable* var : *scope->locals()) {
     205    23700545 :     switch (var->location()) {
     206             :       case VariableLocation::LOCAL: {
     207     8862156 :         int local_index = var->index() - first_slot_index;
     208             :         DCHECK_LE(0, local_index);
     209             :         DCHECK_LT(local_index, stack_local_count);
     210    17724312 :         scope_info->set(stack_local_base + local_index, *var->name());
     211     8862168 :         break;
     212             :       }
     213             :       case VariableLocation::CONTEXT: {
     214             :         // Due to duplicate parameters, context locals aren't guaranteed to come
     215             :         // in order.
     216     3476878 :         int local_index = var->index() - Context::MIN_CONTEXT_SLOTS;
     217             :         DCHECK_LE(0, local_index);
     218             :         DCHECK_LT(local_index, context_local_count);
     219     3476878 :         uint32_t info = VariableModeField::encode(var->mode()) |
     220             :                         InitFlagField::encode(var->initialization_flag()) |
     221     3476878 :                         MaybeAssignedFlagField::encode(var->maybe_assigned());
     222     6953756 :         scope_info->set(context_local_base + local_index, *var->name());
     223             :         scope_info->set(context_local_info_base + local_index,
     224     6953756 :                         Smi::FromInt(info));
     225             :         break;
     226             :       }
     227             :       case VariableLocation::MODULE: {
     228             :         scope_info->set(module_var_entry + kModuleVariableNameOffset,
     229        1780 :                         *var->name());
     230             :         scope_info->set(module_var_entry + kModuleVariableIndexOffset,
     231             :                         Smi::FromInt(var->index()));
     232             :         uint32_t properties =
     233        1780 :             VariableModeField::encode(var->mode()) |
     234             :             InitFlagField::encode(var->initialization_flag()) |
     235        1780 :             MaybeAssignedFlagField::encode(var->maybe_assigned());
     236             :         scope_info->set(module_var_entry + kModuleVariablePropertiesOffset,
     237        1780 :                         Smi::FromInt(properties));
     238             :         module_var_entry += kModuleVariableEntryLength;
     239        1780 :         break;
     240             :       }
     241             :       default:
     242             :         break;
     243             :     }
     244             :   }
     245             : 
     246     4032793 :   index += stack_local_count + 2 * context_local_count;
     247             : 
     248             :   // If the receiver is allocated, add its index.
     249             :   DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
     250     4032793 :   if (has_receiver) {
     251      586230 :     int var_index = scope->AsDeclarationScope()->receiver()->index();
     252      586230 :     scope_info->set(index++, Smi::FromInt(var_index));
     253             :     // ?? DCHECK(receiver_info != CONTEXT || var_index ==
     254             :     // scope_info->ContextLength() - 1);
     255             :   }
     256             : 
     257             :   // If present, add the function variable name and its index.
     258             :   DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
     259     4032793 :   if (has_function_name) {
     260      177421 :     int var_index = scope->AsDeclarationScope()->function_var()->index();
     261             :     scope_info->set(index++,
     262      532263 :                     *scope->AsDeclarationScope()->function_var()->name());
     263      177415 :     scope_info->set(index++, Smi::FromInt(var_index));
     264             :     DCHECK(function_name_info != CONTEXT ||
     265             :            var_index == scope_info->ContextLength() - 1);
     266             :   }
     267             : 
     268             :   // If present, add the outer scope info.
     269             :   DCHECK(index == scope_info->OuterScopeInfoIndex());
     270     4032787 :   if (has_outer_scope_info) {
     271     3916942 :     scope_info->set(index++, *outer_scope.ToHandleChecked());
     272             :   }
     273             : 
     274             :   // Module-specific information (only for module scopes).
     275     4032785 :   if (scope->is_module_scope()) {
     276             :     Handle<ModuleInfo> module_info =
     277        6456 :         ModuleInfo::New(isolate, zone, scope->AsModuleScope()->module());
     278             :     DCHECK_EQ(index, scope_info->ModuleInfoIndex());
     279       12912 :     scope_info->set(index++, *module_info);
     280             :     DCHECK_EQ(index, scope_info->ModuleVariableCountIndex());
     281             :     scope_info->set(index++, Smi::FromInt(module_vars_count));
     282             :     DCHECK_EQ(index, scope_info->ModuleVariablesIndex());
     283             :     // The variable entries themselves have already been written above.
     284             :     index += kModuleVariableEntryLength * module_vars_count;
     285             :   }
     286             : 
     287             :   DCHECK_EQ(index, scope_info->length());
     288             :   DCHECK_EQ(scope->num_parameters(), scope_info->ParameterCount());
     289             :   DCHECK_EQ(scope->num_heap_slots(), scope_info->ContextLength());
     290     4032785 :   return scope_info;
     291             : }
     292             : 
     293       16449 : Handle<ScopeInfo> ScopeInfo::CreateForWithScope(
     294             :     Isolate* isolate, MaybeHandle<ScopeInfo> outer_scope) {
     295       16449 :   const bool has_outer_scope_info = !outer_scope.is_null();
     296       16449 :   const int length = kVariablePartIndex + 1 + (has_outer_scope_info ? 1 : 0);
     297             : 
     298             :   Factory* factory = isolate->factory();
     299       16449 :   Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
     300             : 
     301             :   // Encode the flags.
     302             :   int flags =
     303             :       ScopeTypeField::encode(WITH_SCOPE) | CallsEvalField::encode(false) |
     304             :       LanguageModeField::encode(SLOPPY) | DeclarationScopeField::encode(false) |
     305             :       ReceiverVariableField::encode(NONE) | HasNewTargetField::encode(false) |
     306             :       FunctionVariableField::encode(NONE) | AsmModuleField::encode(false) |
     307             :       AsmFunctionField::encode(false) | HasSimpleParametersField::encode(true) |
     308       16449 :       FunctionKindField::encode(kNormalFunction) |
     309             :       HasOuterScopeInfoField::encode(has_outer_scope_info) |
     310       16449 :       IsDebugEvaluateScopeField::encode(false);
     311             :   scope_info->SetFlags(flags);
     312             : 
     313             :   scope_info->SetParameterCount(0);
     314             :   scope_info->SetStackLocalCount(0);
     315             :   scope_info->SetContextLocalCount(0);
     316             : 
     317             :   int index = kVariablePartIndex;
     318             :   DCHECK_EQ(index, scope_info->ParameterNamesIndex());
     319             :   DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
     320             :   scope_info->set(index++, Smi::kZero);
     321             :   DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
     322             :   DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
     323             :   DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
     324             :   DCHECK(index == scope_info->OuterScopeInfoIndex());
     325       16449 :   if (has_outer_scope_info) {
     326        3139 :     scope_info->set(index++, *outer_scope.ToHandleChecked());
     327             :   }
     328             :   DCHECK_EQ(index, scope_info->length());
     329             :   DCHECK_EQ(0, scope_info->ParameterCount());
     330             :   DCHECK_EQ(Context::MIN_CONTEXT_SLOTS, scope_info->ContextLength());
     331       16449 :   return scope_info;
     332             : }
     333             : 
     334          79 : Handle<ScopeInfo> ScopeInfo::CreateGlobalThisBinding(Isolate* isolate) {
     335             :   DCHECK(isolate->bootstrapper()->IsActive());
     336             : 
     337             :   const int stack_local_count = 0;
     338             :   const int context_local_count = 1;
     339             :   const bool has_simple_parameters = true;
     340             :   const VariableAllocationInfo receiver_info = CONTEXT;
     341             :   const VariableAllocationInfo function_name_info = NONE;
     342             :   const bool has_function_name = false;
     343             :   const bool has_receiver = true;
     344             :   const bool has_outer_scope_info = false;
     345             :   const int parameter_count = 0;
     346             :   const int length = kVariablePartIndex + parameter_count +
     347             :                      (1 + stack_local_count) + 2 * context_local_count +
     348             :                      (has_receiver ? 1 : 0) + (has_function_name ? 2 : 0) +
     349             :                      (has_outer_scope_info ? 1 : 0);
     350             : 
     351             :   Factory* factory = isolate->factory();
     352          79 :   Handle<ScopeInfo> scope_info = factory->NewScopeInfo(length);
     353             : 
     354             :   // Encode the flags.
     355             :   int flags =
     356             :       ScopeTypeField::encode(SCRIPT_SCOPE) | CallsEvalField::encode(false) |
     357             :       LanguageModeField::encode(SLOPPY) | DeclarationScopeField::encode(true) |
     358             :       ReceiverVariableField::encode(receiver_info) |
     359             :       FunctionVariableField::encode(function_name_info) |
     360             :       AsmModuleField::encode(false) | AsmFunctionField::encode(false) |
     361             :       HasSimpleParametersField::encode(has_simple_parameters) |
     362             :       FunctionKindField::encode(FunctionKind::kNormalFunction) |
     363             :       HasOuterScopeInfoField::encode(has_outer_scope_info) |
     364             :       IsDebugEvaluateScopeField::encode(false);
     365             :   scope_info->SetFlags(flags);
     366             :   scope_info->SetParameterCount(parameter_count);
     367             :   scope_info->SetStackLocalCount(stack_local_count);
     368             :   scope_info->SetContextLocalCount(context_local_count);
     369             : 
     370             :   int index = kVariablePartIndex;
     371             :   const int first_slot_index = 0;
     372             :   DCHECK_EQ(index, scope_info->StackLocalFirstSlotIndex());
     373             :   scope_info->set(index++, Smi::FromInt(first_slot_index));
     374             :   DCHECK_EQ(index, scope_info->StackLocalNamesIndex());
     375             : 
     376             :   // Here we add info for context-allocated "this".
     377             :   DCHECK_EQ(index, scope_info->ContextLocalNamesIndex());
     378         158 :   scope_info->set(index++, isolate->heap()->this_string());
     379             :   DCHECK_EQ(index, scope_info->ContextLocalInfosIndex());
     380             :   const uint32_t value = VariableModeField::encode(CONST) |
     381             :                          InitFlagField::encode(kCreatedInitialized) |
     382             :                          MaybeAssignedFlagField::encode(kNotAssigned);
     383             :   scope_info->set(index++, Smi::FromInt(value));
     384             : 
     385             :   // And here we record that this scopeinfo binds a receiver.
     386             :   DCHECK_EQ(index, scope_info->ReceiverInfoIndex());
     387             :   const int receiver_index = Context::MIN_CONTEXT_SLOTS + 0;
     388             :   scope_info->set(index++, Smi::FromInt(receiver_index));
     389             : 
     390             :   DCHECK_EQ(index, scope_info->FunctionNameInfoIndex());
     391             :   DCHECK_EQ(index, scope_info->OuterScopeInfoIndex());
     392             :   DCHECK_EQ(index, scope_info->length());
     393             :   DCHECK_EQ(scope_info->ParameterCount(), 0);
     394             :   DCHECK_EQ(scope_info->ContextLength(), Context::MIN_CONTEXT_SLOTS + 1);
     395             : 
     396          79 :   return scope_info;
     397             : }
     398             : 
     399    19397486 : ScopeInfo* ScopeInfo::Empty(Isolate* isolate) {
     400    19397486 :   return isolate->heap()->empty_scope_info();
     401             : }
     402             : 
     403    13686301 : ScopeType ScopeInfo::scope_type() {
     404             :   DCHECK_LT(0, length());
     405    29094916 :   return ScopeTypeField::decode(Flags());
     406             : }
     407             : 
     408     3814506 : bool ScopeInfo::CallsEval() {
     409     7629012 :   return length() > 0 && CallsEvalField::decode(Flags());
     410             : }
     411             : 
     412     3503172 : LanguageMode ScopeInfo::language_mode() {
     413     7006344 :   return length() > 0 ? LanguageModeField::decode(Flags()) : SLOPPY;
     414             : }
     415             : 
     416      128636 : bool ScopeInfo::is_declaration_scope() {
     417      263862 :   return DeclarationScopeField::decode(Flags());
     418             : }
     419             : 
     420      360941 : int ScopeInfo::LocalCount() { return StackLocalCount() + ContextLocalCount(); }
     421             : 
     422           0 : int ScopeInfo::StackSlotCount() {
     423           0 :   if (length() > 0) {
     424             :     bool function_name_stack_slot =
     425           0 :         FunctionVariableField::decode(Flags()) == STACK;
     426           0 :     return StackLocalCount() + (function_name_stack_slot ? 1 : 0);
     427             :   }
     428             :   return 0;
     429             : }
     430             : 
     431     4020988 : int ScopeInfo::ContextLength() {
     432     4020988 :   if (length() > 0) {
     433     4020988 :     int context_locals = ContextLocalCount();
     434             :     bool function_name_context_slot =
     435     8041976 :         FunctionVariableField::decode(Flags()) == CONTEXT;
     436     4409841 :     bool has_context = context_locals > 0 || function_name_context_slot ||
     437      340935 :                        scope_type() == WITH_SCOPE ||
     438       25472 :                        (scope_type() == BLOCK_SCOPE && CallsSloppyEval() &&
     439      334345 :                         is_declaration_scope()) ||
     440      633387 :                        (scope_type() == FUNCTION_SCOPE && CallsSloppyEval()) ||
     441     4646070 :                        (scope_type() == FUNCTION_SCOPE && IsAsmModule()) ||
     442             :                        scope_type() == MODULE_SCOPE;
     443             : 
     444     4020988 :     if (has_context) {
     445     3694948 :       return Context::MIN_CONTEXT_SLOTS + context_locals +
     446     3694948 :              (function_name_context_slot ? 1 : 0);
     447             :     }
     448             :   }
     449             :   return 0;
     450             : }
     451             : 
     452       14902 : bool ScopeInfo::HasReceiver() {
     453       14902 :   if (length() > 0) {
     454       29804 :     return NONE != ReceiverVariableField::decode(Flags());
     455             :   } else {
     456             :     return false;
     457             :   }
     458             : }
     459             : 
     460     4981773 : bool ScopeInfo::HasAllocatedReceiver() {
     461     4981773 :   if (length() > 0) {
     462     4981774 :     VariableAllocationInfo allocation = ReceiverVariableField::decode(Flags());
     463     4981775 :     return allocation == STACK || allocation == CONTEXT;
     464             :   } else {
     465             :     return false;
     466             :   }
     467             : }
     468             : 
     469         996 : bool ScopeInfo::HasNewTarget() { return HasNewTargetField::decode(Flags()); }
     470             : 
     471     4852292 : bool ScopeInfo::HasFunctionName() {
     472     4852292 :   if (length() > 0) {
     473     9703074 :     return NONE != FunctionVariableField::decode(Flags());
     474             :   } else {
     475             :     return false;
     476             :   }
     477             : }
     478             : 
     479     7560185 : bool ScopeInfo::HasOuterScopeInfo() {
     480     7560185 :   if (length() > 0) {
     481    15120371 :     return HasOuterScopeInfoField::decode(Flags());
     482             :   } else {
     483             :     return false;
     484             :   }
     485             : }
     486             : 
     487       38418 : bool ScopeInfo::IsDebugEvaluateScope() {
     488       38418 :   if (length() > 0) {
     489       76836 :     return IsDebugEvaluateScopeField::decode(Flags());
     490             :   } else {
     491             :     return false;
     492             :   }
     493             : }
     494             : 
     495       16414 : void ScopeInfo::SetIsDebugEvaluateScope() {
     496       16414 :   if (length() > 0) {
     497             :     DCHECK_EQ(scope_type(), WITH_SCOPE);
     498       16414 :     SetFlags(Flags() | IsDebugEvaluateScopeField::encode(true));
     499             :   } else {
     500           0 :     UNREACHABLE();
     501             :   }
     502       16414 : }
     503             : 
     504           0 : bool ScopeInfo::HasHeapAllocatedLocals() {
     505           0 :   if (length() > 0) {
     506           0 :     return ContextLocalCount() > 0;
     507             :   } else {
     508             :     return false;
     509             :   }
     510             : }
     511             : 
     512      422384 : bool ScopeInfo::HasContext() { return ContextLength() > 0; }
     513             : 
     514      138881 : String* ScopeInfo::FunctionName() {
     515             :   DCHECK(HasFunctionName());
     516      277762 :   return String::cast(get(FunctionNameInfoIndex()));
     517             : }
     518             : 
     519      780119 : ScopeInfo* ScopeInfo::OuterScopeInfo() {
     520             :   DCHECK(HasOuterScopeInfo());
     521     1560238 :   return ScopeInfo::cast(get(OuterScopeInfoIndex()));
     522             : }
     523             : 
     524       15986 : ModuleInfo* ScopeInfo::ModuleDescriptorInfo() {
     525             :   DCHECK(scope_type() == MODULE_SCOPE);
     526       31972 :   return ModuleInfo::cast(get(ModuleInfoIndex()));
     527             : }
     528             : 
     529       96745 : String* ScopeInfo::ParameterName(int var) {
     530             :   DCHECK_LE(0, var);
     531             :   DCHECK_LT(var, ParameterCount());
     532       96745 :   int info_index = ParameterNamesIndex() + var;
     533       96745 :   return String::cast(get(info_index));
     534             : }
     535             : 
     536    15325979 : String* ScopeInfo::LocalName(int var) {
     537             :   DCHECK_LE(0, var);
     538             :   DCHECK_LT(var, LocalCount());
     539             :   DCHECK(StackLocalNamesIndex() + StackLocalCount() ==
     540             :          ContextLocalNamesIndex());
     541    15325979 :   int info_index = StackLocalNamesIndex() + var;
     542    15325979 :   return String::cast(get(info_index));
     543             : }
     544             : 
     545     4758208 : String* ScopeInfo::StackLocalName(int var) {
     546             :   DCHECK_LE(0, var);
     547             :   DCHECK_LT(var, StackLocalCount());
     548     4758208 :   int info_index = StackLocalNamesIndex() + var;
     549     4758208 :   return String::cast(get(info_index));
     550             : }
     551             : 
     552     9562757 : int ScopeInfo::StackLocalIndex(int var) {
     553             :   DCHECK_LE(0, var);
     554             :   DCHECK_LT(var, StackLocalCount());
     555             :   int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
     556     9562757 :   return first_slot_index + var;
     557             : }
     558             : 
     559     1547477 : String* ScopeInfo::ContextLocalName(int var) {
     560             :   DCHECK_LE(0, var);
     561             :   DCHECK_LT(var, ContextLocalCount());
     562     1547477 :   int info_index = ContextLocalNamesIndex() + var;
     563     1547477 :   return String::cast(get(info_index));
     564             : }
     565             : 
     566     1230396 : VariableMode ScopeInfo::ContextLocalMode(int var) {
     567             :   DCHECK_LE(0, var);
     568             :   DCHECK_LT(var, ContextLocalCount());
     569     1230396 :   int info_index = ContextLocalInfosIndex() + var;
     570             :   int value = Smi::cast(get(info_index))->value();
     571     1230396 :   return VariableModeField::decode(value);
     572             : }
     573             : 
     574      903812 : InitializationFlag ScopeInfo::ContextLocalInitFlag(int var) {
     575             :   DCHECK_LE(0, var);
     576             :   DCHECK_LT(var, ContextLocalCount());
     577      903812 :   int info_index = ContextLocalInfosIndex() + var;
     578             :   int value = Smi::cast(get(info_index))->value();
     579     1807624 :   return InitFlagField::decode(value);
     580             : }
     581             : 
     582      908506 : MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) {
     583             :   DCHECK_LE(0, var);
     584             :   DCHECK_LT(var, ContextLocalCount());
     585      908506 :   int info_index = ContextLocalInfosIndex() + var;
     586             :   int value = Smi::cast(get(info_index))->value();
     587     1817012 :   return MaybeAssignedFlagField::decode(value);
     588             : }
     589             : 
     590    19959517 : bool ScopeInfo::VariableIsSynthetic(String* name) {
     591             :   // There's currently no flag stored on the ScopeInfo to indicate that a
     592             :   // variable is a compiler-introduced temporary. However, to avoid conflict
     593             :   // with user declarations, the current temporaries like .generator_object and
     594             :   // .result start with a dot, so we can use that as a flag. It's a hack!
     595    59049996 :   return name->length() == 0 || name->Get(0) == '.' ||
     596    39339367 :          name->Equals(name->GetHeap()->this_string());
     597             : }
     598             : 
     599           0 : int ScopeInfo::StackSlotIndex(String* name) {
     600             :   DCHECK(name->IsInternalizedString());
     601           0 :   if (length() > 0) {
     602             :     int first_slot_index = Smi::cast(get(StackLocalFirstSlotIndex()))->value();
     603             :     int start = StackLocalNamesIndex();
     604           0 :     int end = start + StackLocalCount();
     605           0 :     for (int i = start; i < end; ++i) {
     606           0 :       if (name == get(i)) {
     607           0 :         return i - start + first_slot_index;
     608             :       }
     609             :     }
     610             :   }
     611             :   return -1;
     612             : }
     613             : 
     614        5331 : int ScopeInfo::ModuleIndex(Handle<String> name, VariableMode* mode,
     615             :                            InitializationFlag* init_flag,
     616             :                            MaybeAssignedFlag* maybe_assigned_flag) {
     617             :   DCHECK_EQ(scope_type(), MODULE_SCOPE);
     618             :   DCHECK(name->IsInternalizedString());
     619             :   DCHECK_NOT_NULL(mode);
     620             :   DCHECK_NOT_NULL(init_flag);
     621             :   DCHECK_NOT_NULL(maybe_assigned_flag);
     622             : 
     623             :   int module_vars_count = Smi::cast(get(ModuleVariableCountIndex()))->value();
     624             :   int entry = ModuleVariablesIndex();
     625        8231 :   for (int i = 0; i < module_vars_count; ++i) {
     626        3396 :     if (*name == get(entry + kModuleVariableNameOffset)) {
     627             :       int index;
     628         496 :       ModuleVariable(i, nullptr, &index, mode, init_flag, maybe_assigned_flag);
     629         496 :       return index;
     630             :     }
     631        2900 :     entry += kModuleVariableEntryLength;
     632             :   }
     633             : 
     634             :   return 0;
     635             : }
     636             : 
     637    18659692 : int ScopeInfo::ContextSlotIndex(Handle<ScopeInfo> scope_info,
     638             :                                 Handle<String> name, VariableMode* mode,
     639             :                                 InitializationFlag* init_flag,
     640             :                                 MaybeAssignedFlag* maybe_assigned_flag) {
     641             :   DCHECK(name->IsInternalizedString());
     642             :   DCHECK_NOT_NULL(mode);
     643             :   DCHECK_NOT_NULL(init_flag);
     644             :   DCHECK_NOT_NULL(maybe_assigned_flag);
     645             : 
     646    18659692 :   if (scope_info->length() > 0) {
     647             :     ContextSlotCache* context_slot_cache =
     648    18659693 :         scope_info->GetIsolate()->context_slot_cache();
     649             :     int result = context_slot_cache->Lookup(*scope_info, *name, mode, init_flag,
     650    18659693 :                                             maybe_assigned_flag);
     651    18659692 :     if (result != ContextSlotCache::kNotFound) {
     652             :       DCHECK_LT(result, scope_info->ContextLength());
     653             :       return result;
     654             :     }
     655             : 
     656     4262819 :     int start = scope_info->ContextLocalNamesIndex();
     657     4262819 :     int end = start + scope_info->ContextLocalCount();
     658    40482074 :     for (int i = start; i < end; ++i) {
     659    37123067 :       if (*name == scope_info->get(i)) {
     660      903812 :         int var = i - start;
     661      903812 :         *mode = scope_info->ContextLocalMode(var);
     662      903812 :         *init_flag = scope_info->ContextLocalInitFlag(var);
     663      903812 :         *maybe_assigned_flag = scope_info->ContextLocalMaybeAssignedFlag(var);
     664      903812 :         result = Context::MIN_CONTEXT_SLOTS + var;
     665             : 
     666             :         context_slot_cache->Update(scope_info, name, *mode, *init_flag,
     667     1807624 :                                    *maybe_assigned_flag, result);
     668             :         DCHECK_LT(result, scope_info->ContextLength());
     669      903812 :         return result;
     670             :       }
     671             :     }
     672             :     // Cache as not found. Mode, init flag and maybe assigned flag don't matter.
     673             :     context_slot_cache->Update(scope_info, name, TEMPORARY,
     674     3359007 :                                kNeedsInitialization, kNotAssigned, -1);
     675             :   }
     676             : 
     677             :   return -1;
     678             : }
     679             : 
     680           0 : String* ScopeInfo::ContextSlotName(int slot_index) {
     681           0 :   int const var = slot_index - Context::MIN_CONTEXT_SLOTS;
     682             :   DCHECK_LE(0, var);
     683             :   DCHECK_LT(var, ContextLocalCount());
     684           0 :   return ContextLocalName(var);
     685             : }
     686             : 
     687           0 : int ScopeInfo::ParameterIndex(String* name) {
     688             :   DCHECK(name->IsInternalizedString());
     689           0 :   if (length() > 0) {
     690             :     // We must read parameters from the end since for
     691             :     // multiply declared parameters the value of the
     692             :     // last declaration of that parameter is used
     693             :     // inside a function (and thus we need to look
     694             :     // at the last index). Was bug# 1110337.
     695             :     int start = ParameterNamesIndex();
     696           0 :     int end = start + ParameterCount();
     697           0 :     for (int i = end - 1; i >= start; --i) {
     698           0 :       if (name == get(i)) {
     699           0 :         return i - start;
     700             :       }
     701             :     }
     702             :   }
     703             :   return -1;
     704             : }
     705             : 
     706     1306273 : int ScopeInfo::ReceiverContextSlotIndex() {
     707     2612546 :   if (length() > 0 && ReceiverVariableField::decode(Flags()) == CONTEXT)
     708      813916 :     return Smi::cast(get(ReceiverInfoIndex()))->value();
     709             :   return -1;
     710             : }
     711             : 
     712     3280915 : int ScopeInfo::FunctionContextSlotIndex(String* name) {
     713             :   DCHECK(name->IsInternalizedString());
     714     3280915 :   if (length() > 0) {
     715     6699197 :     if (FunctionVariableField::decode(Flags()) == CONTEXT &&
     716      137367 :         FunctionName() == name) {
     717        3322 :       return Smi::cast(get(FunctionNameInfoIndex() + 1))->value();
     718             :     }
     719             :   }
     720             :   return -1;
     721             : }
     722             : 
     723     3342984 : FunctionKind ScopeInfo::function_kind() {
     724     6685968 :   return FunctionKindField::decode(Flags());
     725             : }
     726             : 
     727           0 : int ScopeInfo::ParameterNamesIndex() {
     728             :   DCHECK_LT(0, length());
     729           0 :   return kVariablePartIndex;
     730             : }
     731             : 
     732           0 : int ScopeInfo::StackLocalFirstSlotIndex() {
     733    43888672 :   return ParameterNamesIndex() + ParameterCount();
     734             : }
     735             : 
     736    34325917 : int ScopeInfo::StackLocalNamesIndex() { return StackLocalFirstSlotIndex() + 1; }
     737             : 
     738    14241728 : int ScopeInfo::ContextLocalNamesIndex() {
     739    14241730 :   return StackLocalNamesIndex() + StackLocalCount();
     740             : }
     741             : 
     742     8431433 : int ScopeInfo::ContextLocalInfosIndex() {
     743     8431433 :   return ContextLocalNamesIndex() + ContextLocalCount();
     744             : }
     745             : 
     746     5388717 : int ScopeInfo::ReceiverInfoIndex() {
     747     5388717 :   return ContextLocalInfosIndex() + ContextLocalCount();
     748             : }
     749             : 
     750     4981759 : int ScopeInfo::FunctionNameInfoIndex() {
     751     4981759 :   return ReceiverInfoIndex() + (HasAllocatedReceiver() ? 1 : 0);
     752             : }
     753             : 
     754     4841215 : int ScopeInfo::OuterScopeInfoIndex() {
     755     4841215 :   return FunctionNameInfoIndex() + (HasFunctionName() ? 2 : 0);
     756             : }
     757             : 
     758     4061096 : int ScopeInfo::ModuleInfoIndex() {
     759     4061096 :   return OuterScopeInfoIndex() + (HasOuterScopeInfo() ? 1 : 0);
     760             : }
     761             : 
     762     4045127 : int ScopeInfo::ModuleVariableCountIndex() { return ModuleInfoIndex() + 1; }
     763             : 
     764     4038800 : int ScopeInfo::ModuleVariablesIndex() { return ModuleVariableCountIndex() + 1; }
     765             : 
     766         688 : void ScopeInfo::ModuleVariable(int i, String** name, int* index,
     767             :                                VariableMode* mode,
     768             :                                InitializationFlag* init_flag,
     769             :                                MaybeAssignedFlag* maybe_assigned_flag) {
     770             :   DCHECK_LE(0, i);
     771             :   DCHECK_LT(i, Smi::cast(get(ModuleVariableCountIndex()))->value());
     772             : 
     773         688 :   int entry = ModuleVariablesIndex() + i * kModuleVariableEntryLength;
     774             :   int properties =
     775         688 :       Smi::cast(get(entry + kModuleVariablePropertiesOffset))->value();
     776             : 
     777         688 :   if (name != nullptr) {
     778         192 :     *name = String::cast(get(entry + kModuleVariableNameOffset));
     779             :   }
     780         688 :   if (index != nullptr) {
     781        1376 :     *index = Smi::cast(get(entry + kModuleVariableIndexOffset))->value();
     782             :     DCHECK_NE(*index, 0);
     783             :   }
     784         688 :   if (mode != nullptr) {
     785         496 :     *mode = VariableModeField::decode(properties);
     786             :   }
     787         688 :   if (init_flag != nullptr) {
     788         992 :     *init_flag = InitFlagField::decode(properties);
     789             :   }
     790         688 :   if (maybe_assigned_flag != nullptr) {
     791         992 :     *maybe_assigned_flag = MaybeAssignedFlagField::decode(properties);
     792             :   }
     793         688 : }
     794             : 
     795             : #ifdef DEBUG
     796             : 
     797             : static void PrintList(const char* list_name, int nof_internal_slots, int start,
     798             :                       int end, ScopeInfo* scope_info) {
     799             :   if (start < end) {
     800             :     PrintF("\n  // %s\n", list_name);
     801             :     if (nof_internal_slots > 0) {
     802             :       PrintF("  %2d - %2d [internal slots]\n", 0, nof_internal_slots - 1);
     803             :     }
     804             :     for (int i = nof_internal_slots; start < end; ++i, ++start) {
     805             :       PrintF("  %2d ", i);
     806             :       String::cast(scope_info->get(start))->ShortPrint();
     807             :       PrintF("\n");
     808             :     }
     809             :   }
     810             : }
     811             : 
     812             : void ScopeInfo::Print() {
     813             :   PrintF("ScopeInfo ");
     814             :   if (HasFunctionName()) {
     815             :     FunctionName()->ShortPrint();
     816             :   } else {
     817             :     PrintF("/* no function name */");
     818             :   }
     819             :   PrintF("{");
     820             : 
     821             :   if (length() > 0) {
     822             :     PrintList("parameters", 0, ParameterNamesIndex(),
     823             :               ParameterNamesIndex() + ParameterCount(), this);
     824             :     PrintList("stack slots", 0, StackLocalNamesIndex(),
     825             :               StackLocalNamesIndex() + StackLocalCount(), this);
     826             :     PrintList("context slots", Context::MIN_CONTEXT_SLOTS,
     827             :               ContextLocalNamesIndex(),
     828             :               ContextLocalNamesIndex() + ContextLocalCount(), this);
     829             :     // TODO(neis): Print module stuff if present.
     830             :   }
     831             : 
     832             :   PrintF("}\n");
     833             : }
     834             : #endif  // DEBUG
     835             : 
     836         906 : Handle<ModuleInfoEntry> ModuleInfoEntry::New(Isolate* isolate,
     837             :                                              Handle<Object> export_name,
     838             :                                              Handle<Object> local_name,
     839             :                                              Handle<Object> import_name,
     840             :                                              int module_request, int cell_index,
     841             :                                              int beg_pos, int end_pos) {
     842             :   Handle<ModuleInfoEntry> result = Handle<ModuleInfoEntry>::cast(
     843         906 :       isolate->factory()->NewStruct(MODULE_INFO_ENTRY_TYPE));
     844         906 :   result->set_export_name(*export_name);
     845         906 :   result->set_local_name(*local_name);
     846         906 :   result->set_import_name(*import_name);
     847             :   result->set_module_request(module_request);
     848             :   result->set_cell_index(cell_index);
     849             :   result->set_beg_pos(beg_pos);
     850             :   result->set_end_pos(end_pos);
     851         906 :   return result;
     852             : }
     853             : 
     854        6456 : Handle<ModuleInfo> ModuleInfo::New(Isolate* isolate, Zone* zone,
     855             :                                    ModuleDescriptor* descr) {
     856             :   // Serialize module requests.
     857             :   Handle<FixedArray> module_requests = isolate->factory()->NewFixedArray(
     858        6456 :       static_cast<int>(descr->module_requests().size()));
     859       13630 :   for (const auto& elem : descr->module_requests()) {
     860        2154 :     module_requests->set(elem.second, *elem.first->string());
     861             :   }
     862             : 
     863             :   // Serialize special exports.
     864             :   Handle<FixedArray> special_exports =
     865        6456 :       isolate->factory()->NewFixedArray(descr->special_exports().length());
     866             :   {
     867             :     int i = 0;
     868       13131 :     for (auto entry : descr->special_exports()) {
     869         219 :       Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
     870         438 :       special_exports->set(i++, *serialized_entry);
     871             :     }
     872             :   }
     873             : 
     874             :   // Serialize namespace imports.
     875             :   Handle<FixedArray> namespace_imports =
     876        6456 :       isolate->factory()->NewFixedArray(descr->namespace_imports().length());
     877             :   {
     878             :     int i = 0;
     879       13004 :     for (auto entry : descr->namespace_imports()) {
     880          92 :       Handle<ModuleInfoEntry> serialized_entry = entry->Serialize(isolate);
     881         184 :       namespace_imports->set(i++, *serialized_entry);
     882             :     }
     883             :   }
     884             : 
     885             :   // Serialize regular exports.
     886             :   Handle<FixedArray> regular_exports =
     887        6456 :       descr->SerializeRegularExports(isolate, zone);
     888             : 
     889             :   // Serialize regular imports.
     890             :   Handle<FixedArray> regular_imports = isolate->factory()->NewFixedArray(
     891        6456 :       static_cast<int>(descr->regular_imports().size()));
     892             :   {
     893             :     int i = 0;
     894       13507 :     for (const auto& elem : descr->regular_imports()) {
     895             :       Handle<ModuleInfoEntry> serialized_entry =
     896         595 :           elem.second->Serialize(isolate);
     897        1190 :       regular_imports->set(i++, *serialized_entry);
     898             :     }
     899             :   }
     900             : 
     901        6456 :   Handle<ModuleInfo> result = isolate->factory()->NewModuleInfo();
     902        6456 :   result->set(kModuleRequestsIndex, *module_requests);
     903        6456 :   result->set(kSpecialExportsIndex, *special_exports);
     904        6456 :   result->set(kRegularExportsIndex, *regular_exports);
     905        6456 :   result->set(kNamespaceImportsIndex, *namespace_imports);
     906        6456 :   result->set(kRegularImportsIndex, *regular_imports);
     907        6456 :   return result;
     908             : }
     909             : 
     910       11311 : int ModuleInfo::RegularExportCount() const {
     911             :   DCHECK_EQ(regular_exports()->length() % kRegularExportLength, 0);
     912       11311 :   return regular_exports()->length() / kRegularExportLength;
     913             : }
     914             : 
     915        3460 : String* ModuleInfo::RegularExportLocalName(int i) const {
     916             :   return String::cast(regular_exports()->get(i * kRegularExportLength +
     917        6920 :                                              kRegularExportLocalNameOffset));
     918             : }
     919             : 
     920        5436 : int ModuleInfo::RegularExportCellIndex(int i) const {
     921        5436 :   return Smi::cast(regular_exports()->get(i * kRegularExportLength +
     922             :                                           kRegularExportCellIndexOffset))
     923       10872 :       ->value();
     924             : }
     925             : 
     926        5436 : FixedArray* ModuleInfo::RegularExportExportNames(int i) const {
     927             :   return FixedArray::cast(regular_exports()->get(
     928       10872 :       i * kRegularExportLength + kRegularExportExportNamesOffset));
     929             : }
     930             : 
     931           0 : Handle<ModuleInfoEntry> ModuleInfo::LookupRegularImport(
     932             :     Handle<ModuleInfo> info, Handle<String> local_name) {
     933             :   Isolate* isolate = info->GetIsolate();
     934             :   Handle<FixedArray> regular_imports(info->regular_imports(), isolate);
     935           0 :   for (int i = 0, n = regular_imports->length(); i < n; ++i) {
     936             :     Handle<ModuleInfoEntry> entry(
     937             :         ModuleInfoEntry::cast(regular_imports->get(i)), isolate);
     938           0 :     if (String::cast(entry->local_name())->Equals(*local_name)) {
     939           0 :       return entry;
     940             :     }
     941             :   }
     942           0 :   UNREACHABLE();
     943             :   return Handle<ModuleInfoEntry>();
     944             : }
     945             : 
     946             : }  // namespace internal
     947             : }  // namespace v8

Generated by: LCOV version 1.10